| |
SUBROUTINES
This is a (messy at this time) work in progress. Some links go to the
RTI website even though they are actually documented on this page. The
list on the left is sorted by function; the one on the right is sorted by name.
This page, and it's linked pages, provide a pretty complete programming
reference for Revelation system subroutines. By clicking on the 'Y's, you
should get sample code; if there's not a 'Y', then the sample code should
be right with the subroutine docs.
I would suggest downloading this page and it's linked pages to a subdirectory
under your Revelation, then having a menu item that does a PCPERFORM
of START {subdirectory name}\syssubs1.htm to bring this page up in your
browser. I find it pretty handy when doing a lot of programming.
Enjoy!
Basics
User Interaction
· Subroutines don't do
screen I/O other than through PROGRESS.
· You have source to
PROGRESS.
@FILE.ERROR
· Used to report errors
encountered in the routine.
· Subroutines will null
out - don't rely on it being unchanged.
· Use in conjunction
with STATUS() to determine error handling.
· Calling routine can
deal with the error or call FSMSG
copyrow_sub("MYVOC", "MYROW",
"VOC", "NEWVOCITEM", "O")
If @FILE.ERROR then
fsmsg()
End
copyrow_sub("MYTABLE", "MYROW",
"VOC", "", "")
If @FILE.ERROR<FSCODE$> = "W179" Then
* great! it already exists!
End Else
fsmsg()
End
· Some errors will be
generated by the subroutine. Some errors, usually I/O related, will be passed
back, by the subroutine, unchanged.
· Multiple errors come
back delimited by @RM.
STATUS() values
-2 |
No error. Informational info in @FILE.ERROR |
-1 |
User abandoned process |
0 |
Logical error |
1 |
Physical error, possibly recoverable (eg
drive door open). |
2 |
Fatal error. |
PRINTER.CONTROL
Parameter initialization
· Passed parameters are
not assumed to be initialized
· Uninitialized parms
are assigned a default (usually null)
COPYROW_SUB
Copies one or more rows.
COPYROW_SUB(SourceTable, SourceIds, TargetTable,
TargetIds, Options)
SourceTable |
Required. The source table for
the rows to be copied. |
SourceIds |
The ids for the source rows to
be copied. Multiple ids are separated by @FM. Wildcard "*" can
be used to indicate all rows should be copied. If you like, you can
activate a select list and pass SourceIds as null. The select list will be
used. |
TargetTable |
The table into which the source
rows should be copied. If null, the target table is the same as the source
table. |
TargetIds |
The new ids for the rows to be
copied. If null, the rows are copied to the same name. |
Options |
See the documentation for
COPYROW for a list of supported options. |
Errors Returned
W179 |
Target row already exists. |
W180 |
Target row does not exist. |
S805 |
Number of rows copied. (Informational) |
W106 |
User quit while waiting for a lock. |
W107 |
Source row does not exist. |
B403 |
Unable to write row. |
DELETEROW_SUB
Deletes one or more rows from a table.
DELETEROW_SUB(Table, RowIds, Options)
Table |
Required. The name of the table
from which to delete rows. |
RowIds |
The ids for the rows to be
deleted. Multiple ids are separated by @FM. An active select list may be
used, if so, pass RowIds as null. |
Options |
See the documentation for
DELETEROW for a list of supported options. |
Errors
Returned
W106 |
User quit while
waiting for lock. |
W189 |
Number of rows
deleted (informational) |
ATTACHTABLE_SUB( volumeName, tableList, options )
ATTACHTABLE_SUB attaches tables, making them available for
subsequent processing. The subroutine can attach all available tables on
a volume, or a selected list only. A table is available to ATTACHTABLE_SUB
if it belongs to the current application or if it is global.
You can use a table alias (Qfile) to attach a table that belongs to
another application. However, if the second application has a password,
the alias definition (in the SYSALIAS table) must include the
password. Add it to the second attribute of the definition. For example:
SYSALIAS
SAMPLE,MYPASSWORD
SAMPLE_CUSTOMERS
For more information about creating an alias for a table, see
"Creating an alias (synonym) for a table" in Chapter 22 of the
Advanced Revelation User's Guide.
If a table is qualified with a user name, you can attach it by
including the appropriate user prefix. For details, see "Table
names and users (qualified table names)" in Chapter 22 of the
Advanced Revelation User's Guide.
volumeName |
The name of a valid volume, either a volume defined using the
SetVolume window, or the name of an operating system path where
there are Advanced Revelation tables. If tableList is null,
all qualifying tables on the volume are attached. If no volumeName
is provided, the default data volume is assumed. |
tableList |
An array (@FM-delimited) of tables to attach. If this
parameter is null, all qualifying tables on the volume are
attached. By default, the subroutine attaches the dictionary, the
data portion of the table, and any indexes (the !file). To attach
only one portion of the file, use these prefixes on the table
name: |
Prefix |
Meaning |
DICT. |
Attach only the dictionary portion of the table. |
DATA. |
Attach only the data portion of the file, not the dictionary.
(This also attaches the !file if the table is indexed.) |
If there are two tables of the same name, but one belongs to the
current application and the other is global, the table belonging to the
application is attached. You can attach the table REVMEDIA, but
only if you are in the SYSPROG application.
Options
Option |
Meaning |
A |
(announce). Posts a message in the status line if the file
being
attached was previously attached from another volume. |
Values and Errors Returned
If an error has occured, the system variable status( ) is set
to 1, otherwise status( ) is zero. Specific errors are returned
in @file.error. Multiple errors are delimited with @RM.
Possible values are:
Error |
Meaning |
W504 |
Invalid table name, or attempt to attach a table from another
application
without the proper password. |
109 |
Invalid volume name. |
DELETETABLE_SUB
DELETETABLE_SUB (TableName, Options)
Tablename |
The name of the currently
attached table to delete. |
Options |
See the documentation for
DELETETABLE for a list of supported options. |
Errors Returned
S140 |
Process not available. |
S141 |
Parameter required. |
MAKETABLE_SUB
Creates a table. This routine must be called twice to create both the
data and the dictionary; once for each.
MAKETABLE_SUB(Volume, Table, MediaMap,
FieldList, AttachFlag)
Volume |
The volume onto which to create
the table. If null, the default volume defined in
the current volume is used. This is typically DATAVOL. |
Table |
Required. The name of the table
to create. Tables can be created in other applications by
including the application name with the tablename, separated by
an asterisk.
TABLE*APPNAME The default is to create the table in the current
application. |
MediaMap |
The media map record for the
table. Usually passed as a null, this can be used to preinstall
MFSs on the newly created table. |
FieldList |
A list of fields to create in the
new dictionary. See below for the layout of this parameter. |
AttachFlag |
Pass a 1 (true) if the newly
created table is to be attached. The default is to not attach
the table. |
Fieldlist layout
The fieldlist parameter is a dynamic array.
Each field in the array represents a column in the dictionary. Each
value in the field has a special meaning. Only "F" type fields
can be created.
1) Name |
The name of the dictionary item.
No validation of the name is performed by this routine.
The name is assumed to have been validated by the calling
program. |
2) Datatype |
The generic datatype to be
applied to the column. |
3) KeyFlag |
If this is true, the column is
part of the key. |
4) MVFlag |
If this is true, the column is
multivalued, otherwise it is single valued. |
Errors Returned
S140 |
Process not available (can't run
in a runtime) |
S141 |
Parameter required. |
W506 |
Unable to create table. |
SETALIAS_SUB
Sets up an alias (QFILE).
SETALIAS_SUB(Volume, Application, Password, Table, Alias, Options)
Volume |
The volume containing the table to which to set an alias. |
Application |
The name of the application that owns the table. |
Password |
The password to the application, if any. |
Table |
The name of the table to which to set the alias. |
Alias |
The alias name. If Alias is not provided the system name
SYSALIAS is used. |
Options |
See the documentation for SETALIAS for supported options. |
Errors Returned
W125 |
Password is incorrect. |
W116 |
Application name is incorrect. |
W505 |
Alias is unavailable after SETALIAS_SUB. |
W500 |
Mismatch between volume and table. |
W517 |
Unable to attach table in the application on the volume. |
MAKEACCOUNT_SUB
(sample
code)
Creates a new application (account).
MAKEACCOUNT_SUB (Name, Location, NewList,
Options)
Name |
The name of the application to
create. The name must not conflict with other application or
user names. |
Location |
Where to put the application
specific tables. If not provided a new subdirectory under the
current AREV is created using the same name as the application
(or the first 8 characters of the name).
Volume pointers may be used but only LH volumes are allowed. |
NewList |
Key to the row in the SYSENV
table containing the list of tables to create in the new
application.
See below for the structure of the NewList record. The default
is NEWAPPLICATIONLIST. |
Options |
See the documentation for
MAKEAPPLICATION for supported options. |
Errors Returned
W526 |
Application name is required. |
R120 |
The application already exists. |
S101 |
The location volume must be
Linear Hash. |
S102 |
Unable to create Location. |
W544 |
Unable to read NewList. |
W500 |
Mismatch between table and volume. |
SECUREACCOUNT_SUB
Changes attributes of an application (account).
SECUREACCOUNT_SUB(Request, Name, AppRecord,
Status)
Request |
Required. The action to perform.
0 = Get application information.
1 = Update application information. |
Name |
Required. The name of the
application. |
AppRecord |
If Request = 0, the application
record is returned here.
If Request = 1 you pass the updated application record here.
See below for the structure of the record. |
Status |
One of six status codes. See
below for status codes. |
AppRecord layout:
1 |
The literal "ACCOUNT". |
2 |
Startup command (logon verb). |
3 |
Restriction level. |
4 |
Environment. |
5 |
Reserved. |
6 |
Password (you pass it unencrypted, the system will
encrypt.) |
7 |
Logto passwords (mv list). |
8 |
Logto startup commands (mv list). |
9 |
Logto restriction levels (mv list). |
10 |
Shell code and command. |
11 |
Logto shell code and command. |
12 |
Reserved. |
13 |
Default location for the application. |
Values returned and
Errors Returned
0 |
Successful operation. |
1 |
No application name given. |
2 |
Name is not an application name. (The row
exists in SYSENV but it is not an application.) |
3 |
Name does not exist. |
4 |
Invalid Request code passed. |
5 |
I/O error. Calling program should check
@FILE.ERROR. |
DELETEACCOUNT_SUB
Removes an application (account) from the system.
DELETEACCOUNT_SUB (Name, VolumeList, Options)
Name |
Required. The name of
the application to delete. |
VolumeList |
A list of volumes on
which there are tables belonging to the application to be
deleted. The system will find and delete the application tables
on these volumes. Multiple volumes are separated by @FM. |
Options |
"S" to
suppress progress information display. |
Errors Returned
W172 |
Application name
required. |
W508 |
SYSPROG may not be
deleted. |
USER_SUB
Allows user maintenance (creation, secure, delete).
USER_SUB(Request, Name, UserInfo, Status)
Request |
The action to
perform. See below for a list of valid request codes. |
Name |
The user name on
which to perform the action. |
UserInfo |
This parameter is
used to get information back or to supply information to the
subroutine. A user record. See below for the layout of the user
record. |
Status |
A status code. See
below for status codes. |
Request codes:
0 |
Create a new user. (username passed in Name) |
1 |
Update user information. (username passed in Name.
Userinfo contains new user record). |
2 |
Get user information. (username passed in Name.
User record returned in UserInfo.) |
3 |
Delete a user. (username passed in Name) |
UserInfo record layout:
1 |
The literal "USER". |
2 |
Application the user belongs to. |
3 |
Startup command (logon verb). |
4 |
Restriction level. |
5 |
Environment. |
6 |
Reserved. |
7 |
Password. |
8 |
Shell code and command. |
Values returned and
Errors Returneds:
0 |
Successful completion. |
1 |
No Name given. |
2 |
Name is not a user. |
3 |
Name does not exist. |
4 |
Invalid Request. |
5 |
I/O error. Check @FILE.ERROR for details. |
6 |
Application name given in user record does not
exist. |
7 |
Name already exists. |
BUILDINDEX_SUB( indexType, indexName, indexInfo, clearFlag, đ
indexHandle, sortFileName)
Using BUILDINDEX_SUB
Builds an index in a single table. The index to be built can be a
Btree index, a Cross Reference indexes, or a Relational index.
+ The subroutine BUILDINDEX_SUB cannot build Quickdex or
Rightdex indexes. To build those, use the system subroutine ???
dataTable
The name of the table with for which you want to rebuild indexes. The
table must be attached.
dataHandle
The file handle for dataTable.
F If you are rebuilding an index for a symbolic column, you must also
open the dictionary of the table to @DICT before calling BUILDINDEX_SUB.
indexHandle
The file handle for the index table (the !file) associated with dataTable.
For example, if you are rebuilding indexes in the table SAMPLE_CUSTOMERS,
you must also open !SAMPLE_CUSTOMERS and pass the file handle of
the index in this parameter. You can use the system subroutine INDEX.OPEN
to open the index table.
fieldInfo
An array (@FM-delimited) of indexes (columns) to rebuild. Each
index to be rebuilt is one field in this array, with details about each
index as values (@VM-delimited) within each field. The layout of
each field is as follows:
Value |
Contents |
<n, 1> |
The name of the column (index). For Cross Reference indexes
this is the name of the column without the "_XREF" or
".XREF" suffix. |
<n, 2> |
The literal text Btree, Cross Reference, or Related
To to describe the type of index being rebuilt. This text is
used in error messages if necessary. |
<n, 3> |
Control information for Relational indexes — the full
description of the relation in this format:
targetTable*targetColumn*sortOrder
This information is stored in field 23 of the dictionary
entry for the source column for the relational index. |
<n, 4> |
The full name of the column. For Btree and Relational indexes,
this is the same as the information in value 1. For Cross
Reference indexes this is the name of the column with the
"_XREF" or ".XREF" suffix. |
<n, 5> |
A code indicating the index type: 1 for Btree and Cross
Reference, 2 for Relational. |
<n, 6> |
The column position (field number) of the index. For indexes
on symbolic columns, use the full column name. |
<n, 7> |
A case-sensitivity flag determining whether the data should be
converted to uppercase. 1 (true) means data should be converted
(a case-insensitive index); 0 (false) indicates data should not
be converted (a case-sensitive index). |
<n, 8> |
The justification of the column. For Btree and Cross Reference
indexes this is the justification of the column as defined in
the dictionary (L or R only) followed by the literal
"L". For Relational indexes, see the table below. |
<n, 9> |
The sort direction. For Btree and Cross Reference indexes this
is always "AA". For Relational indexes, see the table
below. |
<n, 10> |
A multivalue flag. Pass true (1) if the column is multivalued,
false otherwise. |
Most of this information can be read directly from the dictionary
entry of the column for which the index is being rebuilt. (See the
second example program for details on where to find this information.)
One exception is the information for justification and sort
direction. For Relational indexes, use this table to determine what
values to pass:
Index Sort Type |
Justification
(Dict just + value in this column) |
Sort
Direction |
AL |
L |
AA |
AR |
R |
AA |
DL |
L |
AD |
DR |
R |
AD |
TOP |
L |
AD |
BOT |
L |
AA |
flagAll
Set to true (1) if all indexes in the table are being rebuilt.
This allows faster processing.
Warning! If not all indexes are being rebuilt or if you are
not sure if all indexes are being rebuilt do not set this flag.
You will lose index information.
Values returned
The return status of BUILDINDEX_SUB is indicated by the system
variable @file.error. If the process completes successfully, the
variable is null. Multiple errors are delimited with record marks (@RM).
The error number appears in field 1 of each @file.error
"record", and additional information about the error appears
in field 2. Possible errors are:
Error |
Meaning |
Add'l Info. |
421 |
User canceled process. |
|
259 |
Related table is not available. |
<2,1> table name
<2,2> rel. table name |
B286 |
The column name is not a valid index name. |
<2> name of column |
B702 |
The index must be rebuilt (if the process is canceled by the
user). |
<2> name of index |
S195 |
Out of disk space. Unable to rebuild index. |
<2,1> type of index
<2,2> name |
Notes
Status line display
The BUILDINDEX_SUB subroutine displays information in the
status line — first as it scans the data in the table, and then as it
rebuilds the index. For tables with more than 100 rows, the status line
is updated only every 100 rows. There is no option to suppress this
display.
Locking and multi-user access to indexes
While you are rebuilding indexes, no other user can be updating the
index (meaning that users cannot change any indexed columns throughout
the table). To ensure that no other users are updating the index, the
control entry *INDEXING and the 0 (zero) entry in the index
(!table) are locked. During the rebuild itself, these index entries are
locked: name*INDEXING, name*, ad name*ROOT.
BUILDINDEX_SUB loops until all of these entries are locked.
Therefore, if another user has any of these entries in use, the rebuild
process halts until the entry is available. By the same token, once the
rebuild process is underway, any attempt to update the index will simply
wait until the control entries are available again.
It is therefore recommended that you do not attempt to rebuild
indexes during periods of heavy use, because your rebuild process could
be delayed, and because while it is running, no user can be updating the
indexes.
Quitting during the rebuild process
The user is able to abort the rebuild process by pressing [Esc] while
a rebuild is underway. However, this leaves the indexes in an
unpredictable condition; the indexes cannot be used until the are
rebuilt.. You should always test to see if the process has been
interrupted, and if so, to warn the user that the indexes should be
rebuilt before they are used.
REBUILDINDEX_SUB
Rebuilds one or more indexes in a table.
REBUILDINDEX_SUB(DataTable, DataHandle,
IndexHandle, FieldInfo, FlagAll)
DataTable |
The name of the data
portion of the table with indexes. |
DataHandle |
The filehandle to DataTable.
The calling program must open the table before calling this
routine. The calling program must open the dictionary of the
table to @DICT before calling this routine. |
IndexHandle |
The filehandle to the !DataTable. The
calling program must open the !table before calling this routine
(INDEX.OPEN is a good choice). |
FieldInfo |
An @FM delimited list of indexes to rebuild. See
below for the structure required for each index type. |
FlagAll |
Set to True (1) if all indexes in the table are
being rebuilt. This allows for faster processing in how the
!table is handled. If all indexes are not being rebuilt or
you're not sure if all indexes are being rebuilt DO NOT SET
THIS FLAG. You will lose index information. |
FieldInfo layout:
1 |
Name of the column. For CrossRef indexes this is
the name of the column without the "_XREF". |
2 |
Literal text for the index type (Btree, CrossRef,
Related To) |
3 |
Desc for Relational indexes, the description of
the relationship. |
4 |
The name of the column. For Btree and Relational
indexes, this is the same as the information in value 1. For
CrossRef indexes this is the name of the column with the
trailing "_XREF". |
5 |
Index type. 1 for Btree and CrossRef, 2 for
Relational. |
6 |
The field on which the index is placed. For real
fields use the field number or the field name (using the field
number will be faster). For symbolics, use the field name. |
7 |
A flag determining whether the data should be
converted to uppercase. 1 (true) means data should be converted.
0 (false) indicates data should not be converted. |
8 |
The justification of the column. For Btree and
CrossRef indexes this is the justifcation of the column (as
defined in the dictionary) followed by the literal
"L". See below for a table of justification codes used
with Relational indexes. |
9 |
Sort direction. For Btree and CrossRef indexes
this is always "AA". See below for a table of sort
directions for Relational indexes. |
10 |
Mv flag. True if the column is multivalued, false
otherwise. |
Relational Justification and Sort Direction
Index Sort Type |
Justification (Dict just + value in this colum) |
Sort Direction |
AL |
L |
AA |
AR |
R |
AA |
DL |
L |
AD |
DR |
R |
AD |
TOP |
L |
AD |
BOT |
L |
AA |
Errors Returned
FS421 |
User cancelled process. |
FS259 |
Related table is not available. |
B286 |
Invalid index name. |
B702 |
Index must be rebuilt. |
S195 |
Out of disk space. Unable to
rebuild index. |
Using BTREE.READ
There are times when you need direct access to indexed values. Much
of the time, the system subroutine, BTREE.EXTRACT will perform this job
quickly and efficiently, returning a sub-set of record keys that matches
the required specifications. However, while BTREE.EXTRACT is powerful,
versatile, and easy to use, it has two limitations:
_ It will only return up to 64K worth of record keys, even though there
may be more keys that would match the search criteria.
_ It returns only the record keys, not the index values.
You can use system subroutine BTREE.READ to address these limitations.
BTREE.READ returns the complete index record that contains the
searched-for value. Since each index record contains the record keys to
the next and previous records in the index you use the record returned
by BTREE.READ as a start and follow pointers from there.
Syntax Use
| BTREE.READ to find a starting position within an index. Once the
starting position is found, you can traverse the index based on your
search criteria. The syntax for BTREE.READ is:
|
| BTREE.READ(i_filevar, field, value, sort_method, MAT record, i,
sep, found)
|
| I_filevar is the file handle to the index file
being accessed. It is not the handle to the data file.
|
| Field is the name of the indexed field being
accessed, for example, "NAME.XREF" or "DATE".
|
| Value contains the value to be searched for. This
is a single value, not a range. If a partial word is passed, for
example, "SM", a starting-with search is implied. The
format of value must match the format of the data stored in the
index. If data is stored in internal format, you must convert value
to its internal representation before passing it to BTREE.READ.
|
| Sort_method is either "AL" or
"AR", indicating either a left-justified or a
right-justified (numeric data) sort order in the index.
|
| MAT Record is a 5 element dimensioned array that
has been initialized to null (""). BTREE.READ returns an
index leaf record in record. For more information on the layout of
record, see "Index Leaf Record Structure" below.
|
| i is a variable that acts as an index into
the value mark- delimited arrays of values and associated record
keys returned in record.
|
| Sep is returned by BTREE.READ. It is the value
that all values in record are less than or equal to. |
| Found is a flag indicating whether or not the
exact value searched for was found. If found is true (1), i points
to the value that contains the searched-for value. If found is false
(0), i points to the position in the index where the value would be
located if it existed.
|
Figure 1 demonstrates calling BTREE.READ.
Index Leaf Record Structure
BTREE.READ returns a Btree index leaf node. Understanding the
structure of the leaf node will help you understand BTREE.READ. A leaf
node is a 5 field record. Each field has a different meaning.
Field 1 - Node Flag
The first field in the index leaf record contains a value of either
"0", "1", or "2", where "2"
denotes that this record contains index values and keys. The other
values indicate that the record contains branch information and no
actual index values.
Field 2 - Forward Pointer
The second field contains the record key to the next record in the
index, assuming ascending order.
The index record keys take the form of
<fieldname>*<optional-identifier>*<separator value>.
The optional identifier is used when there is more than one index leaf
record that contains a single indexed value, common in large files with
relatively few index values for a field, i.e. a status code field that
can contain only a few possible values. The separator value is the same
as the value returned by BTREE.READ in sep. If field 2 is empty then
this is the last leaf record in the index.
Field 3 - Backward Pointer
The third field contains the record key to the previous record in the
index, again assuming ascending order. If field 3 is empty, then this is
the first leaf record in the index.
Field 4 - Indexed Values
Field 4 contains a value-mark delimited list of index values, sorted in
either left-justified (alphabetical) or right-justified (numeric). The
BTREE.READ argument i references a position in this list.
Field 5 - Record Keys
Field 5, the last field in the index leaf record, contains a multivalued
list of keys. Each value is associated with the index value in the same
position in field 4. If more than one key is associated with an index
value, then the keys are delimited with subvalue marks.
Multi-User Access
BTREE.READ does not perform any locking. If your index file is being
updated by multiple users simultaneously these problems could result:
The forward or backward pointer in record could point to a non-existant
record. The values in the index could change as you traverse the index.
To prevent the index from changing as you traverse the index, you should
lock the root node of the index (the "FieldName*ROOT" record
in the indexing file) before accessing the index. Users will still be
allowed to update the data file and to post new index transactions. Be
sure to unlock the root when you're finished with the index. If you must
allow updates while traversing the index use this strategy to account
for a shifting index:
If your read of the next index record fails, reread the current record
from the index. This will give you an updated version of the record with
new pointers. If the new pointer fails (the read still doesn't return a
record) call BTREE.READ again with using the last index value in val.
This will give you a new starting position within the index from which
to to start traversing. Warning! Both of these techniques could result
in your program missing records or in your program processing the same
record twice.
/* This program searches the customer_name index using BTREE.READ and
returns all records that have an indexed value between "SMITH"
and "THOMPSON". */
DECLARE SUBROUTINE BTREE.READ, FSMSG
EQU TRUE$ TO 1
EQU FALSE$ TO 0
EQU NULL$ TO "" DIM I_RECORD(5)
MAT I_RECORD = NULL$
I = NULL$
SEP = NULL$
FOUND = NULL$
I_FILEVAR = NULL$
FIELD = "CUSTOMER_NAME"
VALUE = "SMITH"
MAX_VALUE = "THOMPSON"
/* Get the sort information from the index.*/
SORT_METHOD = XLATE("!SAMPLE_CUSTOMERS", FIELD, 1,
"X")
OPEN "!SAMPLE_CUSTOMERS" TO INDEX_FILE ELSE
FSMSG()
STOP
END
OPEN "SAMPLE_CUSTOMERS" TO CUSTOMER_FILE ELSE
FSMSG()
STOP
END
LOCKED = FALSE$
LOOP
LOCK INDEX_FILE, FIELD:"*ROOT" THEN
LOCKED = TRUE$
END
UNTIL
LOCKED
REPEAT
BTREE.READ(INDEX_FILE,FIELD,VALUE,SORT_METHOD,MAT,I_RECORD,I,SEP,FOUND)
/* Find the starting position in the key list in element five of the
index leaf record. */
IF I > 1 THEN
POS = INDEX(I_RECORD(5), @VM, I-1) + 1
END ELSE
POS = 1
END
FLAG = NULL$
DONE = FALSE$
LOOP
/* Get the next key to process */
REMOVE @ID FROM I_RECORD(5) AT POS SETTING FLAG
READ @RECORD FROM CUSTOMER_FILE, @ID THEN
GOSUB PROCESS_RECORD
END
IF FLAG = 3 THEN
/* REMOVE sets FLAG to 3 when a value mark is found. Finding a value
mark indicates the indexed value has changed. */
IF I_RECORD(4)<1,I> > MAX_VALUE THEN
/* No more valid values to process. */
DONE = TRUE$
END
END ELSE
IF FLAG ELSE
/* If flag = 0 then we have reached the end of the current leaf record
and it is time to read the next record or stop. */
IF I_RECORD(2) THEN
/* There is a pointer to another record. */
MATREAD I_RECORD FROM INDEX_FILE, I_RECORD(2) THEN
/* Start at the beginning of the list of keys in the new record.*/
POS = 1
I = 1
END ELSE
/* Recovery logic goes here if you're not locking the index. */
DONE = TRUE$
END
END ELSE
/* There are no more index records. */
DONE = TRUE$
END
END
END
UNTIL DONE
REPEAT
UNLOCK INDEX_FILE, FIELD:"*ROOT" ELSE
FMSG()
END
PROCESS_RECORD:
/* Logic to process records goes here. */
RETURN
DELETELIST_SUB
DELETELIST_SUB( deleteTableName, deleteRecName )
Removes a list saved earlier with the TCL
command SAVELIST or the subroutine SAVELIST_SUB.
deleteTableName |
The name of the table in which the
list to be deleted is located. The default is LISTS. |
deleteRecName |
The name of the list to delete |
Values returned and
Errors Returned
The return status of SAVELIST_SUB
is indicated by the system variable @file.error. Multiple errors
are delimited with record marks (@RM). The error number appears
in field 1 of each @file.error "record", and additional
information about the error appears in field 2. Possible errors are:
Error |
Meaning |
S145 |
Successful deletion. |
S140 |
Process not allowed
on a Runtime version of Advanced Revelation. |
401 |
Invalid table name
in deleteFileName. |
B166 |
deleteRecName does
not exist in the indicated table (status( ) returns
zero). |
Under some circumstances, DELETELIST_SUB
sets these values for status( ):
status( ) |
Meaning |
-2 |
Successful deletion. |
1 |
An error occurred. |
0 |
Non-critical error occured. |
Correct use of DELETELIST_SUB
list = "phonelist"
table = "" /* defaults to LISTS */
call deletelist_sub( table, list )
if status() # -2 then
call fsmsg()
end
GETLIST_SUB
GETLIST_SUB( sourceTableName, sourceRecName, options )
Retrieves a list of keys saved earlier
with the TCL SAVELIST command or with the system subroutine SAVELIST_SUB,
and makes it into the currently active list (in cursor zero). If @BROWSE.MODE
is true, the list is put directly into @BROWSE.LIST (up to
32K).
sourceTableName |
The name of the table in which to
save the list. The default is LISTS. The table must be
attached |
sourceRecName |
The name of the list to get. |
options |
(o) (Overwrite) If a select list is
already active, overwrite (clear) it. |
Values returned and
Errors Returned
The return status of GETLIST_SUB
is indicated by the system variable @file.error. Multiple errors
are delimited with record marks (@RM). The error number appears
in field 1 of each @file.error "record", and additional
information about the error appears in field 2. Possible errors are:
Error |
Meaning |
Add'l Info. |
S144 |
Select list has been
activated. |
<2> reccount |
S140 |
This process is not
allowed on a Runtime version |
S143 |
A select list is
already active (no O option). |
401 |
Invalid table name in
sourceTableName. |
<2> table |
B558 |
No such list. |
<2,1> key
<2,2> table |
Under some circumstances, GETLIST_SUB sets these values for status(
):
status( ) |
Meaning |
-2 |
Select list has been activated. |
1 |
An error occurred. |
Correct use of GETLIST_SUB
tablename = "" ;
* table name defaults to LISTS
listname = "SORTED_CUSTOMERS"
call getlist_sub( tablename, listname )
if @list.active then
reccount = @file.error<2>
call msg( "%1% rows were selected!", "",
"", reccount )
perform "LIST SAMPLE_CUSTOMERS"
end else
if @file.error<1> = "B558" then
text = "Please
run the Customer sort option"
text<-1> = "before choosing this
report!"
call msg( text )
end else
call fsmsg()
end ; * if @file.error
end ; * if @list.active
call deletelist_sub( tablename, listname )
stop
SAVELIST_SUB( saveTableName, saveRecName, options )
Using SAVELIST_SUB
Saves a currently-active select list to a table, from where it can be
re-activated using the TCL GETLIST command or the subroutine GETLIST_SUB.
The select list to be saved can be active or latent; if the list is
latent, it is resolved before being saved. By default, the select list
remains active after being saved.
saveTableName |
The name of the table in which to save the list. The default is LISTS.
The table must be attached. |
saveRecName |
The name of the list to save. The name should contain no spaces
or system delimiters (@VM, @FM, etc.). We recommend
that you limit punctuation to underscore characters (_). |
Options
Option |
Meaning |
C |
(Clear) Clears the select list after saving it. The default is
that the list remains active. |
Values returned and
Errors Returned
The return status of SAVELIST_SUB is indicated by the system
variable @file.error. Multiple errors are delimited with record
marks (@RM). The error number appears in field 1 of each @file.error
"record", and additional information about the error appears
in field 2. Possible errors are:
Error |
Meaning |
Add'l Info. |
W166 |
Successful save. |
<2,1> table
<2,2> list key
<2,3> key count |
S140 |
Process not allowed on a Runtime version of Advanced
Revelation. |
|
S142 |
No active list to save. |
|
401 |
Invalid table name in saveTableName. |
<2> table |
421 |
User aborted (while a latent list was being resolved) |
<2> key
<3> table |
select.seek
error |
Unable to retain the active select list. |
|
Under some circumstances, SAVELIST_SUB sets these values for status(
):
status( ) |
Meaning |
-2 |
Successful save. |
-1 |
User aborted the process by pressing [Esc]
(this is only possible if the select list was unresolved). |
1 |
An error occurred. |
Correct use of SAVELIST_SUB
perform "SELECT SAMPLE_CUSTOMERS LATENT (S)"
call savelist_sub( "", "CUSTLIST", "")
if status() ne -2 then
call fsmsg()
end else
reccount = @file.error<2,3>
text = "%1% rows selected and saved!"
call msg( text, "", "", reccount )
end
/* savelist is still active */
perform "LIST SAMPLE_CUSTOMERS CITY"
GETCONFIGURE
(Sample
Code)
error = GETCONFIGURE( configureRecord )
A function that loads an array with
information about the current configuration of the system. This includes
much of the information displayed by the TCL WHO command.
configureRecord
This parameter returns an array (@FM-delimited)
of information about the current system. The entry CONFIGURE.RECORD.EQUS
in the SYSINCLUDE table provides text constants for the positions
of this array. The layout is this:
Pos |
Description |
Values |
1 |
System level |
Current release
level (for example, 3.1). |
2 |
Updated from |
Multivalued field
(associated with <2> and <3>) listing the source
release level when an update (Maintenance Release) was applied. |
3 |
Updated to |
Associated
multivalued field (with <2> and <3> listing the
release level after the update. |
4 |
Update date |
Associated
multivalued field (with <2> and <3>) listing the
dates of updates. |
5 |
Conversion list |
Multivalued list of
conversion modules (such as PC-MOS) that have been
applied to this system (associated with <6>). |
6 |
Conversion dates |
Multivalued list of
dates (associated with <5>) on which conversion modules
were applied to this system. |
7 |
Optional module list |
Multivalued list of
add-on modules (such as Environmental Bonds) that have been
applied to this system. |
Pos |
Description |
Values |
8 |
Optional module
install dates |
Multivalued list of
dates (associated with <7> and <8>) of when add-on
modules were added to the system. |
9 |
Optional module
level |
Multivalued list of
release levels associated with <7> and <8>) for
add-on modules were added to the |
10 |
System type |
0 = Full development
1 = Runtime
2 = Demo
3 = Single-disk Runtime |
11 |
Monitor type |
7 = monochrome, any
other value = color. |
12 |
Video adapter type. |
0 = MDA
1 = CGA
2 = EGA
3 = PGA
4 = VGA
5 = MCGA
6 = Unknown |
13 |
Video mode |
0 = Text (default)
1 = EGA25
2 = EGA43
3 = VGA25
4 = VGA43
5 = VGA50 |
14 |
Mouse active |
True if a mouse has
been detected, false otherwise. |
15 |
Mouse button count. |
Number of mouse
buttons detected (2 or 3). |
16 |
Mouse driver
version. |
As returned by the
mouse driver. |
17 |
Mouse type |
1 = Bus
2 = Serial
3 = InPort
4 = PS/2
5 = HP |
18 |
Expanded memory in
use |
True if an EMM
driver has been detected, false otherwise. |
Pos |
Description |
Values |
19 |
EMM window address |
Hex address of 16K
EMM window (buffer). |
20 |
EMM overflow buffer 1 address |
Hex address of first
expanded memory page frame (overflow buffer). |
21 |
EMM overflow buffer 2 address |
Hex address of
second expanded memory page frame (overflow buffer). |
22 |
Expanded memory in use |
Bytes of expanded
memory currently in use. |
23 |
Expanded memory allocated |
Amount of expanded
memory that Advanced Revelation has allocated. |
24 |
Network type |
Name of the network
driver currently loaded. |
25 |
Maximum network users |
Number of maximum
concurrent users for this copy of Advanced Revelation. (The
number to which this copy has been bumped.) |
26 |
Active language set |
Name of the language
set currently active (for example, LND_ENGLISH_INT). |
27 |
Loaded language set |
Multivalued list of
additional language sets currently loaded. The first value in
this list matches the active language set. |
28 |
Active printer |
Name of
currently-active printer. (Name of the printer configuration
record currently loaded.) |
29 |
Available printers |
Multivalued list of
printers available in Advanced Revelation. (Lists the names of
the configuration records.) |
Pos |
Description |
Values |
30 |
Communications port
setup |
Multivalued list of
settings for the default communication port, in this layout:
<30,1> baud rate
<30,2> data bits
<30,3> stop bits
<30,4> parity
<30,5> Xon/Xoff (0/1)
<30,6> strip flag (0/1)
<30,7> break count |
31 |
Rollout file |
Name of DOS file
for storing the current memory configuration when Advanced
Revelation is temporarily suspended. (This is also the value of @ROLLOUT.FILE.) |
32 |
Screen height |
Height (in rows) of
the display device. (This is also the value of @CRTHIGH.) |
33 |
Screen width |
Width (in columns)
of the display device. (This is also the value of @CRTWIDE.) |
34 |
Printer page height |
Height (in rows) of
the logical printer page. (This is also the value of @LPTRHIGH.) |
35 |
Printer page width |
Width (in columns)
of the logical printer page. (This is also the value of @LPTRWIDE.) |
36 |
Index timeout |
Number of seconds of
idle time that the current workstation waits before launching
the background indexing process. A value of 0 means that the
current workstation will not begin background indexing. (This is
also the value of @INDEX.TIME.) |
37 |
Background index
delay. |
Number of seconds
that this workstation waits between index updates before
checking for further index transactions. (This is also the value
of @BACKGROUND.DELAY.) |
Pos |
Description |
Values |
38 |
Temporary files
volume. |
Volume or DOS path
where this workstation should store temporary work files for
sorting, creating View reports in R/LIST, and printing to
PostScript printers. |
39 |
Lock limit |
Maximum number of
locks (table or row) allowed for this workstation on a network.
Zero means there is no limit. |
40 |
Network cache size |
Size in bytes of the
network cache for this workstation. Zero means there is no
caching. |
41 |
Printer ports |
Multivalued list
(associated with <29>) of printer ports for available
printers. |
42 |
Display equivalence
table |
Name of entry in the
SYSPRINTERS table that provides screen output
equivalences for printer attribute codes (font attribute table). |
43 |
Mouse sensitivity |
Value between 1 and
100, with 100 the most sensitive (fastest). |
44 |
Not currently used |
45 |
System
initialiazation file |
Name of INI file
(for example, AREVC.INI) that was used when this session
started. |
Values returned
The return value for GETCONFIGURE
is a single number indicating the success of the operation:
Value |
Meaning |
0 |
GETCONFIGURE returned OK. |
2 |
Configuration information cannot
be found. |
3 |
Error in parsing the
configuration information. |
4 |
The INI file for the
current workstation is not available. |
CALCULATEX
CALCULATEX
CALCULATEX is an external function that evaluates the specified field.
result = CALCULATEX(field, dict, id, record, mv)
Using CALCULATEX
CALCULATEX differs from R/BASIC CALCULATE only in relieving
the user of the necessity to save and restore the values of
@DICT, @RECORD, and @ID.
field
Field contains the name of the dictionary field to evaluate.
dict
Dict contains the source dictionary file.
id
Put the record key of the source record in id.
record
Place the source record in record.
mv
Mv contains the value number of the source value in a
multivalued field. This value should be 0 (zero) if the
field is single-valued.
Values returned
CALCULATEX returns the result of evaluating field in the
specified dictionary.
Correct Use of CALCULATEX
/* The following code opens a file and its associated
dictionary, then uses CALCULATEX to evaluate one multivalue
in a field from SAMPLE_CUSTOMERS. */
DECLARE SUBROUTINE FSMSG, MSG
DECLARE FUNCTION CALCULATEX
file = "SAMPLE_CUSTOMERS"
field = "CONTACT_NAME"
dict = "DICT SAMPLE_CUSTOMERS"
id = 6
mv = 2
OPEN file TO filevar ELSE FSMSG(); STOP
OPEN dict TO @DICT ELSE FSMSG(); STOP
READ @RECORD FROM filevar,id ELSE FSMSG(); STOP
result = CALCULATEX(field, @DICT, id, @RECORD, mv)
text = "Multivalue ":mv:" of the
":field:" field"
text<<-1>> = "for record ":id:" evaluates to
":result
MSG(text,"","","")
DRVREADY
The DRVREADY function, provided with Advanced Revelation 2.12, lets you
determine whether a floppy disk drive is ready. Pass a 0 for drive A and a 1
for drive B. DRVREADY returns true (1) if the drive is ready, otherwise
false (0). Drives C and higher are not supported.
Figure 1 shows how DRVREADY can be used in a program.
Note: On some single floppy drive systems DRVREADY will return true when
testing (the non-existent) drive B.
Figure 1
DECLARE FUNCTION DRVREADY
DECLARE SUBROUTINE MSG
DRV = 0
DONE = 0
LOOP
DONE = DRVREADY(DRV)
IF DONE ELSE
MSG('Insert disk into drive %1%
and close door','','',CHAR(65DRV))
END
UNTIL DONE
REPEAT
EXIT_SYSTEM
EXIT_SYSTEM( displayMessage )
Does a clean logoff from Advanced
Revelation from within an R/BASIC program. In addition to logging off, EXIT_SYSTEM
accomplishes these tasks:
· Writes
out any cached index updates that might be pending because BATCH.INDEXING
has been invoked. For details about BATCH.INDEXING, see the
Revelation Technologies Knowledge Base.
· Detaches
all volumes belonging to Environmental Bonds (or other non-native filing
systems) so that those filing systems can run their own cleanup
operations.
displayMessage
If this parameter is passed true, the
normal Advanced Revelation logoff message (W170) is displayed.
USERCONVERSION
U307A is what is known as a user code. Primarily it is in there for
Pick compatibility and were never removed from the product. Below are
all the user codes available:
OpenInsight and ARev ICONV
U307A |
Wait to Specified Time (time in MTS output
format |
U407A |
Wait for specified number of seconds. |
OpenInsight and ARev OCONV
ARev OCONV
[U60E0] |
@CRTWIDE |
[U70E0] |
Turn Echo On |
[U80E0] |
Turn Echo Off |
(Note the square brackets around the OCONV values!)
Additionally there is an OCONV validation called a G Correlative.
Essentially, it is the limited version of the field function. The format
is GStartPos-1DelimiterNumValues.
StartPos is the starting position passed into the FIELD function
starting position value less 1.
Delimited is the charachter passed into the FIELD function delimiter
value.
NumValues is the starting position passed into the FIELD function number
of values to return
For example,
OCONV( 'A*B*C*D*E*F*G*H*I','G2*3')
will return C*D*E.
Note that the G Correlative does not require the square brackets.
Also note that that starting position number must be 9 or lower. Also,
the starting position number is one less than the value passed into the
FIELD function.
(Code)
REBUILDREVBOOT_SUB( locations )
Using REBUILDREVBOOT_SUB
When you start Advanced Revelation, the program gets its bootstrap
information from a DOS file called REVBOOT. This includes
the object code for the initial system programs, the network driver, the
default error handler, and the text that displays while Advanced
Revelation is loading.
The REVBOOT file is constructed from copies of entries in
various system tables such as SYSOBJ, SYSENV, and SYSTEXT.
REBUILDREVBOOT_SUB allows you to change the bootstrap information
by assembling fresh copies of these entries (after you have made changes
to them) and writing them out as a new copy of the REVBOOT file.
The most common types of changes are:
· Changing network drivers.
· Changing the text of logon messages, such as “Welcome to
Advanced Revelation”, “Processing ...”, the prompt text for
passwords and account names, and the text of error messages that are
displayed during logon.
· Changing the list of programs that are permanently loaded into
memory while Advanced Revelation is running (the programs in INITIAL_LOAD).
For example, to change the text of a logon message, you can edit the
entry called RTP1*PARMS in the SYSTEXT table. After making
changes, run REBUILDREVBOOT_SUB, which will recreate REVBOOT,
including the text changes that you have made.
Before writing out an updated REVBOOT file, the REBUILDREVBOOT_SUB
subroutine makes a copy of the existing REVBOOT file under the name REVBOOT.OLD.
Note that if you run REBUILDREVBOOT_SUB repeatedly, you will
overwrite REVBOOT.OLD each time.
+ Always to back up the DOS REVBOOT file before
experimenting with REBUILDREVBOOT_SUB (even though the subroutine
makes one copy of your existing file). If your REVBOOT file
contains errors, you will not be able to log into Advanced Revelation.
You do not need to be in the SYSPROG application to run this
subroutine, but you must have access to all the system tables listed in
the table under location, below.
locations
An array of information that overrides the defaults for REBUILDREVBOOT_SUB:
· The location where REBUILDREVBOOT_SUB can find certain
system information (such as the logon text).
· The name of the network driver.
· The name and location of the DOS file that the subroutine
creates (the default is REVBOOT).
You need to pass a value in this parameter only if you want REBUILDREVBOOT_SUB
to find components for the new REVBOOT file somewhere other than
their default locations or if you are changing network drivers. By
specifying alternative locations for the components of the REVBOOT file,
you can make changes to copies of these components and preserve the
originals in case you want to restore the default values at a later
time.
You can also pass information in location that causes REBUILDREVBOOT_SUB
to write out the bootstrap information under a different name or to a
location other than the default directory. This feature is useful if you
want to create one or more alternate DOS files that you can experiment
with when logging on to Advanced Revelation (by copying them to REVBOOT),
or if you want to rebuild the REVBOOT file belonging to a
different copy of Advanced Revelation.
The location array consists of 8 fields, most of which have
two values, the first for a table name and the second for the name of a
row in the table. The layout of this array, the definitions of its
elements, and its default values are in the table that follows. To
override a default value, pass an array that is null except for any
values that you want to change.
Field |
Meaning |
Default (@VM-delimited) |
1 |
Bootstrap program |
SYSOBJ, $RTP1We do not recommend that you override the
object code records for bootstrap: ($RTP1, $RTP57, $RTP27, and
$STDIOERR) except to change the location from which they are
read, if relevant. |
2 |
Boot filing system |
SYSOBJ, $RTP57 |
3 |
Network driver |
SYSNETWORKS, null
(see Notes, below) |
4 |
Program loader |
SYSOBJ, $RTP27 |
5 |
Default error handler |
SYSOBJ, $STDIOERR |
6 |
List of programs to remain memory-resident |
SYSENV, INITIAL_LOAD
(see Notes, below) |
7 |
Text of logon messages |
SYSTEXT, RTP1*PARMS
(see Notes, below |
8 |
Name and location for REVBOOT file. |
null
(see Notes, below) |
Values returned
The return status of REBUILDREVBOOT_SUB is indicated by error
values in @file.error. If there has been no error, @file.error
is null. Multiple errors are delimited with record marks (@RM).
The error number appears in field 1 of each @file.error
"record", and additional information about the error appears
in
field 2. Possible errors are:
Error |
Meaning |
Add'l Info. |
W351 |
Unable to open a required table. |
<2> name of table |
B280 |
REVBOOT file exceeds 65,530 bytes. |
|
B166 |
Invalid row key passed in location. |
<2,1> row key
<2,2> table name |
B241 |
Invalid network driver name passed in location or
placed into DRIVERTABLE. |
<2> driver name |
@file.error may also contains errors values indicating
problems in creating or writing the REVBOOT file at DOS.
For possible values, see OSWRITE and OSOPEN in the R/BASIC
manual.
Notes
Changing the network driver
Network drivers are different versions of the Linear Hash filing
system object code ($RTP57A), one each for the different types of
network operating systems that are supported in Advanced Revelation. A
list of possible network drivers appears in the entry DRIVERTABLE
in the table SYSNETWORKS. The layout of that entry is:
Field |
Meaning |
1 |
Name (clear text) of current driver. |
2 |
Multivalued array of names (clear text) of all available
network drivers. |
3 |
Multivalued array (associated with <2>) of the names of
the object code entries for the network drivers. |
You can change a network driver in two ways:
· Change <1> of the DRIVERTABLE entry to the name of
the new driver before running REBUILDREVBOOT_SUB.
· Pass in <3, 2> of location the name (clear text) of
the new driver.
In either case, the name that you use must match exactly (case
sensitive) one of the names in field 2 of DRIVERTABLE. If you are
keeping the network driver object code in a table other than SYSNETWORKS,
pass the name of the alternative table in <3,1> of location.
Changing the text of logon messages
You can change the change the text of logon messages in two ways:
· Modify the entry RTP1*PARMS in SYSTEXT before
calling REBUILDREVBOOT_SUB.
· Copy RTP1*PARMS from SYSTEXT to another table (and
optionally, to another row key name), and pass the new table name and
row key in <7,1> (table) and <7,2> (row key) when calling REBUILDREVBOOT_SUB.
You must not disturb the layout of the text row, because the
positions in the row are associated with particular errors and tasks
(for example, position 34 of the row is the text that displays
underneath the logon banner).
Changing the contents of the program stack (INITIAL_LOAD)
The row INITIAL_LOAD in the SYSENV table contains a list of programs
that are loaded into memory when you first log onto Advanced Revelation.
A number of these programs remain memory resident at all times for
speed.
+ For details about using INITIAL_LOAD, see entries R33
and R50 in the Advanced Revelation KnowledgeBase.
To change the list of programs loaded as part of INITIAL_LOAD:
· Modify the entry INITIAL_LOAD in SYSENV before
calling REBUILDREVBOOT_SUB.
· Copy INITIAL_LOAD from SYSENV to another table (and
optionally, to another row key name), and pass the new table name and
row key in <6,1> (table) and <6,2> (row key) when calling REBUILDREVBOOT_SUB.
Correct use of REBUILDREVBOOT_SUB
/* an example of how to change the network driver */
location = ''
* must match a name in DRIVERTABLE<2> in SYSNETWORKS
location<3,2> = "Novell NetWare"
call rebuildrevboot_sub( location )
if @file.error then
call fsmsg()
end
stop
/* example showing how you can change logon text by copying the
existing text to a new location, changing it, and passing the
new location to REBUILDREVBOOT_SUB */
open 'SYSENV' to sysenvFile else call fsmsg() ; stop
open 'PARM_TABLE' to parmTable else call fsmsg() ; stop
read textInfo from sysenvFile then
textInfo< 2 > = "Please stand by ..."
textInfo< 17 > = "Establishing a network connection ..."
textInfo< 26 > = "|Employee number|" ; * user name
prompt
textInfo< 22 > = "|Password|" ; * password prompt
textInfo< 34 > = "Preparing your application ..."
write textInfo to parmTable, "TEXT" then
location< 7, 1 > = "PARM_TABLE"
location< 7, 2 > = "TEXT"
call rebuildrevboot_sub( location )
if @file.error then
call fsmsg()
end
end
end |
|