Database Extreme Library
Version 1.28 for PDAT 6.0 Professional

Copyright (C) 2002-2005 Richard R. Sands dba Sands USA
All Rights Reserved

Table of Contents

1. Library Overview 6. Library Actions Reference
2. Plugging In the Library 7. Function and Evaluator Reference
3. Distribution 8. Purchasing Information and Support
4. Advanced Filtering Techniques 9. Warranty and User License Agreement
5. Stash File Techniques 10. Warranty and User License Agreement

Library Actions Reference by Action Name

db.Alert db.Export.Memo db.Keyset.Update
db.Alert.Custom (ver. 1.25, Pro) db.Find.Rec db.Renum
db.Append db.Find.RecEx (ver. 1.25 Pro) db.Renum.Key
db.Append.Rec db.FindNext.Rec (ver. 1.14) db.Select
db.Clear db.FindNext.RecEx (ver. 1.25 Pro) db.Set
db.Clear.If  (ver. 1.13) db.FindPrev.RecEx (ver. 1.26 Pro) db.SetEx (ver. 1.27 Pro)
db.Clear.Rec db.Goto (ver. 1.28 Pro) db.Set.Rec
db.Copy.Rec db.GotoForm (ver. 1.15) db.Set.RecEx  (ver. 1.27 Pro)
db.Create (ver. 1.12) db.If  db.StackSize (ver. 1.24, Pro)
db.Delete db.If.True db.Stash.Clear (ver. 1.25 Pro)
db.Delete.DupsNC (ver. 1.14) db.If.TrueEx  (ver. 1.25, Pro) db.Stash.Data (ver. 1.25, Pro)
db.Delete.Dups (ver. 1.11) db.If.False db.Stash.File (ver. 1.25, Pro)
db.Delete.Rec db.Keyset db.Status
db.Export.Doc db.Keyset.Add db.Use

Library Overview

The Database Extreme Library is a share library for PDA Toolbox applications.  It provides database manipulation actions.

This library provides higher level actions for database manipulations including advanced filtering, copying, deleting, and exporting records, and calculating fields.  There are two primary techniques for advanced filtering: Advanced "In-Place" and "Keyset" filtering.  In-place filters are essentially what PDA Toolbox already provides, however, it is limited to one criteria field which is generally a popup filtering a table.  Using the .Select action, you can flag and filter records based on nearly any criteria.  Keysets are new databases that contain a subset of records from a "master" database and a unique key field.  Keyset databases may be edited and the master database updated.  

There are several other actions that include clearing fields, deleting records, and exporting to doc files on a database-wide basis.  You can also calculate both string, numeric, and date fields with the .Set actions.  There are over 40 operators and functions supporting the expression and criteria evaluator.

It is also used as a "Plug-In" to PDAT/Advanced to provide additional Actions to your PDA Toolbox programs.  

This manual assumes the reader has familiarity with the PDAT/Advanced application.

The Database Extreme Library is a Shareware Library for the Palm OS® 3.1 and above unless noted (e.g. FmtDate() function).  The distribution module requires 40k of storage memory.  For more information click here.

Plugging In The Library

For PDA Toolbox 6.0 Professional

For PDAT/Advanced Only

Before you can use the actions contained in this library, you must first "plug" it into PDAT/Advanced.  Once plugged in and registered, you will be able to use and distribute this library freely.

  1. First, you must have a copy of PDAT/Advanced Version 5.1.2 or greater installed on your development handheld or emulator (recommended).
  2. Install the "PDATDBXLib.prc" library file.
  3. Install the "PDATDBXSym.pdb" symbol database.
  4. At PDAT/Advanced's Open Screen, tap the menu and choose from the Advanced menu "Manage Libraries".
  5. Next, if the "Database Extreme Library" is not shown in the list, tap the "Add" button.
  6. In the "Add Library" dialog, enter in the Library ID of "DBex" (without the quotes).
  7. Next, enter the license information you received when you registered or press OK to use in "trial" mode.
  8. Lastly, tap the "Done" button.

After successful registration, when you are editing actions, you'll have a second button named "Lib" which pops up a list of all the commands available to you.

Distribution

It is recommended that you distribute the runtime version of the library.  This is the "PDATDBXLibRT.prc" file.  This file is smaller than the development library as it does not include any of the code for compiling your application.

Since you are distributing multiple PRC files that must be installed on the hand-held device, you may want to check out Ecamm's NutShell for the Palm OS at http://www.ecamm.com/palm/nutshell.  Nutshell is a unique installer solution, which allows users distribute multiple Palm files and data as a single self-expanding PRC file.  With this tool, the user installs a single file onto their hand-held and the first time your app is run, all the libraries, databases, and sub-programs are automatically unpacked and your app runs.  A very good solution to a sticky problem.

Advanced Filtering Techniques

There are two primary techniques for filtering using the Database Extreme Library: In-place and Keysets.  In-place filters are essentially what PDA Toolbox already provides, however, it is limited to one criteria field which is generally a popup filtering a table.  Using the .Select action, you can flag and filter records based on nearly any criteria.  Keysets are new databases that contain a subset of records from a "master" database and a unique key field.  Keyset databases may be edited and the master database updated.  

I've provided two working demos which you can load onto your emulator: Animals1 and Animals2.  Animals1 demonstrates in-place filtering, and Animals2 demonstrates keyset filters.  See the release notes with those two applications for details about databases, etc.

In-Place Filtering - ANIMALS1

The goal of this demo is to demonstrate advanced queries on the primary database using the SELECT action of the Database Extreme Library. Basically, there are two primary databases: The DATA and QURY. You go to the button (Query Animals) and choose the type, # of legs, and skin and tap (Do It!) to perform the query. The records that match will be check-boxed.

The core selection routine is this:

Script 1307 (Do It!) Button
db.Select pets, DATA, CHCK, "mat(DFld({pets}, {QURY}, 0, {LEGS}), 'All', [LEGS]) AND _
	mat(DFld({pets}, {QURY}, 0, {SKIN}), 'All', [SKIN]) AND _
	mat(DFld({pets}, {QURY}, 0, {CATA}), 'All', [CATA])"
GotoForm 1000

The db.Select will scan the database specified in (pets/DATA) selecting all records that match the criteria (last parameter). The CHCK is the field that recieves the selection status. The criteria is a logical expression that says if the LEGS, SKIN, and CATA fields match the user's query request, then it's selected.

The MAT() function is a matching routine. The first parameter is matched to the rest and if found, returns true. For example, MAT('B', 'A', 'B', 'C') would match 'B' to 'A', 'B', or 'C' and return true since 'B' is in the list.

The DFLD() allows you to access another table's value. This function requires the CreatorID, TypeID, Record Number, and Field to retrieve. The record number will almost always be 0 (first record). 

A word about brackets: A field in the current record is bracketed by [ ] as in [LEGS] - this says "get the value of LEGS and use it" whereas the { } brackets are used to postpone getting the values like "get the field ID itself - not the value". So, the DFLD() method typically uses {LEGS} since you don't want to get the VALUE of LEGS - you want to pass the ID of LEGS. In the MAT() routine, you want to pass the actual value of LEGS so it's bracketed like [LEGS]. Confusing, but it will be clear as you see more examples.

Note that in this script, the expressions can have carriage returns and spaces for clarity (unlike SMBeta). This REALLY helps.

Keyset Filtering - ANIMALS2

Keyset filtering is more complicated because you have to create a temporary database, use it, and then update the master with any potential changes you've made.  There are two primary scripts here:

Script 1307 (Do It!) Button
db.KeySet pets, DATA, pets, DAT1,"Animals Data1", "KEY#", " _
    mat(DFLD({pets}, {QURY}, 0, {LEGS}), 'All', [LEGS]) AND _
    mat(DFLD({pets}, {QURY}, 0, {SKIN}), 'All', [SKIN]) AND _
    mat(DFLD({pets}, {QURY}, 0, {CATA}), 'All', [CATA])" 
db.Use pets, DAT1, "Animals Data1", 1000, 1001
db.Use pets, DAT1, "Animals Data1", 1100, 0
GotoForm 1000

Script 1308 (All Animals) Button
db.KeySet.Update pets, DATA, pets, DAT1, "KEY#"
db.Use pets, DATA, "Animals Data", 1000, 1001
db.Use pets, DATA, "Animals Data", 1100, 0
GotoForm 1000

In script 1307, a KeySet is created with the db.KeySet action. A KeySet is a database that contains a copy of all the selected records from the a main database. It contains link field (Key Set Field) that identifies the record back to the main database. This allows you to update the main database by locating each of the original records and updating them from the KeySet record. 

In this case, the KeySet is created from querying the "Animals Data" (pets,DATA), and any records that match are written into "Animals Data1" (pets,DAT1). In addition, a new field is added, "KEY#", that is the KeySet link field.

The two db.Use actions make the KeySet database specified (pets, DAT1, "Animals Data1") the database that is used by a form and optionally, a table. The first USE changes the main form and table (Form 1000, Table 1001). The second db.Use makes the animal editor to use the KeySet database.

For Script 1308, the goal is to select all animals and update the main database from the KeySet database so any changes get saved. This uses the db.KeySet.Update action which basically reads "Update (pets,DATA) from (pets,DAT1) where KEY#=RecordID".

Stash File Information

With DBX version 1.25, you now have the ability to use a Stash File.  A stash file is a single-record database that stores misc. data for your use.  In a way, it simulates "global" variables.  It can also be used as a more effective clipboard.  While many developers have been creating their own "home-brewed" version of this feature, the DBX stash file is better: 

To delete a stash file, you use the normal delete actions in PDAT.  To clear all or individual fields from the stash file, you can use the db.Stash.Clear action.

Stash Files are only available with PDA Toolbox 6.0 SP6 or higher.

Library Actions Reference

Each Action in the library will be described here.

Specifying Databases

Since databases can be dynamically changed, there needs to be a "portable" way of specifying the database when an action requires it. For any parameters named CID (creator ID) or TID (type ID) or Filename you can use these two forms:


db.Alert expression
Description: Displays a simple information alert.
Parameters: expression  Any valid Database Extreme expression.
Example: 

db.Alert "[LNAM] & ', ' & [FNAM]"
db.Alert "1000/RATE"

Among other things, this action is useful for debugging your scripts. If you are having problems with a big expression, use this action to display portions of the expression to ensure that your expressions are returning what you think they are.  This will usually show you where your problem is.

You may use the current open record's fields.  This action may be used with or without an open database.  The alert's caption is always "Information."


db.Alert.Custom Talt, expression  (PDAT Pro 6.0 SP6 or higher)
Description: Displays a custom information alert.
Parameters: Talt   The ID of an Alert.
  expression  Any valid Database Extreme expression.
Example: 

db.Alert.Custom 1900, "LNAM & ', ' & FNAM"
db.Alert.Custom RateAlert, "1000/RATE"

This will display an alert that you define in your Professional script with data evaluated from the expression.  Among other things, this action is useful for debugging your scripts. If you are having problems with a big expression, use this action to display portions of the expression to ensure that your expressions are returning what you think they are.  

When it returns, it will branch to the nth line after the db.Alert.Custom: The first button tapped goes to the following line, the second button tapped goes to the 2nd line following, the third goes to the third line, etc.  The following example displays a custom alert with three buttons:

Action btnTest
   db.Alert.Custom TestAlert, "LNAM & ', ' & FNAM"
   Goto +3
   Goto +4
   Goto +5
   au.Alert.Custom ResultAlert, "You tapped OK"
   Goto +2 
   au.ALert.Custom ResultAlert, "You tapped Maybe"
   Goto +2
   au.ALert.Custom ResultAlert, "You tapped Cancel"
EndAction

To properly create the alert so that it accepts the text passed to it, you must include in the text the placeholder "^1" as in "Do you want to ^1" where the ^1 is replaced with the text in the db.Alert.Custom action.

You may pass "" if you do not require text to be inserted into the alert.

You may use the current open record's fields.  This action may be used with or without an open database.


db.Append sCID, sTID, dCID, dTID, dFName, Criteria
Description: Copies all records that match a criteria from one database to another.
Parameters: sCID:   Creator ID of the source database that is being queried.
  sTID:   Type ID of the source database.
  dCID:   Creator ID of the destination database that is being written to.
  dTID:   Type ID of the destination database.
  dFName:   Filename of the destination database for use when it needs to be created.
  Criteria:   Any expression that evaluates to a boolean value (true/false).
Example: 

db.Append Test, DATA, Test, BkUp, "MyData Backup", "Year(DATE)=2001"

Writes records from (sCID,sTID) to (dCID,dTID,dFName) that match the criteria.  This action will create the database if it does not exist.  This supports appending an empty (new) record.  New records are placed at the end of the database and you are responsible for resorting the database if required.


db.Append.Rec CID, TID, FName
Description: Appends the current record from the primary database to another database.
Parameters: CID:   Creator ID of the database that the record is being appended to.
  TID:   Type ID of the database.
  dFName:   Filename of the destination database for use when it needs to be created.
Example: 

db.Append.Rec Test, Arch, "MyApp Archive"

Writes the current record to (CID,TID,FName).  This action will create the database if it does not exist.  If the record is new (blank), then this will generate an error.


db.Clear CID,TID,Fld, ...
Description: Clears one or more fields from the entire database.
Parameters: CID:   Creator ID of the database to clear the fields from.
  TID:   Type ID of the database to clear the fields from.
  Fld ... A list of database fields separated by a comma.
Example: 

db.Clear Test, DATA, CRED, DEPO

This will remove one or more fields from the database.  It does not matter if the field does not exist.


db.Clear.If CID,TID,Fld, ..., Criteria
Description: Clears one or more fields from the entire database based on a criteria.
Parameters: CID:   Creator ID of the database to clear the fields from.
  TID:   Type ID of the database to clear the fields from.
  Fld ... A list of database fields separated by a comma.
  Criteria Any expression that evaluates to a boolean value (true/false).
Example: 

 db.Clear.If Test, DATA, CRED, DEPO, "CHCK<>0"

This will remove one or more fields from the database based on a criteria.  If the criteria is true, then the fields are cleared.  It does not matter if the field does not exist.


db.Clear.Rec fld, ...
Description: Clears one or more fields from the current record.
Parameters: Fld ...  A list of database fields separated by a comma.
Example: 

db.Clear.Rec CRED, DEPO

This will remove one or more fields from the primary (opened) database.  This supports clearing data in a new record.  New records are placed at the end of the database and you are responsible for resorting the database if required.


db.Copy.Rec sCID, sTID, Fld..., Criteria
Description: Copies specific fields from another database into the current record based on a criteria
Version:

1.05

Parameters: sCID:   Creator ID of the database to copy the fields.
  sTID:   Type ID of the database to copy the fields.
  sFld ... A list of database fields from the source database separated by a comma.
  Criteria Any expression that evaluates to a boolean value (true/false).
Example: 

 db.Copy.Rec Test, DATA, ADR1, ADR2, CITY, "LNAM='smith'"

Think of this action as a light-weight join.  It opens the database (sCID,sTID) and finds the first record that satisfies the Criteria.  Then it copies the fields specified into the currently open record. This will not throw an error if the record is new. 


db.Create CID, TID, Filename
Description: Creates a new database (empty)
Version:

1.12

Parameters: CID:   Creator ID of the new database
  TID:   Type ID of the new database
  Filename:  Filename for the new database
Example: 

 db.Create Test, DATA, "MyDBData"

This action will create a database using the CID/TID and Filename.  If the database is already created this action proceeds normally.  If, for some reason, the database could not be created or opened normally, then this action returns an error and the script will stop. 


db.Delete CID,TID, Criteria [,deleteStyle]
Description:  Removes all records from a database that match a criteria.
Parameters: CID:   Creator ID of the database to be processed.
  TID:   Type ID of the database to be processed.
  Criteria:   Any expression that evaluates to a boolean value (true/false).
  deleteStle:   Optional.  If provided, must be a string starting with "R", "D", or "A".
Example: 

db.Delete Test,DATA, "Year([DATE]) < 2002"
db.Delete Test,DATA, "Year([DATE]) < 2002", "A"

This will remove all records from the specified database where the criteria evaluates to True or non-zero.  The database remains if all records are deleted.

PDAT Professional Only: The deleteStyle parameter is a string parameter defined as:

    "R", "r", "Remove": Physically removes the record from the database.  This should only be used if you application does not support conduits.

    "D", "d", "Delete": Marks the record for deletion and removes the data.  The record becomes "invisible" to the app.

    "A", "a", "Archive": Marks the record for deletion, but does not remove the data.  The record becomes "invisible" to the app.

NOTE: If you delete the record that is being displayed on your form (e.g. a record edit form), that record may remain defined but in a "new" state.


db.Delete.Dups CID,TID, KeyField [,deleteStyle]
db.Delete.DupsNC CID,TID, KeyField [,deleteStyle]
Description:  Removes all records from a database that match a criteria.
Parameters: CID:   Creator ID of the database to be processed.
  TID:   Type ID of the database to be processed.
  KeyField:   Key field for duplicate comparisons
  deleteStle:   Optional.  If provided, must be a string starting with "R", "D", or "A".
Example: 

db.Delete.Dups Test, DATA, SSN#

This will remove all duplicate records from the specified database where the KeyField matches.  The first of a set of duplicate records is retained.  This is a sequential delete so it will be a lengthy operation, however, record order is maintained.  To perform a comparison on multiple fields, you first must make a key field from the concatenated values using the db.Set action.  

Example Script for multiple duplicate check:

db.Set Test, DATA, TFLD, text, "LNAM & FNAM"
db.Delete.Dups Test, DATA, TFLD
db.Clear Test, DATA, TFLD

The above example first creates a test field (TFLD) from the last name (LNAM) and first name (FNAM) fields.  Then it deletes duplicates based on the test field (TFLD).  Lastly, it deletes the remaining TFLD field.

The db.Delete.DupsNC action is identical to db.Delete.Dups with the exception that when comparing strings, a caseless comparison is performed.

PDAT Professional Only: The deleteStyle parameter is a string parameter defined as:

    "R", "r", "Remove": Physically removes the record from the database.  This should only be used if you application does not support conduits.

    "D", "d", "Delete": Marks the record for deletion and removes the data.  The record becomes "invisible" to the app.

    "A", "a", "Archive": Marks the record for deletion, but does not remove the data.  The record becomes "invisible" to the app.

This operation should be done when not in the primary data editing form.


db.Delete.Rec
Description: Deletes the current record without user-intervention.
Example: 

db.Delete.Rec

Silently deletes the current record from the primary (open) database.  If the record is new, then this will generate an error.  If the the record being deleted is the last record in the database, the new "last" record will become active.

NOTE: Deleting all records in your database will result in a new record being created.


db.Export.Doc CID, TID, DocNameExpression, TextExpression, Criteria
Description:  Exports records to DOC file format.
Parameters: CID:   Creator ID of the database to be processed.
  TID:   Type ID of the database to be processed.
  DocNameExpression:   Any expression that evaluates to a string value.
  TextExpression:   Any expression that evaluates to a string value
  Criteria:   Any expression that evaluates to a boolean value (true/false).
Example: 

db.Export.Doc Test, DATA, "'Accounts'", 
"LNAM & ' ' & FNAM", 
"CHCK=1"

Exports records that match the criteria. For the DocNameExpression, the first record of the database is accessible by field name.  If you want to provide a literal name, you will have to double and single quote it as "'My Doc'" since the single-quoted string is a valid string expression.  TextExpression is written to the DOC file only if the criteria proves true for that record.  A doc file is created regardless of if any records are written to it.


db.Export.Memo CID, TID, TitleExpression, TextExpression, Criteria
Description:  Exports records to the Palm MemoPad file format.
Parameters: CID:   Creator ID of the database to be processed.
  TID:   Type ID of the database to be processed.
  TitleExpression:   Any expression that evaluates to a string value.
  TextExpression:   Any expression that evaluates to a string value
  Criteria:   Any expression that evaluates to a boolean value (true/false).
Example: 

db.Export.Memo Test, DATA, "'Accounts'", 
"LNAM & ' ' & FNAM", 
"CHCK=1"

Exports records that match the criteria. For the TitleExpression, the first record of the database is accessible by field name.  If you want to provide a literal name, you will have to double and single quote it as "'My Doc'" since the single-quoted string is a valid string expression.  TextExpression is written to the Memo file only if the criteria proves true for that record.  A doc file is created regardless of if any records are written to it.  NOTE: There is a limit to the size of memos of around 4 thousands bytes per memo however, if your database being exported is larger than that, then this action will create additional memos with the same title following the first one.


db.Find.Rec Criteria
db.FindNext.Rec Criteria
db.Find.RecEx Criteria  (PDAT Pro 6.0 SP6 or higher)
db.FindNext.RecEx Criteria  (PDAT Pro 6.0 SP6 or higher)
db.FindPrev.RecEx Criteria  (PDAT Pro 6.0 SP6 or higher)
Description: Goes to the record that matches a criteria in the active database. 
Parameters: Criteria:   Any logical expression.
Example: 

db.Find.Rec "NAME=popup(1001)"
db.FindNext.Rec "NAME=popup(1001)"

The db.Find.Rec searches the entire open database matching each record against the criteria specified.  If found, then that record is made active.  If not found, the current record remains active.  db.FindNext.Rec will start searching the database at the record following the current record.   db.FindPrev.Rec will start searching the database at the record before the current record.

The db.Find.RecEx and db.FindNext.RecEx / db.FindPrev.RecEx actions support branching.  If a record is found, then it branches to the following action.  If the record is not found, then it will skip the next action and execute the following action. 

Action btnTest
   db.Find.RecEx "LNAM = Stash({LNAM})"
   Goto +2
   Goto +3
   au.Alert.Custom ResultAlert, "Name was found"
   Goto +2 
   au.ALert.Custom ResultAlert, "Name was NOT found"
EndAction


db.Goto Expression
Description: Evals expression to a jump offset. 
Parameters: Expression:   Any numeric integer expression.
Example: 

db.Goto "2"  (skips the next action)
db.Goto "Rnd(4)+1"   (branches 1 to 4)

This powerful action will evaluate the expression, and use the integer result of the expression as the new jump target.  The result may be negative (branch backwards) or positive (branch forward) and if the value is 0 or out-of-bounds of the number of actions, then the script is effectively halted. 

Action btnTest   
   db.goto "val(USER)"
   Goto @Choice0
   Goto @Choice1
   Goto @Choice2
@Choice0:
   db.Alert "Choice 0 was selected"
   Goto @Continue 
@Choice1:
   db.Alert "Choice 1 was selected"
   Goto @Continue 
@Choice2:
   db.Alert "Choice 2 was selected"
   Goto @Continue 
@Continue:
EndAction


db.GotoForm Expression
Description: Jumps to a calculated form destination.
Parameters: Expression:   Any numeric integer expression.
Example: 

db.GotoForm "1000 + 100"  (goes to form 1100)
db.GotoForm "choose(Rnd(4), 1200, 1300, 1400, 1500)   (goes to a random form)
db.GotoForm "choose(ListI(1007), 1200, 1300, 1400, 1500)   (goes to the form based on the popup list's index)

This powerful action will evaluate the expression, and if the expression evaluates to a positive number greater than zero, will make that the target form ID and jump to that form.   This can be used to jump to random forms, jump to forms selected from a popup list, etc.


db.If Criteria, TaltID
Description: Tests a criteria and when false, halts script and displays a message.
Parameters: Criteria:   Any logical expression.
  TaltID:  The Alert Resource ID in your application.
Example: 

db.If "NAME=popup(1001)", 1099

This action will test the criteria and if it evaluates to true, then will continue to execute the script.  If the criteria fails, the script is halted and the alert you specified from your application is displayed.


db.If.False Criteria
Description: Tests if criteria evaluates to false and continues the script if so.
Parameters: Criteria:   Any logical expression.
Example: 

db.If.False "NAME=popup(1001)"

Tests if criteria evaluates to false and continues the script if so.  If the criteria evaluates to true, then it will stop the script.


db.If.True Criteria
db.If.TrueEx Criteria    (PDAT Pro 6.0 SP6 or higher)
Description: Tests if criteria evaluates to true and continues the script if so.
Parameters: Criteria:   Any logical expression.
Example: 

db.If.True "NAME=popup(1001)"
db.If.TrueEx "NAME=popup(1001)"

db.If.True will test if criteria evaluates to true and continues the script if so.  If the criteria evaluates to false, then it will stop the script.

db.If.TrueEx will test if criteria evaluates to true and branch to the next action if true, of the 2nd action if false.  The script does not stop.

The following example displays a the extended db.If.TrueEx:

Action btnTest
   db.if.True "FNAM=''"
   Goto +2
   Goto +3
   db.Alert.Custom ResultAlert, "[LNAM]"
   Goto +2 
   db.Alert.Custom ResultAlert, "[LNAM] & ', ' & [FNAM]"
EndAction


db.Keyset sCID, sTID, dCID, dTID, dFName, KID, Criteria
Description:  Creates a keyset Database from an existing database.
Parameters: sCID:   Creator ID of the source (master) database
  sTID:   Type ID of the source (master) database.
  dCID:   Creator ID of the keyset (destination) database that is being written to.
  dTID:   Type ID of the keyset (destination) database.
  dFName:   Filename of the keyset (destination) database for use when it needs to be created.
  KID:   The name of the field in the keyset database that should contain the keyset ID (KID).
  Criteria:   Any expression that evaluates to a boolean value (true/false).
Example: 

 See Animals2.zip

Used to create filtered databases that contain only selected records which can update a master database. If the keyset database exists, it will first be deleted before the query is performed.  This is similar to Append, but adds KID, a field you specified to hold the keyset Link ID.


db.Keyset.Add sCID, sTID, dCID, dTID, dFName, KID, Criteria
Description:  Appends additional records to a keyset database.
Parameters: sCID:   Creator ID of the source (master) database
  sTID:   Type ID of the source (master) database.
  dCID:   Creator ID of the keyset (destination) database that is being written to.
  dTID:   Type ID of the keyset (destination) database.
  dFName:   Filename of the keyset (destination) database for use when it needs to be created.
  KID:   The name of the field in the keyset database that should contain the keyset ID (KID).
  Criteria:   Any expression that evaluates to a boolean value (true/false).
Example: 

 See Animals2.zip

This is identical to db.keyset, but appends records to the keyset database.  If the database does not exists then it is created.


db.Keyset.Update dCID, dTID, sCID, sTID, KID
Description: Updates a master database from a keyset database.
Parameters: dCID:   Creator ID of the destination (MASTER) database that is being written to.
  dTID:   Type ID of the destination (MASTER) database.
  sCID:   Creator ID of the source (KEYSET) database
  sTID:   Type ID of the source (KEYSET) database.
  KID:   The name of the field in the keyset database that contains the keyset ID (KID).
Example: 

 See Animals2.zip

This action reads the keyset database and searches for each record in the master database.  If the keyset record is found in the master, then the master is updated with the new value.  If the keyset record is not found, then it is assumed to be a new record and is appended to the master database.  There is no "delete" detection, so you should handle deletes by marking records for delete, updating the master, then deleting the records from the master (and keyset, if you are wanting to keep it around).

This action will not work if there is no master database.  If there is a chance that your master database will not exist, then call the db.Create action before calling this to create a database (if needed).


db.Renum CID, TID, fld
Description:  Renumbers a database field based on the physical record number.
Parameters: CID:   Creator ID of the database to renumber.
  TID:   Type ID of the database to renumber.
  Fld:   The string field to hold the record number.
Example: 

db.Renum TEST, DATA, RECN

Renumbers a database field based on the record number (starting at 1).   This is the same as setting a record to the expression "RecNo()"


db.Renum.Key CID, TID, fld
Description:  Rekeys a database based on record ID.
Parameters: CID:   Creator ID of the database to rekey.
  TID:   Type ID of the database to rekey.
  Fld:   The string field to hold the record ID.
Example: 

db.Renum.Key TEST, DATA, RECK

This will renumber a given database using the unique Palm OS record ID.  This is a large number that will not change as long as the record does not get deleted.  It is the same value returned by the function RecID().


db.Select CID, TID, fldX, criteria
Description:  Marks database records as selected based on the criteria.
Parameters: CID:   Creator ID of the database to query.
  TID:   Type ID of the database to query.
  FldX:   The BOOLEAN field to indicate if the record is selected.
  Criteria:   Any expression that evaluates to a boolean value (true/false).
Example: 

db.Select Test, DATA, "CHCK", "NUMB > 10000"
See also: Animals1.zip

This is used to check-mark records that match a criteria.  


db.Set CID, TID, Fld, Fld-Type, Expression [, Criteria]
db.SetEx CID, TID, [Fld, Fld-Type, Expression]... [, Criteria]
Description:  Sets a field in an entire database to the expression.
Parameters: CID:   Creator ID of the database to process.
  TID:   Type ID of the database to process.
  Fld:   The field ID that will get the evaluated result of expression.
  Fld-Type:   The database field type of FLD (string, number, bool, date, or time)
  Expression:   An expression that evaluates to the type specified in Fld-Type.
  [Criteria]:   Optional, any expression that evaluates to a boolean value (true/false).
Example: 

db.Set TEST, DATA, FULL, text, "LEFT(FNAM,1) & LNAM"
db.Set TEST, DATA, FULL, text, "LEFT(FNAM,1) & LNAM", "CHCK=1"
db.SetEx TEST, DATA, FNAM, text, "LEFT(FNAME,1)", FULL, text, "FNAM & LNAM", "CHCK=1"

Sets the "fld" to the value of expression for the entire database.   If criteria is provided, then only those records matching Criteria will have the expression set.  This action does not clear the existing contents if criteria is provided. 

Fld-Type is a string with any of these values:

The db.SetEx action is set up to take multiple sets of Fld, Fld-Type, and Expression parameters so you perform multiple calculations with one action.  This reduces both the flicker and increases the speed of the calculations.  The speed is increased proportionally with the number of calculations performed.  Expressions are calculated left to right so if you calculate a field in the first and use the field in the second expression, then the use will be the value of the calculated value, not the original value.  The Criteria parameter, if provided, applies to all the calculations in the action,

NOTE:  DINKs fields are not supported.


db.Set.Rec Fld, Fld-Type, Expression
Description:  Sets a field in the current record to the value of Expression.
Parameters: Fld:   The BOOLEAN field to indicate if the record is selected.
  Fld-Type:   The database field type of FLD (string, number, bool, date, or time)
  Expression:   An expression that evaluates to the type specified in Fld-Type.
Example: 

db.Set.Rec FULL, text, "LEFT(FNAM,1) & LNAM"

Sets the "fld" to the value of expression for the current record.   This supports creating a new record.  New records are placed at the end of the database and you are responsible for resorting the database if required.

Fld-Type is a string with any of these values:

The db.Set.RecEx action is set up to take multiple sets of Fld, Fld-Type, and Expression parameters so you perform multiple calculations with one action.  This reduces both the flicker and increases the speed of the calculations.  The speed is increased proportionally with the number of calculations performed.  Expressions are calculated left to right so if you calculate a field in the first and use the field in the second expression, then the use will be the value of the calculated value, not the original value.

NOTE:  DINKs fields are not supported.


db.StackSize size
Description: Sets the depth of the evaluation stack.
Parameters: size:   An integer value for the stack size.  
Example: 

db.StackSize 30 'The default size
db.StackSize 50 'for a much more complicated expression

This allows the evaluation stack to be adjusted for more complicated expressions (or simpler ones if adjusting downward).  The amount of memory is proportional to the size of the stack.  By default, the stack size is set to 30.  This is sufficient for 99% of applications.  If your expression is VERY complicated, then you may need to increase it.  To estimate the size of the stack needed, you must consider the maximum depth of nested terms and all operands and function calls within the nested expression.

Some examples:

5+2 This expression has a nesting of 2 (5, 2, and then it gets evaluated to 7).
(5*(2+1)) This is nested to 3 (5, 2, 1 then + adds 2 and 1 to 3, then 5 * 3 = 15)
5*int([FLDX]) This is nested to 3 (5, int(), FLDX)
iif(x, iif(y, iif(z, 10, 20), 30), 40) This is nested to 8 (iif(), x, iif(), y, iif(), z, 10, 20 before the inner iff gets evaluated.

In general, if you are having problems with a big expression with lots of function calls and parans, then increase the stack by 10 at a time.  You probably don't want to go over 100.

The StackSize affects all expressions that are executed after it until it is changed.

This action is available only with the PDAT 6.0 Pro Script Compiler due to memory constraints.


db.Stash.Clear [ fld, ...] (PDAT Pro 6.0 SP6 or higher)
Description: Clears all or selected fields from the stash file.
Parameters: Fld ...  An optional list of database fields separated by a comma.
Example: 

db.Stash.Clear CRED, DEPO
db.Stash.Clear

If fields are provided, then this will remove those fields from the stash file database.  If no fields are provided, then all fields are cleared from the stash file.  There are no warnings.


db.Stash.Data Fld, Fld-Type, Expression [, Fld, Fld-Type, Expression]...    (PDAT Pro 6.0 SP6 or higher)
Description: Stashes calculated data into the stash file.
Parameters: Fld:   The field ID that will get the evaluated result of expression.
  Fld-Type:   The database field type of FLD (string, number, bool, date, or time)
  Expression:   An expression that evaluates to the type specified in Fld-Type.
Example: 

 db.Stash.Data FULL, text, "LEFT(FNAM,1) & LNAM"

This action will evaluate each of the expressions and assign them to fields in the stash file database.  This essentially creates a "global" set of fields or a better clipboard.   You must include at least one set of data (Fld, Type, Expression) but you may include more.

You can access any of the stashed data using the Stash( ) function.  You do not need to have an open record to use this action.  This means you should be able to use it in the eventStartup script or other places where there is no current record active.

Fld-Type is a string with any of these values:

NOTE:  DINKs fields are not supported.


db.Stash.File CID, TID, Filename   (PDAT Pro 6.0 SP6 or higher)
Description: Opens or creates a new Stash File.
Parameters: CID:   Creator ID of the new database
  TID:   Type ID of the new database
  Filename:  Filename for the new database
Example: 

 db.Stash.File CRID, STSH, "MyApp-STSH"

This action will create a stash file using the CID/TID and Filename.  It also ensures that there is a single record defined.  If, for some reason, the database could not be created or opened normally, then this action returns an error and the script will stop.   This action is best used in the startupEvent, but it may be used anywhere.  You may also use it multiple times with different CreatorID/TypeID pairs - though only the last one defined will be the active one.

If there is existing data in the stash file, it remains.  To clear out existing data, either delete the stash file before this action, or use the db.Stash.Clear to clear selected fields. 


db.Status colorIndex, "Message"
Description:  Changes the color and text of the status message.
Parameters: colorIndex:   An integer value of the color to use.
  Message:   The text of the message.  Maximum length, 32 characters.
Example: 

db.Status 49, "Purging Database..."
db.Status 0, default

All actions in this library that process an entire database display a small, framed, message as the processing is performed.  The color of the frame is controlled by colorIndex and is a number between 0 and 250 but it defaults to UIFrameColor (slightly purple).  Each action provides a default message which can be overridden with this action.  Once set, you must set the original text back by setting the message to "default".   

There are a couple of things to keep in mind about this action and status messages in general.  If you have turned off redraw in your script, then no status messages will be displayed at all.  If you leave it on, then the status messages are display, but there is a flicker as they are being erased for the next action.


db.Use CID, TID, FName, FormID, TableID
Description:  Sets a form/table up to use a specific database.
Parameters: CID:   Creator ID of the database to use.
  TID:   Type ID of the database to use.
  FName:   Filename of the database to use.
  FormID:   The ID of the Form you want to make use the database.
  TableID:   The ID of the Table you want to make use the database.
Example: 

db.Use TEST, DAT1, "MyApp Data1", 1000, 1001
db.Use TEST, DAT1, "MyApp Data1", 1000, 0
db.Use TEST, DAT1, "MyApp Data1", 0, 1001

Sets a form to use the CID, TID, Filename (FName) for Form ID "FormID" and Table ID "TableID". FormID or TableID may be 0 if there is no table.

Function and Evaluator Reference

Here are the conventions I use to use and document the evaluator:

Database Fields

You can reference database and record fields in one of two ways: By value or by reference.  The "by value" means that you want the field's value (or contents) from the record or database.  The "by reference" means that the field name itself is the value.  You'd use "by value" most of the time as it gets you the value you are mostly interested in.  However, when you need to pass the name of the field to a function, you would use the "by reference" form.

String Literals

Constants

Operators

Data Types and Calculations

When performing math, two integer values will always have an integer result (e.g. 10 / 3 = 3).  If a floating point number is involved in the expression, then the result is always a floating point (e.g. 10 / 3.0 = 3.33333).

The concatenation operation ("&") will convert numbers to a string so 'Rick' & 8 = 'Rick8', also 32 & 5 = '325'.  This avoids having to constantly use the STR(x) function to convert numbers to strings.  Dates, times, and field references, when implicitly converted to a string are converted as a number, so 1am would be the string '60' (60 minutes since midnite).

For logical operators, both operands must be strings to kick in the string comparisons.  You cannot use AND, OR, NOT with strings.  For floats, NOT is treated as a negating operator.

MathLib Functions Support

None!  I make no claim to knowing anything about the functions contained in MathLib.  Your best bet is to consult the MathLib documentation and lookup the functions that are supported here in the MathLib Function Reference.

Functions Parameter and Return Types Notation

Logical Functions

cmp

i = cmp(s1, s2)
String compare: i=0 if s1=s2, i=-1 if s1<s2, i=1 if s1>s2
choose
x = choose(i, x1, x2, x3...)
Chooses a result based on i.  The variable i should be between 0 and x.  For example, choose(0, 'red', 'white', 'blue') would result in 'red' (the zero'th choice).  Although i must be a numeric value, you can mix any numbers and strings in the resulting list.
iif
x = iif(iTest, xTrue, xFalse)
Returns value of xTrue if iTest<>0, otherwise xFalse. Both xTrue and xFalse are evaluated and may be any kind of value.
mat
i = mat(xTarget, xTest1, xTest2...)
Returns true if xTarget matches any of the remaining arguments.
missing
i = missing({vfld})
Returns true if the field specified is not in the record (e.g. it's missing)
Example: FNAM & iif(Missing({MNAM}), ' ', MNAM & '. ') & LNAM 
def
i = def({vfld})
Returns true if the field specified exists in the record and it is a valid value for the field type.
Example: FNAM & iif(Def({MNAM}), MNAM & '. ', '') & LNAM 

String Functions

char
s = char(s, i)
Return i'th character
clipboard
s = clipboard()
Returns the string (if any) contained in the clipboard.  If the clipboard is empty, then the resulting string is "".  If the clipboard contains a number, then it is returned in the string form, so if you want it as a number, use Val(Clipboard()).
crc
i = crc(s, i)
Returns a unsigned integer (0 to 65k) representing the CRC16 of the string s.  The parameter i is the "seed value" which modifies the crc of the string.
extract
s 	= extract(src, target, index)
Returns the index'th string in src delimited by target.  This allows you to treat a string as an array of strings delimited by some string/character.  For instance, "extract('ABC#DEFG#HIJ', '#', 1)" would return 'ABC' and a index of 2 would return 'DEFG'.  0 or indexes beyond what's there will result in "" being returned: "extract('ABC#DEFG#HIJ', '#', 4)" would return "".  If a "$" is your delimiter, be sure to use '\4' as the embedded code: "extract([AMTS], '\4', 2)" would extract the numeric amount from a currency string (e.g. if [AMTS] was "$1000", then it would return 1000).
lcase
s = lcase(s)
Returns the string s as all lowercase, for instance lcase('LIB') = 'lib'.  This function may not work for non-US English strings.
left
s = left(s, i)
Leftmost i characters
len
i = len(s)
Returns the length of the string s.  This value may be zero.
lpad
s = lpad(s, x)
Left justifies s in a field of x spaces.
mid
s = mid(s, iStart, iCount) 
Substr starting at iStart for iCount characters.
pos
i = pos(src, target)
Returns the character position of target in src.  For instance, "pos('Rick@SandsUSA.com', '@')" would equal 5.
right
s = right(s, i)
Right-most i characters
rightTo
s = rightTo(s, i)
Right-most starting from i'th position
rpad
s = rpad(s, x)
Right justifies s in a field of x spaces.
spc
s = spc(x)
Creates a string of x spaces.
ucase
s = ucase(s)
Returns the string s as all uppercase, for instance ucase('lib') = 'LIB'.  This function may not work for non-US English strings.

Conversion Functions

fix
s = fix(n, i)
Attempts to convert any value into a string while formatting the number to i decimal places.  If there are more decimal digits than i, the remaining digits are truncated (e.g. fix(1.2345, 2) is fixed to 1.23 and fix(10, 3) is fixed to 10.000)
loc
s = loc(n, cDP, cComma)
Attempts to convert the number n to a localized number.  cDP and cComma are the character values to use, of use the value 'd' to specify the default (system preferences).  NOTE: This function should be used for non-calculated fields, for example, when exporting due to PDA Toolbox always assuming no group formatting and a decimal point of '.'.
str
s = str(n)
Attempts to convert any value into a string
val
n = val(s)
Attempts to convert any value into a number

Date Functions

fmtDate
s = FmtDate(s, d)

This function formats a DATE as you want it.  Any or all components of the date may be used or ignored.  NOTE: This function requires a minimum of OS 3.5.
This function uses the formatting template referenced by s to create a formatted string from the date values that you pass in. 
You specify a series of formatting substrings in s. Each substring has the form:

^<valueType><formatModifier>

Each substring has three components:

  • The ^ character begins a substring.

  • The <valueType> component is a single-digit value that specifies the value type.

  • The <formatModifier> component is a single-letter value that specifies how you want that value formatted.

The following is an example of a template specification with three substrings:

^0z ^2l ^4r

The <valueType> component is show below. Note that the formatted result depends on the <modifier> value.

<valueType> What? Example
0  Day number 1, 01, 23, 31
1 Day name Tue, Tuesday
2 Month name May, Aug, August
3 Month number 4, 04, 11
4 Year number 97, 1997

Here are the values you can specify for the <modifier> component of each template substring.

<modifier> Description
s Formats the value in short form
r Formats the value in regular form
l Formats the value in long form (lowercase L)
z Adds a leading zero to the formatted numeric value
day
i = day(d)
Returns Day value of Date (e.g. 1 to 31)
month
i = month(d)
Returns Month value of Date (e.g. 1 to 12)
year
i = year(d)
Returns Year value of Date (e.g. 2002)
qtr
i = qtr(d)
Returns quarter number from date (e.g. 1-4 (4=4th Quarter))
toDate
d = toDate(i,i,i)
Returns date. (e.g. ToDate(2,15,2002) returns value for Feb. 15, 2002)
DateStr
s = DateStr(d)
Returns date. (e.g. DateStr(d) returns string formatted via sys prefs
today
x = today(i)
Returns the current date.  The i parameter indicates what "kind" of date you desire:
  • 0: A PDA Toolbox Date value assignable to a DATE field
  • 1: The month part (e.g. 1 to 12)
  • 2: The day part (e.g. 1 to 31)
  • 3: The year part (e.g. 2003)
  • 4: The current Quarter (e.g. 1 to 4)
  • 5: As a string (e.g. '12/31/02')

Time Functions

hour
i = hour(t)
Returns hours value of Time.  This is in 24 hour notation (e.g. 0 to 23).
min
i = min(t)
Returns minutes value of Time.  (e.g. 0 to 59).
ToTime
t = toTime(iHr, iMin)
Returns a Time value from iHr and iMin.  Calculated as minutes since midnite: (iHr * 60) + iMin
TimeStr
s = timeStr(t)
Returns a time formatted with the system preferences as a string
now
x = now(i)
Returns the current time.  The i parameter indicates what "kind" of time you desire:
  • 0: A PDA Toolbox Time value assignable to a TIME field
  • 1: The hour part (e.g. 0 to 23)
  • 2: The minute part (e.g. 0 to 59)
  • 3: Seconds since 1/1/1904 (PDAT Alarm Type)
  • 4: As a string (e.g. '3:50 pm')

Alarm Functions

adate
d = adate(a)
Returns a date from an alarm type date/time.  PDA Toolbox Alarm Type is actually the number of seconds since 1/1/1904.  Use NOW(3) to get the current date/time.
atime
t = atime(a)
Returns a time from an alarm type date/time.

Database Functions

RecCnt
i = RecCnt()
Returns the number of records for the current database.    Does not count "deleted (but not removed)", or "archived" records.
RecID
i = RecID()
Returns the unique record ID of the current record.
RecNo
i = RecNo()
Returns record number. First record is 1. This is a transient value.
DName
s = dname()
Returns name of the current database without the .pdb file extension.
DCnt
i = dcnt({vCID},{vTID})
Returns record count for specified database (vc,vt).  Does not count "deleted (but not removed)", or "archived" records.
DFld
x = dfld({vCID},{vTID},RecNo,{vfld})
Returns field's value (vt) from external database (vc,vt) at record #(i). First record is 0.
DSum
x = dsum({vCID},{vTID},{vfld})
Returns sum of database field not including NULL fields.
DAvg
x = davg({vCID},{vTID},{vfld})
Returns average of database field not including NULL fields.
DMin
x = dmin({vCID},{vTID},{vfld})
Returns minimum value of database field not including NULL fields.
DMax
x = dmax({vCID},{vTID},{vfld})
Returns maximum value of database field not including NULL fields.

Control Functions

Field
s = field(id)
Retrieves the string from the textbox specified by ID.
Popup
s = popup(id)
Retrieves the string from the popup trigger specified by ID.
Checkbox
i = checkbox(id)
Retrieves the value (0,1) from the checkbox specified by ID.
Radio
i = radio(id)
Retrieves the value (0,1) from the radio button specified by ID.
List
s = list(id)
Retrieves the string from the listbox specified by ID.  NOTE: The value cannot be retained as PDAT does not support listboxes.
ListI
i = listI(id)
Retrieves the selected value (-1 to n-1) from the listbox specified by ID.  NOTE: The value cannot be retained as PDAT does not support listboxes.
Slider
i = slider(id)
Retrieves the selected value (0 to n) from the slider control specified by ID.  NOTE: The value cannot be retained as PDAT does not support sliders.

Non-Mathlib Math Functions

Rnd
i = Rnd(i)
Returns random number between 0 and (i-1)
Abs
i = Abs(i)				z
Integer absolute value (floating point uses MathLib)

Misc. Functions

FormID i = FormID() Returns the current form ID or 0 if the form ID is undefined (e.g. during special scripts).
Stash x = Stash( {vfld} ) Return a value from the stash file.  The field ID passed in must be in curly-brackets { }

MathLib Function Reference

I make no claim to knowing anything about the functions contained in MathLib.  Your best bet is to consult the MathLib documentation.

abs f = abs(f) int f = int(f)
acos f = acos(f) log f = log(f)
acosh f = acosh(f) log10 f = log10(f)
asin f = asin(f) log1p f = log1p(f)
asinh f = asinh(f) log2 f = log2(f)
atan f = atan(f) logb f = logb(f)
atan2 f = atan2(f1, f2) nextafter f = nextafter(f1, f2)
atanh f = atanh(f) pow f = pow(f1, f2)
cbrt f = cbrt(f) remainder f = remainder(f1, f2)
ceil f = ceil(f) round f = round(f)
cos f = cos(f) scalb f = scalb(f1, f2)
cosh f = cosh(f) sin f = sin(f)
drem f = drem(f1, f2) sinh f = sinh(f)
exp f = exp(f) sqrt f = sqrt(f)
expm1 f = expm1(f) tan f = tan(f)
floor f = floor(f) tanh f = tanh(f)
fmod f = fmod(f1, f2) trunc f = trunc(f)
hypot f = hypot(f1, f2)    
Purchasing Information and Support

This program is not Freeware.  It is Shareware.  This means that you can, and should, try the demo out before buying.  Shortly after you register via PayPal you will receive an unlock key that will enable developing with this library.

 The cost of this package is US$12.95.

Primary support for this library is at the PDAT Nuts & Bolts Support Forum at www.PDATNutsAndBolts.com.

You can always contact me at:  email: Rick@SandsUSA.com or at my site http://www.SandsUSA.com.

Warranty and User License Agreement

"The Software" is "Database Extreme Library" aka "PDATDBXLib.prc" by Richard R. Sands dba Sands USA.

DISCLAIMER #1 - MUST READ

This product is an "After-Market" utility for PDA Toolbox(tm) and as such, is subject to obsolescence by changes in PDA Toolbox or the Palm OS(tm) itself.  This cannot be prevented.  I may choose to stop or limit development and support of this product if such situation occurs. 

USER LICENSE AGREEMENT

This Agreement sets forth your licensed rights to use "The Software" and is granted to you upon condition that you accept the terms of this license. Your electronic indication of agreement, or your use of the program constitute acceptance of all of the terms of this license.

The program copy and documentation are furnished to make "The Software" available for your use and remain the property of Sands USA.

IF YOU DO NOT AGREE WITH ANY PART OF THIS LICENSE, DO NOT USE THIS SOFTWARE. Delete "The Software" and all associated files from all media on which it has been copied. 

LICENSE TERMS AND CONDITIONS

THE LICENSED PRODUCT
"The Software" comprises copyrighted computer programs and utilities for the reporting of Palm OS(tm) application databases (PRC) created by the PDA Toolbox(tm) Application Generator. The Licensed Product in its entirety is protected by US and foreign copyright.  YOU MAY NOT DISTRIBUTE THE LICENSE CODE provided to you.

YOUR USE OF THE LICENSED PRODUCT
General Use. You have the right to use "The Software" with PDAT/Advanced and to distribute the library file "PDATDBXLib.prc"  or "PDATDBXLibRT.prc" but license codes, or other information about this library.  For those purposes, you have the right to install the "The Software" and any associated files on one (1) computer. Use of "The Software" on a network or any other arrangement by which its functions are accessible to more than one user at a time is not permitted. 

LIMITATIONS ON USE
General Use Limitations. You have no right to reproduce, transfer, publish or otherwise distribute either the "The Software" software, or any components or documentation provided.

ALL RIGHTS NOT SPECIFICALLY GRANTED BY THIS LICENSE ARE RESERVED BY SANDS USA. 

WARRANTIES, WARNING, DISCLAIMER

Warning and Disclaimer of All Warranties. THE PROGRAM IS FURNISHED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, IN ALL JURISDICTIONS WHERE ALL WARRANTIES MAY BE DISCLAIMED IN THE LICENSING OF INTELLECTUAL PROPERTY.


PDAT/Advanced is Copyrighed by Richard R. Sands dba Sands USA
Database Extreme Library is Copyrighed by Richard R. Sands dba Sands USA
PDAT Toolbox is Copyrighted by Paul Prejean
Nutshell executable and documentation are Copyright ©2002-2004 by Ecamm Network. All rights reserved.
RsrcEdit is apparently not copyrighted by Quartus, but they are the caretakers of RsrcEdit.
Database Extreme Documentation Copyright (C) 2002-2004 Richard R. Sands dba Sands USA
All Rights Reserved
Microsoft Windows, Microsoft Office, Microsoft Visual Studio, Microsoft Visual Studio .NET, Microsoft Visual Basic, and Internet Explorer are Trademarks of, and copyrighted by, Microsoft Corporation
PDA Toolbox Professional is copyrighted by Paul R. Anderson and Richard R. Sands
RsrcEdit is apparently not copyrighted but maintained at www.Quartus.net
And Finally, ...
palmOne, Zire, Tungsten, Treo, Blazer, VersaMail, Addit, Handspring, stylizations and design marks associated with all the preceding, and trade dressassociated with palmOne, Inc.’s products, are among the trademarks or registered trademarks owned by or exclusively licensed to palmOne, Inc. All other brand and product names are or may be trademarks of, and are used to identify products or services of, their respective owners.