Clipper Reference Guide

< | 

Less than—binary (Relational)
Syntax
<exp1> < <exp2>
Description

The less than () operator is a binary operator that compares two values of the same data type and returns true (.T.) if <exp1 is less than exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for "A" is 65 and the code for "Z" is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: False (.F.) is less than true (.T.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples
■  These examples illustrate how the less than operator (<)
   behaves with different data types:

   // Character
   ? "Z" < "A"                 // Result: .F.
   ? "ZA" < "A"                // Result: .F.
   ? "A" < "AZ"                // Result: .T.

   // Date
   ? CToD("12/12/88") < ;
      CToD("12/11/88")         // Result: .F.

   // Logical
   ? .F. < .T.                 // Result: .T.


   // Numeric
   ? 2 < 1                     // Result: .F.
   ? 1 < 2                     // Result: .T.
Platforms
Available on MS-DOS
See also

<= | 

Less than or equal—binary (Relational)
Syntax
<exp1> <= <exp2>
Description

The less than or equal (<= ) operator compares two values of the same data type and returns true (.T.) if exp1 is less than or equal to exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for "A" is 65 and the code for "Z" is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: False (.F.) is less than true (.T.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples
■  These examples illustrate how the less than or equal operator
   (<=) behaves with different data types:

   // Character
   ? "Z" <= "A"               // Result: .F.
   ? "ZA" <= "A"              // Result: .F.
   ? "A" <= "AZ"              // Result: .T.

   // Date
   ? CToD("12/12/88") <= ;
      CToD("12/11/88")        // Result: .F.


   // Logical
   ? .F. <= .T.               // Result: .T.

   // Numeric
   ? 2 <= 1                  // Result: .F.
   ? 1 <= 2                  // Result: .T.
   ? 1 <= 1                  // Result: .T.
Platforms
Available on MS-DOS
See also

<> != # | 

Not equal—binary (Relational)
Syntax
<exp1> <> <exp2>
<exp1> != <exp2>
<exp1> #  <exp2>
Description

The not equal ( <>) operator compares two values of the same data type and returns true (.T.) if exp1 is not equal to exp2 according to the following rules:

■ Character: The comparison is based on the underlying ASCII

code and is the inverse of the equal operator (=). This means that the comparison is sensitive to the current EXACT SETting. See the examples below.

■ Date: Dates are compared according to the underlying date

value.

■ Logical: False (.F.) is not equal to true (.T.).

■ Memo: Treated the same as character.

NIL: All values compared to NIL other than NIL return true

(.T.).

■ Numeric: Compared based on magnitude.

Examples
■  These examples illustrate how the not equal operator (<>)
   behaves with different data types:

   // Character
   SET EXACT ON
   ? "123" <> "12345"         // Result: .T.
   ? "12345" <> "123"         // Result: .T.
   ? "123" <> ""              // Result: .T.
   ? "" <> "123"              // Result: .T.
   SET EXACT OFF
   ? "123" <> "12345"         // Result: .T.
   ? "12345" <> "123"         // Result: .F.
   ? "123" <> ""              // Result: .F.
   ? "" <> "123"              // Result: .T.

   // Date
   ? CToD("12/12/88") <> ;
      CToD("12/12/88")        // Result: .F.

   // Logical
   ? .T. <> .T.               // Result: .F.
   ? .T. <> .F.               // Result: .T.

   // NIL
   ? NIL <> NIL               // Result: .F.
   ? NIL <> 12                // Result: .T.
   ? NIL <> "hello"           // Result: .T.

   // Numeric
   ? 2 <> 1                   // Result: .T.
   ? 1 <> 1                   // Result: .F.
Platforms
Available on MS-DOS
See also

= (assign) | 

Simple assign—binary (Assignment)
Syntax
<idVar> = <exp>
Description

The simple assignment operator (=) assigns a value to a variable. It is identical in operation to the STORE command that initializes a single variable and must be specified as a program statement. The inline assignment operator (:=) is like the = operator except that you can specify it within expressions. If you specify the simple assign operator (=) within an expression, it is interpreted as the equality (=) operator.

Note: You cannot initialize a specific variable using the simple assign operator (=) in a declaration statement. Only the inline assign (:=) operator can be used for this purpose.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. At runtime, if no private or public variable exists with the specified name, a private variable is created. To assign a field variable with the = operator, you must declare the field variable name in a FIELD statement or refer to the field name prefaced by the FIELD-> alias or the name of the work area.

Examples
■  These examples are valid simple assignment statements:

   nValue = 25
   nNewValue = Sqrt(nValue) ** 5
   nOldValue = nValue

■  In this example, the two lines are equivalent:

   FIELD->CustAge = 20
   REPLACE CustAge WITH 20
Platforms
Available on MS-DOS
See also

= (compound assign) | 

Compound assignment—binary (Assignment)
Syntax
<idVar>  += <cString>         (concatenation)
<idVar>  += <nNumber>         (addition)
<idVar>  -= <cString>         (concatenation)
<idVar>  -= <nNumber>         (subtraction)
<idVar>  -= <dDate>           (subtraction)
<idVar>  *= <nNumber>         (multiplication)
<idVar>  /= <nNumber>         (division)
<idVar>  %= <nNumber>         (modulus)
<idVar>  ^= <nNumber>         (exponentiation)
Description

In addition to the simple and inline assignment operators (= and :=), there are a series of compound assignment operators that perform an operation then assign a value. They have the form:

idVar operator= exp

Each compound assignment expression is equivalent to the assignment expression:

idVar := ( idVar operator exp )

For each data type that supports an operator, the compound assignment operator performs the same operation before performing the assignment operation. The following table details all of the compound operators:

Compound Operators

    Operator     Defined as     Operations
    a += b       a := (a + b)   concatenation, addition
    a -= b       a := (a - b)   concatenation, subtraction
    a *= b       a := (a * b)   multiplication
    a /= b       a := (a / b)   division
    a %= b       a := (a % b)   modulus
    a ^= b       a := (a ^ b)   exponentiation

Note: The exponentiation operator (**) does not have a corresponding compound assignment operator. The exponentiation compound assignment operator is ^=.

Since the compound assignment operators are based on the inline assignment operator (:=), the operation returns the result of its operation as the value of the expression. This means you can use these operators within expressions just like the inline assignment operator (:=).

Examples
■  These examples use the compound addition and concatenation
   assignment operator:

   // Character (concatenation)
   LOCAL cString := "Hello"
   ? cString += " there"           // Result: "Hello there"

   // Date (addition)
   LOCAL dDate := CToD("12/12/90")
   dDate += 12                     // Result: 12/24/90

   // Numeric (addition)
   LOCAL nValue := 10
   ? Sqrt(nValue += 15)            // Result:  5.00
   ? nValue                        // Result: 25.00

■  These examples use the compound subtraction and concatenation
   assignment operator:

   // Character (concatenation)
   LOCAL cString := "Hello   "
   ? cString -= "There"            // Result: HelloThere

   // Date (subtraction)
   LOCAL dDate := CToD("12/24/90")
   dDate -= 12                     // Result: 12/12/90

   // Numeric (subtraction)
   LOCAL nValue := 10
   ? newValue := (nValue -= 5) ** 2       // Result: 25
   ? nValue                               // Result:  5

■  This example uses the compound multiplication assignment
   operator:

   LOCAL nValue := 10
   ? newValue := (nValue *= 5) + 100      // Result: 150
   ? nValue                               // Result:  50

■  This example uses the compound division assignment operator:

   LOCAL nValue := 10
   ? newValue := (nValue /= 5) + 100      // Result: 102.00
   ? nValue                               // Result:   2.00

■  This example uses the compound modulus assignment operator:

LOCAL nValue := 10
   ? newValue := (nValue %= 4) * 100      // Result: 200.00

   ? nValue                               // Result:   2.00

■  This example uses the compound exponentiation assignment
   operator:

   LOCAL nValue := 10
   ? newValue := (nValue ^= 3) + 50       // Result: 1050.00
   ? nValue                               // Result: 1000.00
Platforms
Available on MS-DOS
See also
-, --, :=, /, *, **, %, +, ++

= (equality) | 

Equal—binary (Relational)
Syntax
<exp1> = <exp2>
Description

The equal operator (= ) compares two values of the same data type and returns true (.T.) if exp1 is equal to exp2 according to the following rules:

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for "A" is 65 and the code for "Z" is 90).

When EXACT is OFF, two character strings are compared according to the following rules. assume two character strings, cLeft and cRight, where the expression to test is (cLeft = cRight):

- If cRight is null, returns true (.T.).

- If Len(cRight) is greater than Len(cLeft), returns false

(.F.).

- Compare all characters in cRight with cLeft. If all

characters in cRight equal cLeft, returns true (.T.); otherwise, returns false (.F.).

With EXACT ON, two strings must match exactly except for trailing blanks.

■ Date: Dates are compared according to the underlying date

value.

■ Logical: True (.T.) is equal to true (.T.) and false (.F.)

equal to false (.F.).

■ Memo: Treated the same as character.

NIL: True (.T.) if compared to a NIL value; false (.F.) if

compared to a value of any other data type.

■ Numeric: Compared based on magnitude.

Examples
■  These examples illustrate how the equal operator (=) behaves
   with different data types:

   // Character
   SET EXACT ON
   ? "123" = "123  "        // Result: .T.
   ? " 123" = "123"         // Result: .F.
   SET EXACT OFF
   ? "123" = "12345"        // Result: .F.
   ? "12345" = "123"        // Result: .T.
   ? "123" = ""             // Result: .T.
   ? "" = "123"             // Result: .F.

   // Date
   ? CToD("12/12/88") = ;
      CToD("12/12/88")      // Result: .T.

   // Logical
   ? .T. = .T.              // Result: .T.
   ? .F. = .T.              // Result: .F.

   // NIL
   ? NIL = NIL              // Result: .T.
   ? NIL = 12               // Result: .F.
   ? NIL = CToD("")         // Result: .F.

   // Numeric
   ? 2 = 1                  // Result: .F.
   ? 1 = 1                  // Result: .T.
Platforms
Available on MS-DOS
See also
<, <=, <> != #, ==, >, >=, $

== | 

Exactly equal—binary (Relational)
Syntax
<exp1> == <exp2>
Description

The exactly equal operator (==) is a binary operator that compares two values of the same data type for exact equality depending on the data type. It returns true (.T.) if exp1 is equal to exp2 according to the following rules:

■ Array: Compares for identity. If exp1 and exp2 are

variable references to the same array, returns true (.T.); otherwise, returns false (.F.).

■ Character: Comparison is based on the underlying ASCII code.

ASCII codes for alphabetic characters are ascending (e.g., the code for "A" is 65 and the code for "Z" is 90). Unlike the relational equality operator (=) , true (.T.) is returned if exp1 and exp2 are exactly equal including trailing spaces; otherwise, the comparison returns false (.F.). SET EXACT has no effect.

■ Date: Dates are compared according to the underlying date

value; behaves the same as the relational equality operator (=).

■ Logical: True (.T.) is exactly equal to true (.T.), and false

(.F.) is exactly equal to false (.F.).

■ Memo: Treated the same as character.

NIL: True (.T.) if compared to a NIL value; false (.F.) if

compared to a value of any other data type.

■ Numeric: Compared based on magnitude; behaves the same as the

relational equality operator (=).

■ Object: Treated the same as array.

Examples
■  These examples illustrate how the == operator behaves with
   different data types:

   // Character
   ? "A" == "A"             // Result: .T.
   ? "Z" == "A"             // Result: .F.
   ? "A" == "A "            // Result: .F.
   ? "AA" == "A"            // Result: .F.

   // Array or object

   aOne := { 1, 2, 3 }
   aTwo := { 1, 2, 3 }
   aThree := aOne
   ? aOne == aTwo           // Result: .F.
   // values within the arrays are equal, but the arrays,
   // themselves, are separate and distinct
   ? aOne == aThree         // Result: .T.
Platforms
Available on MS-DOS
See also

> | 

Greater than—binary (Relational)
Syntax
<exp1> > <exp2>
Description

The greater than (>) operator compares two values of the same data type and returns true (.T.) if exp1 is greater than exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for "A" is 65 and the code for "Z" is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: True (.T.) is greater than false (.F.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples
■  These examples illustrate how the greater than operator (>)
   behaves with different data types:

   // Character
   ? "Z" > "A"             // Result: .T.
   ? "AZ" > "A"            // Result: .F.
   ? "A" > "AZ"            // Result: .F.

   // Date

   ? CToD("12/12/88") > ;
      CToD("12/11/88")     // Result: .T.

   // Logical
   ? .T. > .F.             // Result: .T.

   // Numeric
   ? 2 > 1                 // Result: .T.
   ? 1 > 2                 // Result: .F.
Platforms
Available on MS-DOS
See also

>= | 

Greater than or equal—binary (Relational)
Syntax
<exp1> >= <exp2>
Description

The greater than or equal to operator (>=) is a binary operator that compares two values of the same data type and returns true (.T.) if exp1 is greater than or equal to exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for "A" is 65 and the code for "Z" is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: True (.T.) is greater than false (.F.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples
■  These examples illustrate how the greater than or equal
   operator (>=) behaves with different data types:

   // Character
   ? "Z" >= "A"             // Result: .T.

   ? "AZ" >= "A"            // Result: .T.
   ? "A" >= "AZ"            // Result: .F.

   // Date
   ? CToD("12/12/88") >= ;
      CToD("12/11/88")      // Result: .T.

   // Logical
   ? .T. >= .F.             // Result: .T.

   // Numeric
   ? 2 >= 1                 // Result: .T.
   ? 1 >= 2                 // Result: .F.
   ? 2 >= 2                 // Result: .T.
Platforms
Available on MS-DOS
See also

- | 

Subtraction, unary negative, concatenation (Math, Character)
Syntax
<nNumber1> - <nNumber2>             (subtraction)
<dDate1>   - <dDate2>               (subtraction)
<dDate>    - <nNumber>              (subtraction)
<cString1> - <cString2>             (concatenation)
Description

The (-) operator performs different operations depending on the data types of the operands:

■ Unary negative sign (numeric): A numeric expression prefaced

with the minus (-) operator performs the equivalent of multiplying the operand by (-1), returning a negative numeric value.

■ Binary subtraction (numeric, date): If both operands are

numeric data type, nNumber2 is subtracted from nNumber1 and the result is returned as a numeric value. If both operands are date data type, dDate2 is subtracted from dDate1 and the result is returned as a numeric value representing the number of days between the two dates. If the left operand is date data type and the right operand numeric data type, the nNumber is subtracted as days from dDate and a date value is returned. If the order of operands is reversed, a runtime error occurs.

■ Concatenation (character, memo): If both operands are

character data type, cString2 is joined to cString1, returning a character string. Trailing blanks are trimmed from cString1 and joined to the end of the return string.

Examples
■  These examples illustrate the various forms of the - operator:

   // Binary subtraction (numeric)
   ? 1 - 1                           // Result: 0
   ? 1 - 0                           // Result: 1
   ? 0 - 1                           // Result: -1

   // Binary subtraction (date)

   ? CToD("12/12/88") - 12         // Result: 11/30/88
   ? 12 - CToD("12/12/88")         // Result: Runtime error

   // Concatenation (character)
   ? "Hi " - "There" + "*"         // Result: Hithere *
Platforms
Available on MS-DOS
See also

-> | 

Alias assignment—binary (Special)
Syntax
<idAlias>-><idField>
<idAlias>->(<exp>)
(<nWorkArea>)-><idField>
(<nWorkArea>)->(<exp>)
FIELD-><idVar>
MEMVAR-><idVar>
Description

When used with an idAlias as the first operand, the alias operator

(->) accesses field information or evaluates an expression in the indicated work area. The alias operator implicitly SELECTs the idAlias before evaluating the idField or exp operand. When the evaluation is complete, the original work area is SELECTed again. An alias reference can be in an expression or on a line by itself:

? Customer->Name Customer->(UpdateTransaction())

Using the alias operator lets you:

■ Access information from unselected work areas within

expressions

■ Access environmental information from unselected work areas

■ Access information from unselected work areas in modes such as

REPORT and LABEL FORMs

■ Write more compact code

In addition to allowing expression and field evaluation in unselected work areas, the alias operator makes an explicit reference to a field or variable using either the FIELD or the MEMVAR keyword aliases. MEMVAR forces idVar to refer to a memory variable name, and FIELD forces it to reference a database field. These special alias identifiers allow you to avoid ambiguity when there are conflicts between field and memory variable names. Remember that a reference to a variable identifier not prefaced with an alias defaults to a field if there are both field and memory variables with the same name. To override this, use the (/V) option when compiling.

In addition to specifying the alias as an identifier, you can access the target work area using an expression that returns the work area number if the expression is enclosed by parentheses. This lets you use work area numbers as handles, which is useful for passing references to work areas without using macros, aliases, names, etc.

Examples
■  This example accesses database and work area information in an
   unselected work area:

   USE Customer NEW
   USE Invoices NEW
   ? Customer->CustName                  // Result: Bill Smith
   ? Customer->(RecNo())                 // Result: 1
   ? Customer->(Found())                 // Result: .F.
   ? Customer->(City + ", " + State + ;
      "  " + Zip)                        // Result: ShadowVille,
                                         //         CA  90415

■  This example uses a user-defined function (MySeek()) as an
   operand of the alias operator for a common operation that normally
   requires many more statements:

   IF Invoices->(MySeek(CustNum))
      <process customer>...
   ELSE
      <process no find>...
   ENDIF
   RETURN

   FUNCTION MySeek( cSearch )
      SEEK cSearch
   RETURN (Found())

   Note:  This example is just an illustration of the alias operator
   with a user-defined function.  CA-Clipper's dbSeek() could be used
   instead of MySeek().

■  This example explicitly references field and memory variables
   with the same name:

   USE Customer NEW
   MEMVAR->CustName = "Bill Smith"      // Create a memvar
                                        // CustName
   LOCATE FOR MEMVAR->CustName = FIELD->CustName

■  This example uses an expression as a work area handle to
   create a work area-independent database operation:

   cTable1 := "C:Myfile.dbf"
   cTable2 := "D:Myfile.dbf"
   USE (cTable1) NEW
   hArea1 = Select()
   USE (cTable2) NEW
   hArea2 = Select()
   DoStuff( hArea1, hArea2 )

   FUNCTION DoStuff( hArea1, hArea2 )
      LOCAL nCount, nSave
      nSave := Select()
      SELECT (hArea1)
      FOR nCount := 1 TO FCount()
         FieldPut( nCount, ( hArea2 )-> ;
            ( FieldGet( nCount )))
      NEXT
      SELECT (nSave)
      RETURN NIL
Platforms
Available on MS-DOS
See also

-- | 

Decrement—unary (Mathematical)
Syntax
--<idVar>       (prefix decrement)
<idVar>--       (postfix decrement)
Description

The decrement operator (—) decreases the value of its operand by one. This operator subtracts one from the value of idVar and assigns the new value to idVar.

The — operator can appear before or after idVar. Specifying the operator before idVar decrements and assigns the value before the value is used. This is called prefix notation, and it is the most common usage. Specifying the operator after idVar decrements and assigns the value after it is used. This is postfix notation. Stated differently, postfix notation delays the assignment portion of the operation until the rest of the expression is evaluated, and prefix notation gives the assignment precedence over all other operations in the expression.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. You can assign field variables by declaring the field variable name in a FIELD statement or by referring to the field name prefaced by the FIELD-> alias or by the name of the work area.

Examples
■  In this example of the postfix decrement operator the
   assignment takes place before the original variable is decremented,
   thus the two values are not the same when queried:

   nValue := 1
   nNewValue := nValue--
   ? nNewValue                  // Result:   1
   ? nValue                     // Result:   0

■  In this example, the prefix decrement operator decreases the
   first operand of the multiplication by one, making its value 9.
   Then, the assignment of this new value to the nValue variable takes
   place before the rest of the expression is evaluated.  Thus, the new
   value is used to perform the multiplication operation, and the result
   of 9 * 9 is 81.

   nValue := 10
   ? --nValue * nValue          // Result:  81
   ? nValue                     // Result:   9
Platforms
Available on MS-DOS
See also

: | 

Send—binary (Object)
Syntax
<object>:<message>[(<argument list>)]
Description

Each class defines a set of operations that can be performed on objects of that class. Perform these operations by sending a message to the object using the send operator (:).

When a message is sent to an object, the system examines the message. If the object is of a class that defines an operation for that message, the system automatically invokes a method to perform the operation on the specified object. If the class does not define a method for the specified message, a runtime error occurs.

Executing a message send produces a return value, much like a function call. The return value varies depending on the operation performed.

Examples
■  In this example, myBrowse is the name of a variable that
   contains a TBrowse object reference.  pageUp() is a method that
   specifies the operation to be performed.  The available operations
   and corresponding methods vary depending on the class of the object.
   The Error, Get, TBColumn, and TBrowse classes are documented in this
   chapter.

   myBrowse:pageUp()

■  This example forces the checkbox state to true (.T.):

   myCheck : Select (.T.)
Platforms
Available on MS-DOS

:= | 

Inline assign—binary (Assignment)
Syntax
<idVar> := <exp>
Description

The inline assignment operator (:=) assigns values of any data type to variables of any storage class. The operator evaluates exp, assigns the resulting value to idVar, and returns the resulting value as the return value of the operation. This latter behavior permits multiple assignments such as idVar1 := idVar2 := value. Unlike the simple assign operator (=), the inline assignment operator (:=) can be used anywhere an expression or constant is allowed, including variable declaration statements. With a variable declaration statement, assignment initializes a variable. Note, however, you cannot declare an array and initialize elements within the same program statement.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. At runtime, if no private or public variable exists with the specified name, a private variable is created. You can assign field variables with the := operator by declaring the field variable name in a FIELD statement or referring to the field name prefaced by the FIELD-> alias or the name of the work area.

Examples
■  Several examples of inline assignment follow:

   LOCAL nValue := 10
   //
   IF (dDate := (Date() - 1000)) = CToD("12/20/79")
   //
   ? Sqrt(nValue := (nValue ** 2))
   //
   cTransNo := cSortNo := (CustId + DToC(Date()))

■  This last example performs multiple assignments using the
   inline assignment operator as you would with the STORE command.  When
   := is used in this way, the assignments are executed from right to
   left.  This feature is particularly useful when you need to store the
   same value to many different fields, possibly in different database
   files.

   CustFile->CustId := TransFile-> ;
      TransNo := (CustId + DToC(Date())
Platforms
Available on MS-DOS
See also

?|?? | 

Display one or more values to the console
Syntax
? | ?? [<exp list>]
Arguments
exp list is a list of values to display and can be any combination of data types, including memo.
If you specify no argument and use the ? command, a carriage return/linefeed is sent to the console. If you use the ?? command without arguments, nothing happens.
Description

? and ?? are console commands that display the results of one or more expressions, separated by a space, to the console. These commands are also command synonyms for the QOut() and QQOut() functions, respectively.

Although functionally similar, ? and ?? differ slightly. ? sends a carriage return/linefeed to the console before displaying the results of the expression list. ?? displays output at the current screen cursor or printhead position. This lets you use successive ?? commands to display output to the same line.

A ? or ?? command locates the cursor or printhead one position to the right of the last character displayed. If SET PRINTER is OFF, Row() and Col() are updated to reflect the new cursor position. If SET PRINTER is ON, PRow() and PCol() are updated with the new printhead position.

If output from a ? or ?? command reaches the edge of the screen as reported by MaxCol(), it wraps to the next line. If the output reaches the bottom of the screen as reported by MaxRow(), the screen scrolls up one line.

You can echo output from the ? or ?? commands to the printer by specifying a SET PRINTER ON command before beginning output. You can echo output from both of these commands to a text file using SET ALTERNATE TO xcFile to create the file, and SET ALTERNATE ON to begin echoing to the file. Like other console commands, SET CONSOLE OFF suppresses the display to the screen without affecting output to the printer or text file.

To format any expression specified, use Transform() or a user-defined function. If you need to pad a variable length value for column alignment, use any of the Pad() functions to left-justify, right- justify, or center the value. See the examples below.

Examples
■  This example prints a record from a database file using ? and
   ?? commands with PadR() to ensure column alignment:

   LOCAL nPage := 0, nLine := 99
   USE Salesman INDEX Salesman NEW
   SET PRINTER ON
   SET CONSOLE OFF
   DO WHILE !Eof()
      IF nLine > 55
         IF nPage != 0
            EJECT
         ENDIF
         ? PadR("Page", LTrim(Str(nPage++)), 72)
         ?? DToC(Date())
         ?
         ?
         ? PadC("Sales Listing", 79)
         ?
         nLine := 5
      ENDIF
      ? Name, Address, PadR(RTrim(City) + "," ;
            + State, 20), ZipCode
      nLine++
      SKIP
   ENDDO
   SET CONSOLE ON
   SET PRINTER OFF
   CLOSE Salesman
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

/ | 

Division—binary (Mathematical)
Syntax
<nNumber1> / <nNumber2>
Description

The division operator (/) returns a numeric value from the division of nNumber1 by nNumber2.

Note: Dividing nNumber1 with zero value for nNumber2 results in a runtime error.

Examples
■  This example shows division results to 16 decimal places,
   using different operands:

   SET DECIMALS TO 16
   ?  3 /  0            // Result: Runtime error
   ?  3 / -2            // Result: -1.500000000
   ? -3 /  2            // Result: -1.500000000
   ? -3 /  0            // Result: Runtime error
   ? -1 / -3            // Result: +0.333333333
   ? -2 /  3            // Result: -0.666666667
   ?  2 / -3            // Result: -0.666666667
   ?  1 / -3            // Result: -0.333333333
Platforms
Available on MS-DOS
See also

.AND. | 

Logical AND—binary (Logical)
Syntax
<lCondition1> .AND. <lCondition2>
Description

The .AND. operator is a binary logical operator that executes a logical AND operation using the following modified Boolean rules:

■ Returns true (.T.) if both lCondition1 and lCondition2

evaluate to true (.T.)

■ Returns false (.F.) if either lCondition1 and lCondition2

evaluate to false (.F.)

Warning! In a departure from Summer '87 and other dialect behavior, CA-Clipper shortcuts the evaluation of .AND. operands. This means that lCondition1 and lCondition2 are both evaluated only when lCondition1 evaluates to TRUE (.T.). If lCondition1 evaluates to FALSE (.F.), the .AND. operation is FALSE (.F.) and lCondition2 is therefore not evaluated.

For backward compatibility, shortcutting can be suppressed by compiling with the /Z option.

Examples
■  This example shows .AND. results using different operands:

   ? .T. .AND. .T.            // Result: .T.
   ? .T. .AND. .F.            // Result: .F.
   ? .F. .AND. .T.            // Result: .F.   (shortcut)
   ? .F. .AND. .F.            // Result: .F.   (shortcut)
Platforms
Available on MS-DOS
See also

.NOT. | 

Logical NOT—unary (Logical)
Syntax
! <lCondition>
.NOT. <lCondition>
Description
The not (!) operator is a unary logical operator that returns the logical inverse of lCondition.
Examples
■  This example shows .NOT. results using different operands:

   ? ! (.T.)               // Result: .F.
   ? ! 1 > 2               // Result: .T.
   ? .NOT. 1 > 2           // Result: .T.
Platforms
Available on MS-DOS
See also

.OR. | 

Logical OR—binary (Logical)
Syntax
<lCondition1> .OR. <lCondition2>
Description

The .OR. operator is a binary logical operator that executes a logical OR operation using the following modified Boolean rules:

■ Returns true (.T.) if either lCondition1 or lCondition2

evaluates to true (.T.)

■ Returns false (.F.) if both lCondition1 and lCondition2

evaluates to false (.F.)

Warning! In a departure from the Summer '87 and other dialect behavior, CA-Clipper shortcuts the evaluation of .OR. operands. This means that lCondition1 and lCondition2 are both evaluated only when lCondition1 evaluates to false (.F.). If lCondition1 evaluates to true (.T.), the .OR. operation is true (.T.) and lCondition2 is, therefore, not evaluated. For backward compatibility, shortcutting can be suppressed by compiling with the /Z option.

Examples
■  This example shows .OR. results using different operands:

   ? .T. .OR. .T.            // Result: .T.   (shortcut)
   ? .T. .OR. .F.            // Result: .T.   (shortcut)
   ? .F. .OR. .T.            // Result: .T.
   ? .F. .OR. .F.            // Result: .F.
Platforms
Available on MS-DOS
See also

( ) | 

Function or grouping indicator (Special)
Description

Parentheses (()) in expressions are used to group certain operations for readability or to force a particular evaluation order. Parentheses also identify a function call.

When specifying the grouping operator, the item that falls within the parentheses must be a valid expression. Subexpressions may be further grouped.

For function calls, a valid function name must precede the left parenthesis, and the function arguments, if any, must be contained within the parentheses.

Examples
■  This example changes the default order of expression
   evaluation:

   ? 5 * (10 + 6) / 2         // Result: 40

■  The next example shows a function call:

   x := Sqrt(100)
Platforms
Available on MS-DOS
See also

[ ] | 

Array element indicator (Special)
Syntax
<aArray>[<nSubscript>, ... ]
<aArray>[<nSubscript1>][<nSubscript2>] ...
Description
The subscript operator ([]) specifies a single array element. The name of a previously declared array must precede the left bracket and the array element subscript must appear as a numeric expression within the brackets. You can make array element references using Pascal or C-style syntax.
Examples
■  This example accesses each element in a two-dimensional array
   of known dimensions:

   LOCAL i, j
   FOR i := 1 TO 5
      FOR j := 1 TO 10
         ? aOne[i, j]
      NEXT
   NEXT

■  These examples specify an <aArray> expression:

   LOCAL aArray := { 1, 2, 3, 4, 5 }
   //
   ? ArrayFunc()[2]                     // Result: 2
   ? { {1, 2}, {3, 4} }[1][2]           // Result: 2
   ? aArray[5]                          // Result: 5

   FUNCTION ArrayFunc
      STATIC aArray := { 1, 2 }
      RETURN aArray

■  This example queries and assigns a static array encapsulated
   within a function definition:

   ? ArrayFunc()[1]                     // Result: 1
   ArrayFunc()[1] := 10
   ? ArrayFunc()[1]                     // Result: 10

   FUNCTION ArrayFunc
      STATIC aArray := { 1, 2 }
      RETURN aArray
Platforms
Available on MS-DOS
See also

{ } | 

Literal array and code block delimiters (Special)
Syntax
{ <exp list> }                 (literal array)
{ |<param list>| <exp list> }  (code block definition)
Description
Curly braces ({}) delimit references to literal arrays or code blocks. If the reference is a literal array, you can use them to create an array in either an assignment or a variable declaration statement. If the reference is a variable declaration, the array can contain expressions of any kind as elements, unless STATIC is the declaration statement. In this case, the literal array can only contain constant values.
Examples
■  This example uses literal arrays in declaration statements to
   create a variable and initialize it with an array reference:

   LOCAL aPerson := { "Name", "Address", Date() }
   STATIC aNumList := { 1, 2, 3, 4, 5, 6, 7, 8 }

■  This example creates a multidimensional literal array:

   aMulti := { {1, 2, 3}, {"A", "B", "C"} }

■  This example uses curly braces to formulate a simple code
   block with a single parameter:

   LOCAL bSayBlock
   bSayBlock := { |x| QOut(x) }
   Eval(bSayBlock, 10)               // Result: 10
Platforms
Available on MS-DOS
See also

@ | 

Pass-by-reference—unary (Special)
Syntax
@<idVar>
Description

The pass-by-reference operator (@) passes variables by reference to functions or procedures invoked with function-calling syntax. It is a unary prefix operator whose operand may be any variable name.

Passing a variable by reference means that a reference to the value of the argument is passed instead of a copy of the value. The receiving parameter then refers to the same location in memory as the argument. If the called routine changes the value of the receiving parameter, it also changes the argument passed from the calling routine.

Passing a variable by value means that the argument is evaluated and its value is copied to the receiving parameter. Changes to a receiving parameter are local to the called routine and lost when the routine terminates. The default method of passing arguments is by value for all data types including references to arrays and objects.

Examples
■  This example demonstrates the difference between passing a
   user-defined function argument by reference and by value:

   LOCAL nNum := 1                     // Initial values

   LOCAL aArr := { "a", "b", "c" }
   //
   CLS
   // Print initial values
   ? ValType(nNum), nNum
   ? ValType(aArr), aArr[1], aArr[2], aArr[3]
   //
   Udf1(nNum)                          // Pass by value (default)
   ? ValType(nNum), nNum               // Result:  N, 1
   //
   Udf1(aArr[1])                       // Pass by value (default)
   ? ValType(aArr), aArr[1],;
         aArr[2], aArr[3]              // Result:  A, "a" "b" "c"
   //
   Udf2(aArr)                          // Pass a reference to
   ? ValType(aArr), aArr[1],;          // the array (default)
         aArr[2], aArr[3]              // A, "Oi!" "b" "c"
   //
   Udf1(@nNum)                         // Force pass by reference
   ? ValType(nNum), nNum               // Result:  N, 1000
   //
   Udf3(@aArr)                         // Pass array by reference
   ? ValType(aArr)                     // Result:  N
   //
   RETURN NIL


   FUNCTION Udf1(nParam)               // Receive as a local
   ? nParam                            // parameter
   nParam := 1000
   ? nParam
   RETURN NIL
   //
   FUNCTION Udf2( aParam )             // Receive as a local
   ? ValType(aParam), aParam[1]        // parameter
   aParam[1] := "Oi!"
   ? aParam[1]
   RETURN NIL
   //
   FUNCTION Udf3(aParam)               // Receive as a local
   ? ValType(aParam), aParam[1]        // parameter
   aParam := 1000
   ? aParam
   RETURN NIL
Platforms
Available on MS-DOS
See also

@...BOXHarbour implementation | 

Draw a box on the screen
Syntax
@ <nTop>, <nLeft>, <nBottom>, <nRight>
   BOX <cBoxString> [COLOR <cColorString>]
Arguments
nTop, nLeft, nBottom, nRight define the coordinates of the box. @...BOX draws a box using row values from zero to MaxRow(), and column values from zero to MaxCol(). If nBottom and nRight are larger than MaxRow() and MaxCol(), the bottom-right corner is drawn off the screen.
BOX cBoxString defines a string of eight border characters and a fill character. If cBoxString is specified as a single character, that character draws the whole box.
COLOR cColorString defines the display color of the drawn box. If not specified, the box is drawn using the standard color setting of the current system color as defined by SetColor(). Note that cColorString is a character expression containing the standard color setting. If you want to specify a literal color setting, enclose it within quote marks.
Description

@...BOX draws a box on the screen using configurable border and fill characters. @...BOX draws the box using cBoxString starting from the upper left-hand corner, proceeding clockwise and filling the screen region with the ninth character. If the ninth character is not specified, the screen region within the box is not painted. Existing text and color remain unchanged.

After @...BOX executes, the cursor is located in the upper corner of the boxed region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.

Examples
■  These examples draw two boxes using box manifest constants
   defined in the supplied header file, box.ch.  The first example draws
   a box using the specified characters for the border, but leaves all
   other areas of the screen intact.  The second example draws the same
   box filling the box region with space characters.

   #include "Box.ch"
   // Draw a box with a double-line top with a
   // single-line side
   @ 1, 1, 22, 79 BOX B_DOUBLE_SINGLE
   // Draw the same box filling the box region with
   // spaces
   @ 1, 1, 22, 79 BOX B_DOUBLE_SINGLE + Space(1)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is box.ch.
See also

@...CLEARHarbour implementation | 

Clear a rectangular region of the screen
Syntax
@ <nTop>, <nLeft> [CLEAR
   [TO <nBottom>, <nRight>]]
   [DOUBLE] [COLOR <cColor>]
Arguments
nTop and nLeft define the upper-left corner coordinate.
TO nBottom, nRight defines the lower-right corner coordinates of the screen region to CLEAR. If the TO clause is not specified, these coordinates default to MaxRow() and MaxCol().
Description
@...CLEAR erases a rectangular region of the screen by filling the specified region with space characters using the current standard color setting. After @...CLEAR erases the designated region, the cursor is located in the upper corner of the region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.
Examples
■  This example erases the screen from 10, 10 to 20, 40, painting
   the region blue and then displaying a bright cyan box on blue:

   SetColor("BG+/B")
   @ 10, 10 CLEAR TO 20, 40
   @ 10, 10 TO 20, 40
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

@...GETHarbour implementation | 

Create a new Get object and display it to the screen
Syntax
@ <nRow>, <nCol>
   [SAY <exp>
      [PICTURE <cSayPicture>]
      [COLOR <cColorString>]]
   GET <idVar>
      [PICTURE <cGetPicture>]
      [COLOR <cColorString>]
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [RANGE* <dnLower>, <dnUpper>] |
      [VALID <lPostExpression>]
      [SEND <msg>]
      [GUISEND <guimsg>]
Arguments
nRow and nCol specify the row and column coordinates for the operation. If the SAY clause is present, nRow and nCol specify the coordinates for the SAY, and the GET is displayed to the right of the SAY output. If the SAY clause is not present, nRow and nCol directly specify the coordinates for the GET. In either case, output which extends beyond the visible extent of the display is clipped and does not appear.
SAY exp displays the value of exp at the specified coordinates. If you specify the PICTURE cSayPicture clause, exp is formatted according to the rules of SAY pictures.
GET idVar specifies the name of the variable associated with the GET. idVar may be of any storage class (if the storage class is ambiguous, FIELD is assumed). If idVar contains an array value, you must supply one or more subscripts. The current value of idVar is displayed at the GET coordinates. The value must be character, date, numeric, or logical type. Array, NIL, code block, and null string values are not permitted.
PICTURE cGetPicture specifies the display format and editing rules for the GET.
COLOR cColorString defines the color settings for the current Get object. cColorString is a character expression containing one or more color settings. You must specify literal color settings enclosed in quote marks.
If you specify two color settings, the first determines the unselected color (the display color for the Get object) and the second determines the selected color (the color when the Get object has focus). If you only specify one color, it determines both the unselected and selected colors for the Get object.
On a combined @...SAY...GET command, two COLOR clauses are required to specify colors for both the SAY and the GET: one for the SAY, and one for the GET.
CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse's left button is clicked and its cursor is on the caption. By default, the caption appears to the right of the GET. Use the Get object's capRow or capCol variable to change the screen position of the caption. Note that if the SAY clause is used, the CAPTION clause is ignored.
When present, the & character specifies that the character immediately following it in the caption is the GET's accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the GET. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.
MESSAGE cMessage specifies a character string that is displayed on the Get system's status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the SET MESSAGE command for details pertaining to the Get system's status bar.
WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
RANGE* dnLower, dnUpper specifies a range of allowable values for input to the GET. During a READ command, if you enter a new GET value that does not fall within the specified range, the cursor cannot leave the GET.
VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.
GUISEND guimsg can be used to send a message (such as the Display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.
Description

The @...GET command creates a new Get object, displays its value, and adds it to the array referred to by the variable GetList. If no variable called GetList has been declared or created in the current procedure, and no PRIVATE variable called GetList exists from a previous procedure, the system uses the predefined PUBLIC variable GetList. A subsequent READ command activates the GETs contained in the GetList array and allows the user to edit their contents.

Each Get object has an associated variable, idVar. The variable may be of any storage class, including a database field, private, public, local, or static variable. If idVar is followed by one or more subscripts, the specified array element is associated with the GET. When the Get object is created, the idVar name is stored in the Get object, along with a code block which allows the value of idVar to be retrieved or assigned during the READ.

The READ command performs a full-screen edit of the GETs in the GetList array. As the user moves the cursor into each GET, the value of the associated idVar is retrieved by evaluating the code block saved in the Get object. The value is converted to textual form and placed in a buffer within the Get object. This buffer is displayed on the screen, and the user is allowed to edit the text from the keyboard. When the user moves the cursor out of the GET, the updated buffer is converted back to the appropriate data type and assigned to idVar.

Automatic formatting and validation: During a READ, some formatting and edit validation is automatically performed for numeric, date, and logical values. As the user is typing, an automatic data type test is performed on each key pressed, preventing the user from entering an invalid character.

Prevalidation: The WHEN clause specifies a condition which must be satisfied before the cursor can enter the GET. During a READ, lPreExpression is evaluated whenever the user attempts to move the cursor into the GET. If it evaluates to true (.T.), the cursor can enter; otherwise, the GET is skipped.

Postvalidation: You may perform postvalidation using either the VALID or RANGE* clauses. VALID specifies a condition which must be satisfied before the cursor can leave the GET. During a READ, lPostExpression is evaluated whenever the user attempts to move the cursor out of the GET. If it evaluates to true (.T.), the cursor can leave; otherwise, the cursor remains in the GET. RANGE* specifies a range of acceptable values for numeric or date values. If the value entered by the user is not within the specified range, the cursor cannot leave the GET.

Note: You may specify either a VALID or RANGE clause, but not both.

PICTURE: When you specify the PICTURE clause for a GET, the character string specified by cGetPicture controls formatting and edit validation. The picture string controls the display format like a SAY picture. It also controls the way the user can edit the buffer. A picture string consists of two distinct parts, a function string and a template string, either or both of which may be present.

■ Function string: A PICTURE function string specifies

formatting or validation rules which apply to the GET's display value as a whole, rather than to particular character positions within it. The function string consists of the @ character, followed by one or more additional characters, each of which has a particular meaning (see the following table). The function string must be the first element of a PICTURE clause and cannot contain spaces. A function string may be specified alone or with a template string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

GET PICTURE Format Functions

       Function     Type Action
       A            C    Allows only alphabetic characters.
       B            N    Displays numbers left-justified.
       C            N    Displays CR after positive numbers.
       D            D,N  Displays dates in SET DATE format.
       E            D,N  Displays dates with day and month inverted
                         independent of the current DATE SETting, numerics
                         with comma and period reverse (European style).
       K            ALL  Deletes default text if first key is not a cursor
                         key.
       R            C    Nontemplate characters are inserted in the display
                         but not saved in the variable.
       S<n>         C    Allows horizontal scrolling within a GET.  <n> is
                         an integer that specifies the width of the region.
       X            N    Displays DB after negative numbers.
       Z            N    Displays zero as blanks.
       (            N    Displays negative numbers in parentheses with
                         leading spaces.
       )            N    Displays negative numbers in parentheses without
                         leading spaces.
       !            C    Converts alphabetic character to uppercase.

■ Template string: A PICTURE template string specifies

formatting or validation rules on a character by character basis. The template string consists of a series of characters, some of which have special meanings (see the following table). Each position in the template string corresponds to a position in the displayed GET value. Characters in the template string that do not have assigned meanings are copied verbatim into the displayed GET value. If you use the @R picture function, these characters are inserted between characters of the display value, and are automatically removed when the display value is reassigned to idVar; otherwise, they overwrite the corresponding characters of the display value and also affect the value assigned to idVar. You may specify a template string alone or with a function string. If you use both, the function string must precede the template string, and the two must be separated by a single space.

GET PICTURE Template Symbols

       Template     Action
       A            Allows only alphabetic characters
       N            Allows only alphabetic and numeric characters
       X            Allows any character
       9            Allows digits for any data type including sign for
                    numerics
       #            Allows digits, signs and spaces for any data type
       L            Allows only T, F, Y or N
       Y            Allows only Y or N
       !            Converts an alphabetic character to uppercase
       $            Displays a dollar sign in place of a leading space in a
                    numeric
       *            Displays an asterisk in place of a leading space in a
                    numeric
       .            Displays a decimal point
       ,            Displays a comma

SCOREBOARD: If a new value is rejected because it fails the RANGE* test or because it is a malformed date value, a message appears on the screen. The message displays in the SCOREBOARD area, which you can enable or disable using the SET SCOREBOARD command.

Exit with Esc: If the user exits a GET by pressing Esc, the GET variable is restored to the value it had on entry to the GET, and the READ is terminated. No postvalidation is performed. You can enable or suppress this behavior with the SET ESCAPE command.

SET KEY procedures: The SET KEY command lets you specify a procedure to be executed whenever a specific key is pressed during a READ. After a SET KEY procedure terminates, the GET is reactivated with the cursor restored to its previous position.

Lifetime of a Get object: Get objects, like arrays, exist as long as there are active references to them somewhere in the current program. Normally, only the array in the GetList variable maintains a reference to the Get object; the GET is released when GetList is released or reassigned. The CLEAR and CLEAR GETS commands assign an empty array to GetList, as does the READ command unless you specify the SAVE clause.

Assignment: Each GET is associated with a variable, idVar, in the @...GET command. At various times during the editing process, idVar may be assigned the current value of the Get object's buffer. This occurs in the following instances:

■ After the user presses an exit key and before the validation

expression is executed

■ After the user presses a SET KEY

Also, the current Get object's buffer is refreshed from idVar and redisplayed at various intervals:

■ After a SET KEY procedure terminates

■ After a WHEN expression is evaluated

■ After a VALID expression is evaluated

This lets you explicitly assign idVar within any of these operations. See the note below for more information.

GET coordinates and display: When you create a Get object using the @...GET command, the row and column coordinates at which the GET is initially displayed are stored in the Get object. When the @...GET command executes, the new GET displays at nRow and nCol, unless you specify the SAY clause which positions the GET so there is one display column between the last character of the SAY output and the first character of the GET (or of the DELIMITERS, see below).

If SET DELIMITERS is ON when the @...GET command executes, the current DELIMITER characters display on either side of the initial GET display, and the column coordinate of the GET is adjusted accordingly. Note that the delimiters are not attributes of the Get object, but simply display as the SAY clause does.

If INTENSITY is ON, GETs initially display in the current unselected color (or the enhanced color, if no unselected color has been specified). During a READ, the active GET displays in the enhanced color, while the remaining GETs display in the unselected color. With INTENSITY OFF, all GETs display in the standard color.

When a GET displays, the width of the displayed value is determined by the length of the value in idVar or, if you specify the PICTURE clause, by the number of positions in cGetPicture. If you specify the @S function as a part of cGetPicture, the @S argument controls the width of the displayed value.

Notes

WHEN and VALID: The expressions specified in the WHEN and

VALID clauses may be of arbitrary complexity and may include calls to user-defined functions. This is useful for attaching automatic actions to the activation or deactivation of a GET.

■ Assigning idVar: Because of the automatic refresh and

display properties of a Get object while it is being READ, you can make an explicit assignment to the Get object's idVar within a WHEN or VALID expression. You can directly assign the variable by name in the validation expression or, for private, public, local, or static variables, by passing a reference to idVar to a function; the function can then assign idVar by assigning the corresponding formal parameter. If idVar is a field, it is globally visible and can be assigned by name in a function called by the validation expression.

When including a GET in a called function, do not include an idVar with the same name as a field idVar. Field references have precedence over public variables so the public idVar will be ignored.

GET specific help: You can use a SET KEY procedure to display

help text associated with a Get object. Within the SET KEY procedure, use the ReadVar() function to determine the idVar associated with the current Get object. Use this information to display the appropriate help text. Remember that when a CA-Clipper- compiled program loads, the F1 KEY is automatically SET TO a procedure or user-defined function named Help.

SET DEVICE TO PRINTER: SET DEVICE TO PRINTER does not direct

display of a Get object under the @...GET command to the printer or file.

Examples
■  This  example uses the VALID clause to validate input into a
   GET:

   LOCAL nNumber := 0
   @ 10, 10 SAY "Enter a number:" ;
      GET nNumber VALID nNumber > 0

■  This example demonstrates passing a code block with the VALID
   clause.  The parameter oGet is the current Get object.  Udf() changes
   the value of the GET:

   LOCAL GetList := {}, cVar := Space(10)
   CLS
   @ 10, 10 GET cVar  VALID { |oGet| Udf1( oGet ) }
   READ
   .
   .
   .
   * Udf( <oGet> ) --> .T.

   FUNCTION Udf1( oGet )

   IF "test" $ oGet:BUFFER          // Compare buffer contents
   oGet:varPut( "new value " )      // Change contents
   ENDIF

   RETURN .T.

■  This example uses the WHEN clause to prohibit entry into GETs
   based on the value of another GET.  In this example, entering Y in the
   Insured field indicates the client has insurance and the user is
   allowed to enter insurance information.  If the client does not have
   insurance, the cursor moves to the Accident field:

   @ 10, 10 GET Insured PICTURE "Y"
   @ 11, 10 GET InsNumber WHEN Insured
   @ 12, 10 GET InsCompany WHEN Insured
   @ 13, 10 GET Accident PICTURE "Y"
   READ

■  This is an example of a GET in a secondary work area:

   USE Invoice NEW
   APPEND BLANK
   USE Inventory NEW
   @ 1, 1 GET Invoice->CustNo
   READ

■  This example uses the @K function to suggest a default input
   value, but deletes it if the first key pressed is not a cursor key or
   Return:

   LOCAL cFile := "Accounts"
   @ 1, 1 SAY "Enter file" GET cFile PICTURE "@K"
   READ

■  This is an example of a nested READ using a GetList and
   lexical scoping:

   #include "inkey.ch"
   //
   // Local to this function only
   LOCAL GetList := {}
   LOCAL cName   := Space( 10 )
   //
   CLS
   SetKey( K_F2, { || MiscInfo() } )   // Hot key to special READ
   //
   // Get object added to getlist
   // works on local getlist
   @ 10, 10 SAY "Name" GET cName
   READ
   //
   RETURN NIL

   /***
   *  MiscInfo() ---> NIL
   */FUNCTION MiscInfo()
   //
   LOCAL GetList    := {}               // Local to this
   LOCAL cExtraInfo := Space( 30 )      // function only
   //
   // Get object added to getlist
   // works on local getlist
   @ 12, 10 SAY "Note: " GET cExtraInfo
   READ
   //
   RETURN NIL
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

@...GET CHECKBOXHarbour implementation | 

Create a new check box Get object and display it to the screen
Syntax
@ <nRow>, <nCol>
   GET <lVar>
   CHECKBOX
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [COLOR <cColorString>]
      [FOCUS <fblock>
      [STATE <bBlock>]
      [STYLE <cStyle>]
      [SEND <msg>]
      [GUISEND <guimsg>]
      [BITMAPS <aBitmaps>]
Arguments
nRow and nCol specify the row and column coordinates for the check box and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.
GET lVar specifies the name of the variable associated with the GET. lVar must contain a logical value. A value of true (.T.) indicates that the check box is checked; otherwise, a value of false (.F.) indicates that it is not checked.
CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse's left button is clicked and its cursor is on the caption. By default, the caption appears to the left of the GET. Use the Get object's capRow or capCol variable to change the screen position of the caption.
When present, the & character specifies that the character immediately following it in the caption is the check box's accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the check box. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.
MESSAGE cMessage specifies a character string that is displayed on the Get system's status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system's status bar.
WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
COLOR cColorString defines the color settings for the check box. cColorString is a character expression containing exactly four color settings.
CheckBox Color Attributes
    Position     Applies To                             Default Value from
    in colorSpec                                        System Color Setting
    1            The check box when it does not have      Unselected
                 input focus
    2            The check box when it has input focus    Enhanced
    3            The check box's caption                  Standard
    4            The check box caption's accelerator key  Background
Note: In graphic mode, colorSpec positions 1 and 2 have no affect and are ignored.
FOCUS fblock specifies a code block that is evaluated each time the check box receives focus. The code block takes no implicit arguments. Use the CheckBox:hasFocus instance variable to determine if the check box has focus.
STATE bBlock specifies a code block that is evaluated each time the check box's state changes. The code block takes no implicit arguments. Use the CheckBox:buffer instance variable to determine if the check box is being checked or unchecked. A value of true (.T.) indicates that it is being checked; otherwise, a value of false (.F.) indicates that it is being unchecked.
STYLE cStyle specifies a character string that indicates the check box's delimiter characters. The string must contain four characters. The first is the left delimiter. Its default value is the left square bracket ([) character. The second is the checked indicator. Its default value is the square root
() character. The third is the unchecked indicator. Its default is
the space character (" "). The fourth character is the right delimiter. Its default value is the right square bracket (]) character.
Note: The style clause is ignored in graphic mode.
SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.
GUISEND guimsg can be used to send a message (such as the Display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.
BITMAPS aBitmaps contains an array of exactly two elements. The first element of this array is the file name of the bitmap to be displayed when the check box is selected. The second element of this array is the file name of the bitmap to be displayed when the check box is not selected.
Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.
CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed.
This argument only affects applications running in graphic mode and is ignored in text mode.
Examples
■  This example demonstrates how to add a check box to a data entry screen:

   @ 5, 20 GET lReadOnly CHECKBOX

■  This example demonstrates a check box that has a caption and a
   message:

   @ 5, 20 GET lReadOnly CHECKBOX ;
           CAPTION "&Read Only" ;
           MESSAGE "Check to open file for reading only"

■  This example demonstrates a check box that uses the X
   character as the checked character instead of the square root
   character.

   @ 5, 20 GET lReadOnly CHECKBOX ;
           CAPTION "&Read Only" ;
           MESSAGE "Check to open file for reading only" ;
           STYLE "[X ]"
Platforms
Available on MS-DOS
File
Libraries are CLIPPER.LIB and LLIBG.LIB.
See also

@...GET LISTBOXHarbour implementation | 

Create a new list box Get object and display it to the screen
Syntax
@ <nTop>, <nLeft>, <nBottom>, <nRight>
   GET <nVar|cVar>
   LISTBOX <aList>
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [COLOR <cColorString>]
      [FOCUS <fblock>]
      [STATE <bBlock>]
      [DROPDOWN]
      [SCROLLBAR]
      [SEND <msg>]
      [GUISEND <guimsg>]
      [BITMAP <cBitmap>]
Arguments
nTop, nLeft, nBottom and nRight specify the screen position for the list box and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.
GET nVar|cVar specifies the name of the variable associated with the GET. Its value indicates which item (if any) in the list is selected. A numeric value refers to the position in the list of the selected item. A value of 0 indicates no selected item. A character string value refers to the data or text contained within the selected item. A character string that does not refer to any item in the list indicates no selected item.
LISTBOX aList specifies an array that contains the items in the list. The array may be either a single- or two-dimensional array. Use a single-dimension array when the data being displayed is the same as the data being saved; otherwise, use a two-dimensional array. In this case, the data in the first element of each subarray is displayed and the data in the second element is used for determining which item is selected.
CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse's left button is clicked and its cursor is on the caption. By default, the caption appears to the left of the GET. Use the Get object's capRow or capCol variable to change the screen position of the caption.
When present, the & character specifies that the character immediately following it in the caption is the list box's accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the list box. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.
MESSAGE cMessage specifies a character string that is displayed on the Get system's status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system's status bar.
WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
COLOR cColorString defines the color settings for the list box. cColorString is a character expression containing exactly seven color settings if there is no drop-down list box, and eight if there is a drop-down list box.
ListBox Color Attributes
    Position     Applies To                             Default Value from
    in colorSpec                                        System Color Setting
    1            List box items that are not selected     Unselected
                 when the list does not have input focus
    2            The selected list box item when the      Unselected
                 List does not have input focus
    3            List box items that are not selected     Unselected
                 when the list has input focus
    4            The selected list box item when the      Enhanced
                 list has input focus
    5            The list box's border                    Border
    6            The list box's caption                   Standard
    7            The list box caption's accelerator key   Background
    8            The list box's drop-down button          Standard
Note: In graphic mode, colorSpec position 8 has no affect and is ignored.
FOCUS fblock specifies a code block that is evaluated each time the list box receives focus. The code block takes no implicit arguments. Use the PushButton:hasFocus instance variable to determine if the push button has focus.
STATE bBlock specifies a code block that is evaluated immediately after the list box object's selection changes. The code block takes no implicit arguments. Use the ListBox:buffer instance variable to determine the current selection.
DROPDOWN indicates that the list box will be a drop-down list box. Drop-down list boxes are displayed differently on the screen than regular list boxes. A regular list box is always displayed regardless of whether it has input focus. A drop-down list box's display behavior is determined by whether it is closed or open. By default, a drop-down list box is closed. In this case, only the caption, the selected item, and the open button are displayed.
When open, the actual list box is displayed in addition to the caption, selected item, and open button.
Drop-down list boxes are useful in situations where screen space is limited.
SCROLLBAR indicates that the list box will be created with a scroll bar whether or not it is needed. Normally a scroll bar is not needed if the data being displayed fits inside the list box.
SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.
GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.
BITMAP cBitmap defines the bitmap that will be used as the down arrow on a drop-down list box. Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.
CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed.
Examples
■  This example demonstrates how to add a list box to a data
   entry screen.  It utilizes the position-oriented method of selection:

   nColor := 1     //default to the first item.
   @ 5, 20, 8, 28 GET nColor LISTBOX { "Red", Green", "Blue" }

■  This example demonstrates a list box that has a caption and a
   message.  It utilizes the data-oriented method of selection:

   cColor := "Red" //default to red.
   @ 5, 20, 8, 28 GET cColor LISTBOX { "Red", Green", "Blue" };
           CAPTION "&Color" ;
           MESSAGE "Select the background color"

■  This example demonstrates a list box that utilizes a two-
   dimensional array.

   cState := "NY"

   @ 5, 20, 10, 30 GET cState LISTBOX { { "Alabama", "AL" }, ;
                                { "Alaska", AK" }   , ;
                                { "Arizona", "AZ" }, ;
                                { etc...          } } ;
           CAPTION "&State" ;
           MESSAGE "Select the client's state"
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

@...GET PUSHBUTTONHarbour implementation | 

Create a new push button Get object and display it to the screen
Syntax
@ <nRow>, <nCol>
   GET <lVar>
   PUSHBUTTON
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [COLOR <cColorString>]
      [FOCUS <fblock>
      [STATE <bBlock>]
      [STYLE <cStyle>]
      [SEND <msg>]
      [GUISEND <guimsg>]
      [SIZE X <nSizeX> Y <nSizeY>]
      [CAPOFF X <nCapXOff> Y <nCapYOff>]
      [BITMAP <cBitmap>]
      [BMPOFF X <nBmpXOff> Y <nBmpYOff>]
Arguments
nRow and nCol specify the row and column coordinates for the push button and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.
GET lVar specifies the name of the variable associated with the GET. lVar may contain a value of any type, but upon return from the READ, will always contain logical false (.F.). The purpose of lVar is to provide a place holder in the GetList for the push button.
CAPTION cCaption specifies a character string that concisely describes the GET on the screen. caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse's left button is clicked and its cursor is on the caption. By default, the caption appears within the push button's border. Use the Get object's capRow or capCol variable to change the screen position of the caption.
When present, the & character specifies that the character immediately following it in the caption is the push button's accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the push button. The case of an accelerator key is ignored.
MESSAGE cMessage specifies a character string that is displayed on the Get system's status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system's status bar.
WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
COLOR cColorString defines the color settings for the push button. cColorString is a character expression containing exactly four color settings.
PushButton Color Attributes
    Position     Applies To                             Default Value from
    in colorSpec                                        System Color Setting
    1            The push button when it does not have    Unselected
                 input focus
    2            The push button when it has input focus  Enhanced
                 and is not pressed
    3            The push button when it has input focus  Standard
                 and is pressed
    4            The push button caption's accelerator    Background
                 key
Note: The background colors of the PushButton Color Attributes are ignored in graphic mode.
FOCUS fblock specifies a code block that is evaluated each time the push button recieves focus. The code block takes no implicit arguments. Use the PushButton:hasFocus instance variable to determine if the push button has focus.
STATE bBlock specifies a code block that is evaluated each time the push button object's state changes. The code block takes no implicit arguments. Use the PushButton:buffer instance variable to determine if the push button is pressed or released. A value of true (.T.) indicates that it is being pressed; otherwise, a value of false (.F.) indicates that it is being released.
STYLE cStyle specifies a character string that indicates the delimiter characters that are used by the push button's display() method. When specified, the string must contain either zero, two, or eight characters. The default is two characters. The first is the left delimiter. Its default value is the less than () character. The second character is the right delimiter. Its default value is the greater than () character.
When the style string is empty, the button has no delimiters. When the string length is two, the button has left and right delimiters and occupies one row on the screen. The first character is the left delimiter. The second character is the right delimiter. When the string length is eight, the button is contained within a box that occupies three rows on the screen.
Standard Box Types
    Constant            Description
    B_SINGLE            Single-line box
    B_DOUBLE            Double-line box
    B_SINGLE_DOUBLE     Single-line top/bottom, double-line sides
    B_DOUBLE_SINGLE     Double-line top/bottom, single-line sides
Box.ch contains manifest constants for the PushButton:style value.
The default style for the @...GET PUSHBUTTON is "<>".
Note: The Style clause is ignored in graphic mode.
SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.
GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.
SIZE X nSizeX Y nSizeY defines the size of the button to be displayed. The coordinates are in pixels. nSizeX represents the number of pixels in the x direction (horizontally) and nSizeY represents the number of pixels in the y direction (vertically). This argument only affects applications running in graphic mode and is ignored in text mode.
CAPOFF X nCapXOff Y nCapYOff defines the offset where the caption is displayed. The coordinates are in pixels. nCapXOff represents the number of pixels in the x direction (horizontally) from the left edge of the button where the caption will be displayed. nCapYOff represents the number of pixels in the y direction (vertically) from the top edge of the button where the caption will be displayed. If the CAPOFF clause is not supplied, the caption will be centered on the button. This argument only affects applications running in graphic mode and is ignored in text mode.
BITMAP cBitmap defines a bitmap file to be displayed on the button. Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.
CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed.
BMPOFF X nBmpXOff Y nBmpYOff defines the offset where the bitmap is displayed. The coordinates are in pixels. nCapXOff represents the number of pixels in the x direction (horizontally) from the left edge where the bitmap will be displayed. nCapYOff represents the number of pixels in the y direction (vertically) from the top edge where the bitmap will be displayed. If the BMPOFF clause is not supplied, the bitmap will be placed at the upper-left corner of the button. This argument only affects applications running in graphic mode and is ignored in text mode.
Examples
■  This example demonstrates how to add a push button to a data
   entry screen:

   @ 5, 20 GET lCancel PUSHBUTTON ;
           CAPTION "&Cancel"
           STATE { || ReadKill( .T. ) }
Platforms
Available on MS-DOS
File
Libraries are CLIPPER.LIB and LLIBG.LIB.
See also

@...GET RADIOGROUPHarbour implementation | 

Create a new radio button group Get object and display it to the screen
Syntax
@ <nTop>, <nLeft>, <nBottom>, <nRight>
   GET <nVar|cVar>
   RADIOGROUP <aGroup>
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [COLOR <cColorString>]
      [FOCUS] <fblock>
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [SEND <msg>]
      [GUISEND <guimsg>]
Arguments
nTop, nLeft, nBottom and nRight specify the screen position for the radio button group and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.
GET nVar|cVar specifies the name of the variable associated with the GET. Its value indicates which radio button (if any) in the group is selected. A numeric value refers to the position in the group of the selected button. A value of 0 indicates no selected button. A character string value refers to the data or text contained within the selected button. A character string that does not refer to any item in the list indicates no selected item.
RADIOGROUP aGroup specifies an array of RadioButto objects.
CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position is maintained within the Get object. This allows the GET to receive input when the mouse's left button is clicked and its cursor is on the caption. By default, the caption appears in the top-left border of the GET. Use the Get object's capRow or capCol variable to change the screen position of the caption.
When present, the & character specifies that the character immediately following it in the caption is the radio group's accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the radio group. The case of an accelerator key is ignored.
MESSAGE cMessage specifies a character string that is displayed on the Get system's status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system's status bar.
COLOR cColorString defines the color settings for the radio button group. cColorString is a character expression containing exactly three color settings.
RadioGroup Color Attributes
    Position     Applies To                             Default Value from
    in colorSpec                                        System Color Setting
    1            The radio group's border                   Border
    2            The radio group's caption                  Standard
    3            The radio group caption's accelerator key  Background
FOCUS fblock specifies a code block that is evaluated each time the radio button group receives focus. The code block takes no implicit arguments. Use the RadioGroup:hasFocus instance variable to determine if the radio group has focus.
WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
Note: There is no STATE clause for the @...GET RADIOGROUP command. Instead each radio button in the group can have its own sBlock instance variable. See sBlock under RadioButto class for more details.
SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.
GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.
Examples
■  This example demonstrates how to add a radio button group to a
   data entry screen.  It utilizes a position-oriented method of
   selection:

   nColor := 1            //default to the first item.
   aGroup := Array( 3 )
   aGroup[ 1 ] := RadioButto( 6, 22, "&Red" )
   aGroup[ 2 ] := RadioButto( 7, 22, "&Green" )
   aGroup[ 3 ] := RadioButto( 8, 22, "&Blue" )
   @ 5, 20, 9, 40 GET nColor RADIOGROUP aGroup

  The nColor variable will return a position, in this case 1, 2, or 3.

■  This example demonstrates a radio button group that utilizes a
   data-oriented method of selection:

   cColor := "R"          //default to red.
   aGroup := Array( 3 )
   aGroup[ 1 ] := RadioButto( 6, 22, "&Red", "R" )
   aGroup[ 2 ] := RadioButto( 7, 22, "&Green", "G" )
   aGroup[ 3 ] := RadioButto( 8, 22, "&Blue", "B" )
   @ 5, 15, 9, 40 GET cColor RADIOGROUP aGroup

  The nColor variable will return data, in this case "R", "G", or "B".
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

@...GET TBROWSEHarbour implementation | 

Create a new TBrowse Get object and display it to the screen
Syntax
@ <nTop>, <nLeft>, <nBottom>, <nRight>
   GET <idVar>
   TBROWSE <oBrowse>
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [SEND <msg>]
      [GUISEND <guimsg>]
Arguments
nTop, nLeft, nBottom and nRight specify the screen position for the TBrowse object. Output which extends beyond the visible extent of the display is clipped and does not appear.
GET idVar specifies the name of the variable associated with the GET. Its value is neither queried nor modified by the Get system. The GET is merely a mechanism used for integrating a TBrowse object into the @...GET/READ system.
TBROWSE oTBrowse specifies a previously defined TBrowse object.
MESSAGE cMessage specifies a character string that is displayed on the Get system's status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system's status bar.
WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.
SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.
GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.
Examples
■  This example demonstrates how to add a TBrowse object to a
   data entry screen:

   oTB := TBrowseDB( 10, 10, 15, 40 )
   oTB:AddColumn(TBColumnNew("Last Name",{||Customer->lName}))
   oTB:AddColumn(TBColumnNew("First Name",{||Customer->fName}))
   oTB:AddColumn(TBColumnNew("Phone",{||Customer->Phone}))
   uDummy := NIL
   @ 10, 10, 15, 40 GET uDummy TBROWSE oTB
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

@...PROMPTHarbour implementation | 

Paint a menu item and define a message
Syntax
@ <nRow>, <nCol> PROMPT <cMenuItem>
   [MESSAGE <cExpression>]
Arguments
nRow and nCol are the row and column coordinates of the menu item display. Row values can range from zero to MaxRow(), and column values can range from zero to MaxCol().
PROMPT cMenuItem is the menu item string to display.
MESSAGE cExpression defines the message to display each time the current menu item is highlighted. A code block evaluating to a character expression may optionally be used.
Description

@...PROMPT is the display portion of the CA-Clipper lightbar menu system. Each @...PROMPT command paints a menu item in the current standard color and defines an associated MESSAGE to be displayed on the line specified by SET MESSAGE. The lightbar menu is then invoked with MENU TO. You can specify menu items in any order and configuration of row and column position. MENU TO, however, navigates the current list of menu items in the order they were defined. You can define up to 4096 menu items for each menu.

After each @...PROMPT command, the cursor is located one column position to the right of the last menu item character and Row() and Col() are updated to reflect the new cursor position. This lets you use Row() and Col() to specify consecutive menu item positions relative to the first one painted. See the example below.

Examples
■  This example displays a lightbar menu with the associated
   messages displayed on the next line.  When the user presses Return,
   the position of the item in the list of menu items is assigned to
   nChoice:

   LOCAL nChoice := 1
   SET WRAP ON
   SET MESSAGE TO 2
   @ 1, 3 PROMPT "File" MESSAGE "Access data files"
   @ Row(), Col() + 2 PROMPT "Edit" ;
      MESSAGE "Edit current record"
   MENU TO nChoice

■  This example shows how to pass the MESSAGE clause a code block
   which calls a user-defined function that displays a message in a
   different color:

   SET COLOR TO gr+/b,r+/n
   SET MESSAGE TO 23    // This is necessary.
   CLEAR SCREEN

   @ 3,4 PROMPT "one "  MESSAGE {||UDF("Message One  ")}
   @ 4,4 PROMPT "two "  MESSAGE {||UDF("Message Two  ")}
   @ 5,4 PROMPT "three" MESSAGE {||UDF("Message Three")}

   MENU TO test

   FUNCTION UDF(cParm)
   cOldColor := SetColor("w+/n")
   @ 22,1 SAY cParm        // Must be different row than the
                           // SET MESSAGE TO nRow
   SetColor(cOldColor)
   RETURN ""               // Character string must be returned
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

@...SAYHarbour implementation | 

Display data at a specified screen or printer row and column
Syntax
@ <nRow>, <nCol>
   SAY <exp> [PICTURE <cSayPicture>]
   [COLOR <cColorString>]
Arguments
nRow and nCol are the row and column coordinates of the display. Row values can range from zero to a maximum of MaxRow(), if the current DEVICE is the SCREEN, or 32,766, if the current DEVICE is the PRINTER. Also, column values can range from zero to a maximum of MaxCol() or 32,766 if the current DEVICE is the PRINTER.
SAY exp displays the result of a character, date, logical, or numeric expression to the current DEVICE.
PICTURE cSayPicture defines the formatting control for the display of exp. CA-Clipper provides two mechanisms, functions and templates, to control formatting. Functions apply to an entire SAY, while templates format characters position by position.
COLOR cColorString defines the display color of exp. If not specified, exp displays in the standard color as defined by SetColor(). cColorString is a character expression containing the standard color setting. If you specify a literal color setting, it must be enclosed in quote marks.
On a combined @...SAY...GET command, two COLOR clauses are required to specify colors for both the SAY and the GET: one for the SAY and one for the GET.
Description

@...SAY is a full-screen command that outputs the results of exp to either the screen or the printer at the specified row and column coordinates. It can optionally format output using the PICTURE clause. @...SAY creates data entry screens or reports that can be sent to the screen or printer.

When an @...SAY command executes , the output from exp is sent to the current device defined with SET DEVICE. The current DEVICE can be the SCREEN or PRINTER. Unlike console commands, @...SAY output to the printer is not echoed to the screen and SET CONSOLE has no effect on @...SAY output to the screen.

If the current DEVICE is the SCREEN (the system default), @...SAY displays output to the screen leaving the cursor one column position to the right of the last character displayed. Row() and Col() are then updated with this position. Output that displays off the screen, as defined by MaxRow() and MaxCol(), is clipped and the cursor is positioned beyond the visible screen. All @...SAY output displays are in standard color. Refer to the SetColor() reference in this chapter for more information on color.

If the current DEVICE is set to PRINTER, the display is directed to the printer at the specified nRow and nCol position. If the current MARGIN value is greater than zero, it is added to nCol first. The printhead is then advanced one column position to the right of the last character output and PRow() and PCol() are updated. @...SAY commands to the printer behave differently from those to the screen if output is addressed to a printer row or column position less than the current PRow() and PCol() values:

■ If nRow is less than PRow(), an automatic EJECT (Chr(12)) is

sent to the printer followed by the number of linefeed characters (Chr(10)) required to position the printhead on nRow on the following page

■ If nCol including the SET MARGIN value is less than PCol(),

a carriage return character (Chr(13)) and the number of spaces required to position exp at nCol are sent to the printer

To override this behavior and send control codes to the printer, or for any other reason, you can use SetPRC() to reset PRow() and PCol() to new values. See the SetPRC() function reference for more information.

If the current DEVICE is the PRINTER, redirect output from @...SAY commands to a file using the SET PRINTER TO xcFile command.

@...SAY command output can be formatted using the PICTURE clause with a cSayPicture. This performs the same action as the Transform() function. A cSayPicture may consist of a function and/or a template. A PICTURE function imposes a rule on the entire @...SAY output. A PICTURE template defines the length of the @...SAY output and the formatting rule for each position within the output.

■ Function string: A PICTURE function string specifies

formatting rules which apply to the SAY's entire display value, rather than to particular character positions within it. The function string consists of the @ character, followed by one or more additional characters, each of which has a particular meaning (see table below). The function string must not contain spaces. A function string may be specified alone or with a template string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

SAY and Transform() PICTURE Format Functions

       Function     Action
       B            Displays numbers left-justified
       C            Displays CR after positive numbers
       D            Displays dates in SET DATE format
       E            Displays dates and numbers in British format
       R            Nontemplate characters are inserted
       X            Displays DB after negative numbers
       Z            Displays zeros as blanks
       (            Encloses negative numbers in parentheses
       !            Converts alphabetic characters to uppercase

■ Template string: A PICTURE template string specifies

formatting rules on a character-by-character basis. The template string consists of a series of characters, some of which have special meanings (see table below). Each position in the template string corresponds to a position in the displayed SAY value. Characters in the template string that do not have assigned meanings are copied verbatim into the displayed SAY value. If you use the @R picture function, characters without special PICTURE template string meaning are inserted between characters of the display value; otherwise, they overwrite the corresponding characters of the display value. You may specify a template string alone or with a function string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

SAY and Transform() Template Symbols

       Template     Action
       A,N,X,9,#    Displays digits for any data type
       L            Displays logicals as "T" or "F"
       Y            Displays logicals as "Y" or "N"
       !            Converts alphabetic characters to uppercase
       $            Displays a dollar sign in place of a leading space in a
                    number
       *            Displays an asterisk in place of a leading space in a
                    number
       .            Specifies a decimal point position
       ,            Specifies a comma position

Examples
■  This example uses an @...SAY with a PICTURE clause to display
   formatted output:

   nNetIncome = 7125.50
   nNetLoss = -125.50
   cPhone = "2134567890"
   cName = "Kate Mystic"
   //
   @ 1, 1 SAY nNetIncome PICTURE "@E 9,999.99"
   // Result: 7.125,50

   @ 2, 1 SAY nNetLoss PICTURE "@)"
   // Result: (125.50)

   @ 3, 1 SAY cPhone PICTURE "@R (999)999-9999"
   // Result: (213)456-7890

   @ 4, 1 SAY cName PICTURE "@!"
   // Result: KATE MYSTIC

■  This example is a small label printing program that uses SET
   DEVICE to direct output to the printer and SetPRC() to suppress
   automatic EJECTs:

   USE Salesman INDEX Salesman NEW
   SET DEVICE TO PRINTER
   DO WHILE !Eof()                     // Print all records
      @ 2, 5 SAY RTrim(FirstName) + ", " + LastName
      @ 3, 5 SAY Street
      @ 4, 5 SAY RTrim(City) + ", " + State + "  " + ;
               PostalCode
      @ 6, 0 SAY Space(1)            // Move to label bottom
      SetPRC(0, 0)                   // Suppress page eject
      SKIP                           // Next record
   ENDDO
   SET DEVICE TO SCREEN
   CLOSE Salesman
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

@...TOHarbour implementation | 

Draw a single- or double-line box
Syntax
@ <nTop>, <nLeft>
   TO <nBottom>, <nRight> [DOUBLE] [COLOR <cColorString>]
Arguments
nTop, nLeft, nBottom, and nRight define the coordinates of the box. @...TO draws the box using row values from zero to MaxRow() and column values from zero to MaxCol(). nBottom and nRight can be larger than the screen size, but output is clipped at MaxRow() and MaxCol().
DOUBLE draws the box with a double line. If not specified, the box is drawn with a single line.
COLOR cColorString defines the display color of the drawn box. If not specified, the box is drawn using the standard color setting of the current system color as defined by SetColor(). Note that cColorString is a character expression containing the standard color setting. If you specify a literal color setting, enclose it within quote marks.
Description

@...TO draws a single- or double-line box on the screen. If nTop and nBottom are the same, a horizontal line is drawn. If nLeft and nRight are the same, a vertical line is drawn.

After @...TO finishes drawing, the cursor is located in the upper-left corner of the boxed region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.

@...TO is like @...BOX except that @...BOX lets you define the characters of the box and supports a fill character. @...TO, however, is recommended for portability since it does not require the specification of hardware-dependent graphics characters.

Examples
■  This example erases a region of the screen, then draws a box
   of the same size:

   @ 10, 10 CLEAR TO 20, 40
   @ 10, 10 TO 20, 40 DOUBLE COLOR "BG+/B"
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

$ | 

Substring comparison—binary (Relational)
Syntax
<cString1> $ <cString2>
Description
The $ operator is a binary relational operator that performs a case- sensitive substring search and returns true (.T.) if cString1 is found within cString2.
Examples
■  This example illustrates the case-sensitivity of the substring
   operator ($):

   ? "A" $ "ABC"            // Result: .T.
   ? "a" $ "ABC"            // Result: .F.
Platforms
Available on MS-DOS
See also

* | 

Multiplication—binary (Mathematical)
Syntax
<nNumber1> * <nNumber2>
Description
The multiplication operator (*) is a binary operator that returns a numeric value from its operation on nNumber1 and nNumber2.
Examples
■  This example shows multiplication results using different
   operands:

   ?  3 *  0            // Result:  0
   ?  3 * -2            // Result: -6
   ? -3 *  2            // Result: -6
   ? -3 *  0            // Result:  0
   ? -1 *  3            // Result: -3
   ? -2 * -3            // Result:  6
   ?  2 * -3            // Result: -6
   ?  1 * -3            // Result: -3
Platforms
Available on MS-DOS
See also

** | 

Exponentiation—binary (Mathematical)
Syntax
<nNumber1> ** <nNumber2>
<nNumber1> ^  <nNumber2>
Description
The exponentiation operator (**) is a binary operator that raises nNumber1 to the power of nNumber2.
Examples
■  This example shows exponentiation results to 16 decimal
   places, using different operands:

   SET DECIMALS TO 16
   ?  3 **  0            // Result:  1.000000000
   ?  3 **  1            // Result:  3.000000000
   ?  3 ** -2            // Result:  0.111111111
   ? -3 **  2            // Result:  9.000000000
   ? -3 **  0            // Result:  1.000000000
   ? -1 **  3            // Result: -1.000000000
   ? -2 **  3            // Result: -8.000000000
   ?  2 ** -3            // Result:  0.125000000
   ?  1 ** -3            // Result:  1.000000000
Platforms
Available on MS-DOS
See also

& | 

Macro evaluation—unary (Special)
Syntax
&<cMacroVar>[.]
&(<cMacroExp>)
Description

The macro operator in CA-Clipper is a special operator that allows runtime compilation of expressions and text substitution within strings. Whenever the macro operator (&) is encountered, the operand is submitted to a special runtime compiler (the macro compiler) that compiles expressions, but not statements or commands.

Text Substitution

Whenever a reference to a private or public macro variable, embedded in a character string, is encountered, the variable reference is replaced by the content of the macro variable. For example,

cMacro := "there" ? "Hello &cMacro" // Result: Hello there

If you specify a macro expression (e.g., &(cMacro1 + cMacro2)), and the macro variable is a local, static, field variable, or an array element, it is treated as literal text and not expanded.

Macro operator:nesting Compile and Run

When a macro variable or expression specified within an expression is encountered, it is treated like an expression, with the macro symbol behaving as the compile and run operator. If the macro is specified as a macro variable,

cMacro := "DToC(Date())" ? &cMacro

the macro compiler compiles, then executes the content of the macro variable. The compiled code is then discarded.

If you specify an expression enclosed in parentheses and prefaced by the macro operator (&),

? &(IndexKey(0))

the expression is evaluated and the resulting character string is compiled and run as a macro variable.

Using the macro operator, you can compile a character string containing a code block definition:

bBlock := &("{ |exp| QOut(exp) }")

The run portion of the operation returns the code block as a value. You may then use the code block by invoking it with the Eval() function. This is especially significant in activations that involve extensive looping through user-defined conditions (operations that in earlier versions of CA-Clipper required macro expansion). In those versions, the macro expression was compiled and run for each iteration of the loop. With the combination of a macro expansion and a code block Eval(), the compilation is performed once at compile time, and the Eval() merely executes the code block each time through the loop:

Eval(bBlock, Date())

The time savings at runtime can be enormous.

Notes

■ Command keywords: You cannot use the macro operator (&) to

substitute or compile command keywords. However, you can redefine command keywords by modifying the command definition in std.ch, overriding an existing command definition with a new definition using the #command directive, or redefining a command keyword using the #translate directive. In any case, you may redefine a command keyword only at compile time, not at runtime.

■ Command arguments: In prior versions of CA-Clipper as well as

in other dialects, you could use macro variables as the arguments of commands requiring literal text values. These included all file command arguments and SET commands with toggle arguments. In these instances, you can now use an extended expression enclosed in parentheses in place of the literal argument. For example,

xcDatabase = "Invoices" USE &xcDatabase.

can be replaced with:

xcDatabase = "Invoices" USE (xcDatabase)

It is important to use extended expressions if you are using local and static variables. Generally, commands are preprocessed into function calls with command arguments translated into function arguments as valid CA-Clipper values. File names in file commands, for instance, are stringified using the smart stringify result marker and passed as arguments to the functions that actually perform the desired actions. If you specify a literal or macro value as the command argument, it is stringified. If, however, the argument is an extended expression, it is written to the result text exactly as specified. This example,

#command RENAME xcOld TO xcNew; =>;

FRename( (xcOld), (xcNew) )

// RENAME &xcOld TO &xcNew RENAME (xcOld) TO (xcNew)

is written to the result text as this:

FRename( "&xcOld", "&xcNew" ) FRename( xcOld, xcNew )

when preprocessed. When the macro variables are stringified, the macro variable names are hidden in the string and not compiled. Later, at runtime, they are substituted into the string and passed as arguments to the FRename() function. This precludes local and static macro variables since the names of the variables are not present at runtime to be substituted. Public and private variables, however, behave as expected.

■ Lists as arguments of commands: The macro operator (&) will

not fully substitute or compile a list as an argument of most commands. In particular, these are commands where an argument list is preprocessed into an array or a code block. Instances of this are arguments of the FIELDS clause and SET INDEX. An exception is the SET COLOR command which preprocesses the list of colors into a single character string and passes it to the SetColor() function.

In any case, list arguments should always be specified as extended expressions with each list argument specified:

LOCAL xcIndex := { "Ntx1", "Ntx2" } SET INDEX TO (xcIndex[1]), (xcIndex[2])

■ Arrays: You can use the macro operator (&) with arrays and

array elements. However, because of the increased power of CA-Clipper arrays, you may find less need to use the macro operator (&) to make variable references to arrays. You can now assign array references to variables, return array references from user-defined functions, and nest array references within other arrays. You may also create arrays by specifying literal arrays or using the Array() function.

You can, therefore, make references to arrays and array elements using both macro variables and macro expressions with the restriction that you cannot make the subscript references in a PRIVATE or PUBLIC statement. Also, you cannot specify the macro operator (&) in a declaration statement, such as a LOCAL or STATIC statement. Attempting this will generate a fatal compiler error.

This example references array elements using macro variables:

cName := "aArray" nElements := 5 cNameElement := "aArray[1]" // PRIVATE &cName.[nElements] // Creates "array" with 5

// elements

&cNameElement. := 100 // Assigns 100 to element 1 &cName.[3] := "abc" // Assigns "abc" to element 3

You can successfully apply a macro operator (&) to an array element if the reference is made using a macro expression. A macro variable reference, however, will generate a runtime error. For example, the following lists the values of all fields of the current record:

USE Customer NEW aStruc := dbStruct() // FOR nField := 1 TO Len(aStruc)

? &(aStruc[nField, 1])

NEXT

■ Code blocks: You can apply the macro operator (&) to a macro

variable or expression in a code block in most cases. There is a restriction when the macro variable or macro expression contains a declared variable. A runtime error occurs if you specify a complex expression (an expression that contains an operator and one or more operands) that includes the macro operator (&) within a code block.

This has important implications for the use of local and static variables in the conditional clauses of commands, since these clauses are blockified as they are written to the result text during preprocessing. This applies to all FOR and WHILE clauses, the SET FILTER command, and the SET RELATION linking expression. The general workaround is to gather the entire expression into a single macro variable then apply the macro operator (&) to the variable.

■ Macro conditions: When using the macro operator (&) to specify

conditional clauses of database commands such as FOR or WHILE clauses, there are some restrictions based on the expression's complexity and size:

- The maximum string size the macro compiler can process is 254

characters.

- There is a limit to the complexity of conditions (the more

complex, the fewer the number of conditions you can specify).

■ Procedures and functions: You can reference procedure and

function calls using macro variables and expressions. With DO, the macro variable reference to the procedure can be all or part of the procedure name. With a call to a function (built-in or user- defined), the macro variable reference must include the function name and all of its arguments.

In CA-Clipper, because of the added facility code blocks, all invocations of procedures and functions using the macro operator should be converted to the evaluation of code blocks. This code fragment

cProc := "AcctsRpt" . . . DO &cProc

can be replaced with:

bProc := &( "{ || AcctsRpt() }" ) . . . Eval(bProc)

The advantage of a code block over a macro evaluation is that the result of the compilation of a string containing a code block can be saved and, therefore, need only be compiled once. Macro evaluations compile each time they are referenced.

■ References into overlays: You must declare procedures and

user-defined functions that are used in macro expressions and variables but not referenced elsewhere as EXTERNAL, or the linker will not include them into the executable (.EXE) file.

TEXT...ENDTEXT: Macro variables referenced within a

TEXT...ENDTEXT construct are expanded. Note that a field cannot be expanded, so you must first assign the field value to a memory variable then reference the memory variable as a macro variable within the TEXT...ENDTEXT. For example:

USE Customer NEW myVar := Customer->CustName TEXT This is text with a macro &myVar ENDTEXT

■ Nested macros: The processing of macro variables and

expressions in CA-Clipper permits nested macro definitions. For example, after assigning a macro variable to another macro variable, the original macro variable can be expanded resulting in the expansion of the second macro variable and evaluation of its contents:

cOne = "&cTwo" // expand cTwo cTwo = "cThree" // yielding "cThree" cThree = "hello" // ? &cOne // Result: "hello"

Platforms
Available on MS-DOS
See also

#command | #translate | 

Specify a user-defined command or translation directive
Syntax
#command   <matchPattern> => <resultPattern>
#translate   <matchPattern> => <resultPattern>
Arguments
matchPattern is the pattern the input text should match.
resultPattern is the text produced if a portion of input text matches the matchPattern.
The => symbol between matchPattern and resultPattern is, along with #command or #translate, a literal part of the syntax that must be specified in a #command or #translate directive. The symbol consists of an equal sign followed by a greater than symbol with no intervening spaces. Do not confuse the symbol with the >= or the <= comparison operators in the CA-Clipper language.
Description

#command and #translate are translation directives that define commands and pseudofunctions. Each directive specifies a translation rule. The rule consists of two portions: a match pattern and a result pattern. The match pattern matches a command specified in the program (.prg) file and saves portions of the command text (usually command arguments) for the result pattern to use. The result pattern then defines what will be written to the result text and how it will be written using the saved portions of the matching input text.

#command and #translate are similar, but differ in the circumstance under which their match patterns match input text. A #command directive matches only if the input text is a complete statement, while #translate matches input text that is not a complete statement. #command defines a complete command and #translate defines clauses and pseudofunctions that may not form a complete statement. In general, use #command for most definitions and #translate for special cases.

#command and #translate are similar to but more powerful than the #define directive. #define, generally, defines identifiers that control conditional compilation and manifest constants for commonly used constant values such as Inkey() codes. Refer to any of the header files in the \CLIP53\INCLUDE directory for examples of manifest constants defined using #define.

#command and #translate directives have the same scope as the #define directive. The definition is valid only for the current program (.prg) file unless defined in std.ch or the header specified with the /U option on the compiler command line. If defined elsewhere, the definition is valid from the line where it is specified to the end of the program file. Unlike #define, a #translate or #command definition cannot be explicitly undefined. The #undef directive has no effect on a #command or #translate definition.

As the preprocessor encounters each source line preprocessor, it scans for definitions in the following order of precedence: #define, #translate, and #command. When there is a match, the substitution is made to the result text and the entire line is reprocessed until there are no matches for any of the three types of definitions. #command and #translate rules are processed in stack-order (i.e., last in-first out, with the most recently specified rule processed first).

In general, a command definition provides a way to specify an English language statement that is, in fact, a complicated expression or function call, thereby improving the readability of source code. You can use a command in place of an expression or function call to impose order of keywords, required arguments, combinations of arguments that must be specified together, and mutually exclusive arguments at compile time rather than at runtime. This can be important since procedures and user-defined functions can now be called with any number of arguments, forcing any argument checking to occur at runtime. With command definitions, the preprocessor handles some of this.

All commands in CA-Clipper are defined using the #command directive and supplied in the standard header file, std.ch, located in the \CLIP53\INCLUDE directory. The syntax rules of #command and #translate facilitate the processing of all CA-Clipper and dBASE-style commands into expressions and function calls. This provides CA-Clipper compatibility, as well as avenues of compatibility with other dialects.

When defining a command, there are several prerequisites to properly specifying the command definition. Many preprocessor commands require more than one #command directive because mutually exclusive clauses contain a keyword or argument. For example, the @...GET command has mutually exclusive VALID and RANGE clauses and is defined with a different #command rule to implement each clause.

This also occurs when a result pattern contains different expressions, functions, or parameter structures for different clauses specified for the same command (e.g., the @...SAY command). In std.ch, there is a #command rule for @...SAY specified with the PICTURE clause and another for @...SAY specified without the PICTURE clause. Each formulation of the command is translated into a different expression. Because directives are processed in stack order, when defining more than one rule for a command, place the most general case first, followed by the more specific ones. This ensures that the proper rule will match the command specified in the program (.prg) file.

For more information and a general discussion of commands, refer to the "Basic Concepts" chapter in the Programming and Utilities Guide.

Match Pattern

The matchPattern portion of a translation directive is the pattern the input text must match. A match pattern is made from one or more of the following components, which the preprocessor tries to match against input text in a specific way:

■ Literal values are actual characters that appear in the match

pattern. These characters must appear in the input text, exactly as specified to activate the translation directive.

■ Words are keywords and valid identifiers that are compared

according to the dBASE convention (case-insensitive, first four letters mandatory, etc.). The match pattern must start with a Word.

#xcommand and #xtranslate can recognize keywords of more than four significant letters.

■ Match markers are label and optional symbols delimited by

angle brackets (<>) that provide a substitute (idMarker) to be used in the resultPattern and identify the clause for which it is a substitute. Marker names are identifiers and must, therefore, follow the CA-Clipper identifier naming conventions. In short, the name must start with an alphabetic or underscore character, which may be followed by alphanumeric or underscore characters.

This table describes all match marker forms:

Match Markers

       Match Marker             Name
       <idMarker>               Regular match marker
       <idMarker,...>           List match marker
       <idMarker:word list>     Restricted match marker
       <*idMarker*>             Wild match marker
       <(idMarker)>             Extended Expression match marker

- Regular match marker: Matches the next legal expression in the

input text. The regular match marker, a simple label, is the most general and, therefore, the most likely match marker to use for a command argument. Because of its generality, it is used with the regular result marker, all of the stringify result markers, and the blockify result marker.

- List match marker: Matches a comma-separated list of legal

expressions. If no input text matches the match marker, the specified marker name contains nothing. You must take care in making list specifications because extra commas will cause unpredictable and unexpected results.

The list match marker defines command clauses that have lists as arguments. Typically these are FIELDS clauses or expression lists used by database commands. When there is a match for a list match marker, the list is usually written to the result text using either the normal or smart stringify result marker. Often, lists are written as literal arrays by enclosing the result marker in curly ({ }) braces.

- Restricted match marker: Matches input text to one of the

words in a comma-separated list. If the input text does not match at least one of the words, the match fails and the marker name contains nothing.

A restricted match marker is generally used with the logify result marker to write a logical value into the result text. If there is a match for the restricted match marker, the corresponding logify result marker writes true (.T.) to the result text; otherwise, it writes false (.F.). This is particularly useful when defining optional clauses that consist of a command keyword with no accompanying argument. std.ch implements the REST clause of database commands using this form.

- Wild match marker: Matches any input text from the current

position to the end of a statement. Wild match markers generally match input that may not be a legal expression, such as #command NOTE *x* in std.ch, gather the input text to the end of the statement, and write it to the result text using one of the stringify result markers.

- Extended expression match marker: Matches a regular or

extended expression, including a file name or path specification. It is used with the smart stringify result marker to ensure that extended expressions will not get stringified, while normal, unquoted string file specifications will.

■ Optional match clauses are portions of the match pattern

enclosed in square brackets ([ ]). They specify a portion of the match pattern that may be absent from the input text. An optional clause may contain any of the components allowed within a matchPattern, including other optional clauses.

Optional match clauses may appear anywhere and in any order in the match pattern and still match input text. Each match clause may appear only once in the input text. There are two types of optional match clauses: one is a keyword followed by match marker, and the other is a keyword by itself. These two types of optional match clauses can match all of the traditional command clauses typical of the CA-Clipper command set.

Optional match clauses are defined with a regular or list match marker to match input text if the clause consists of an argument or a keyword followed by an argument (see the INDEX clause of the USE command in std.ch). If the optional match clause consists of a keyword by itself, it is matched with a restricted match marker (see the EXCLUSIVE or SHARED clause of the USE command in std.ch).

In any match pattern, you may not specify adjacent optional match clauses consisting solely of match markers, without generating a compiler error. You may repeat an optional clause any number of times in the input text, as long as it is not adjacent to any other optional clause. To write a repeated match clause to the result text, use repeating result clauses in the resultPattern definition.

Result Pattern

The resultPattern portion of a translation directive is the text the preprocessor will produce if a piece of input text matches the matchPattern. resultPattern is made from one or more of the following components:

■ Literal tokens are actual characters that are written directly

to the result text.

■ Words are CA-Clipper keywords and identifiers that are written

directly to the result text.

■ Result markers: refer directly to a match marker name. Input

text matched by the match marker is written to the result text via the result marker.

This table lists the Result marker forms:

Result Markers

       Result Marker     Name
       <idMarker>        Regular result marker
       #<idMarker>       Dumb stringify result marker
       <"idMarker">      Normal stringify result marker
       <(idMarker)>      Smart stringify result marker
       <{idMarker}>      Blockify result marker
       <.idMarker.>      Logify result marker

- Regular result marker: Writes the matched input text to the

result text, or nothing if no input text is matched. Use this, the most general result marker, unless you have special requirements. You can use it with any of the match markers, but it almost always is used with the regular match marker.

- Dumb stringify result marker: Stringifies the matched input

text and writes it to the result text. If no input text is matched, it writes a null string (""). If the matched input text is a list matched by a list match marker, this result marker stringifies the entire list and writes it to the result text.

This result marker writes output to result text where a string is always required. This is generally the case for commands where a command or clause argument is specified as a literal value but the result text must always be written as a string even if the argument is not specified.

- Normal stringify result marker: Stringifies the matched input

text and writes it to the result text. If no input text is matched, it writes nothing to the result text. If the matched input text is a list matched by a list match marker, this result marker stringifies each element in the list and writes it to the result text.

The normal stringify result marker is most often used with the blockify result marker to compile an expression while saving a text image of the expression (See the SET FILTER condition and the INDEX key expression in std.ch).

- Smart stringify result marker: Stringifies matched input text

only if source text is enclosed in parentheses. If no input text matched, it writes nothing to the result text. If the matched input text is a list matched by a list match marker, this result marker stringifies each element in the list (using the same stringify rule) and writes it to the result text.

The smart stringify result marker is designed specifically to support extended expressions for commands other than SETs with xlToggle arguments. Extended expressions are command syntax elements that can be specified as literal text or as an expression if enclosed in parentheses. The xcDatabase argument of the USE command is a typical example. For instance, if the matched input for the xcDatabase argument is the word Customer, it is written to the result text as the string "Customer," but the expression (cPath + cDatafile) would be written to the result text unchanged (i.e., without quotes).

- Blockify result marker: Writes matched input text as a code

block without any arguments to the result text. For example, the input text x + 3 would be written to the result text as {|| x + 3}. If no input text is matched, it writes nothing to the result text. If the matched input text is a list matched by a list match marker, this result marker blockifies each element in the list.

The blockify result marker used with the regular and list match markers matches various kinds of expressions and writes them as code blocks to the result text. Remember that a code block is a piece of compiled code to execute sometime later. This is important when defining commands that evaluate expressions more than once per invocation. When defining a command, you can use code blocks to pass an expression to a function and procedure as data rather than as the result of an evaluation. This allows the target routine to evaluate the expression whenever necessary.

In std.ch, the blockify result marker defines database commands where an expression is evaluated for each record. Commonly, these are field or expression lists, FOR and WHILE conditions, or key expressions for commands that perform actions based on key values.

- Logify result marker: Writes true (.T.) to the result text if

any input text is matched; otherwise, it writes false (.F.) to the result text. This result marker does not write the input text itself to the result text.

The logify result marker is generally used with the restricted match marker to write true (.T.) to the result text if an optional clause is specified with no argument; otherwise, it writes false (.F.). In std.ch, this formulation defines the EXCLUSIVE and SHARED clauses of the USE command.

■ Repeating result clauses are portions of the resultPattern

enclosed by square brackets ([ ]). The text within a repeating clause is written to the result text as many times as it has input text for any or all result markers within the clause. If there is no matching input text, the repeating clause is not written to the result text. Repeating clauses, however, cannot be nested. If you need to nest repeating clauses, you probably need an additional #command rule for the current command.

Repeating clauses are the result pattern part of the #command facility that create optional clauses which have arguments. You can match input text with any match marker other than the restricted match marker and write to the result text with any of the corresponding result markers. Typical examples of this facility are the definitions for the STORE and REPLACE commands in std.ch.

Notes

■ Less than operator: If you specify the less than operator (`)

in the resultPattern expression, you must precede it with the escape character ().

■ Multistatement lines: You can specify more than one statement

as a part of the result pattern by separating each statement with a semicolon. If you specify adjacent statements on two separate lines, the first statement must be followed by two semicolons.

Examples
These examples encompass many of the basic techniques you can use when
defining commands with the #command and #translate directives.  In
general, these examples are based on standard commands defined in
Std.ch.  Note, however, the functions specified in the example result
patterns are not the actual functions found in std.ch, but fictitious
functions specified for illustration only.

■  This example defines the @...BOX command using regular match
   markers with regular result markers:

   #command  @ <top>, <left>, <bottom>, <right> BOX ;
         <boxstring>;
   =>;
         CmdBox( <top>, <left>, <bottom>, ;
         <right>,<boxstring> )

■  This example uses a list match marker with a regular result
   marker to define the ? command:

   #command ? [<list,...>] => QOut(<list>)

■  This example uses a restricted match marker with a logify
   result marker to implement an optional clause for a command
   definition.  In this example, if the ADDITIVE clause is specified,
   the logify result marker writes true (.T.) to the result text;
   otherwise, it writes false (.F.):

   #command RESTORE FROM <file> [<add: ADDITIVE>];
   =>;
         CmdRestore( <(file)>, <.add.> )

■  This example uses a list match marker with a smart stringify
   result marker to write to the result text the list of fields
   specified as the argument of a FIELDS clause.  In this example, the
   field list is written as an array with each field name as an element
   of the array:

   #command COPY TO <file> [FIELDS <fields,...>];
   =>;
         CmdCopyAll( <(file)>, { <(fields)> } )

■  These examples use the wild match marker to define a command
   that writes nothing to the result text.  Do this when attempting to
   compile unmodified code developed in another dialect:

   #command SET ECHO <*text*>    =>
   #command SET TALK <*text*>    =>

■  These examples use wild match markers with dumb stringify
   result markers to match command arguments specified as literals, then
   write them to the result text as strings in all cases:

   #command SET PATH TO <*path*>  =>  ;
      Set( _SET_PATH, #<path> )
   #command SET COLOR TO <*spec*> =>  SetColor( #<spec> )

■  These examples use a normal result marker with the blockify
   result marker to both compile an expression and save the text version
   of it for later use:

   #command SET FILTER TO <xpr>;
   =>;
         CmdSetFilter( <{xpr}>, <"xpr"> )

   #command INDEX ON <key> TO <file>;
   =>;
         CmdCreateIndex( <(file)>, <"key">, <{key}> )

■  This example demonstrates how the smart stringify result
   marker implements a portion of the USE command for those arguments
   that can be specified as extended expressions:

   #command USE <db> [ALIAS <a>];
   =>;
         CmdOpenDbf( <(db)>, <(a)> )

■  This example illustrates the importance of the blockify result
   marker for defining a database command.  Here, the FOR and WHILE
   conditions matched in the input text are written to the result text
   as code blocks:

   #command COUNT [TO <var>];
         [FOR <for>] [WHILE <while>];
         [NEXT <next>] [RECORD <rec>] [<rest:REST>] [ALL];
   =>;
         <var> := 0,;
         dbEval( {|| <var>++}, <{for}>, <{while}>,;
            <next>, <rec>, <.rest.> )

■  In this example the USE command again demonstrates the types
   of optional clauses with keywords in the match pattern.  one clause
   is a keyword followed by a command argument, and the second is solely
   a keyword:

   #command USE <db> [<new: NEW>] [ALIAS <a>] ;
         [INDEX <index,...>][<ex: EXCLUSIVE>] ;
         [<sh: SHARED>] [<ro: READONLY>];
   =>;
         CmdOpenDbf(<(db)>, <(a)>, <.new.>,;
            IF(<.sh.> .OR. <.ex.>, !<.ex.>, NIL),;
               <.ro.>, {<(index)>})

■  This example uses the STORE command definition to illustrate
   the relationship between an optional match clause and a repeating
   result clause:

   #command STORE <value> TO <var1> [, <varN> ];
   =>;
         <var1> := [ <varN> := ] <value>

■  This example uses #translate to define a pseudofunction:

   #translate AllTrim(<cString>) => LTrim(RTrim(<cString>))
Platforms
Available on MS-DOS
See also

#define | 

Define a manifest constant or pseudofunction
Syntax
#define <idConstant> [<resultText>]
#define <idFunction>([<arg list>]) [<exp>]
Arguments
idConstant is the name of an identifier to define.
resultText is the optional replacement text to substitute whenever a valid idConstant is encountered.
idFunction is a pseudofunction definition with an optional argument list (arg list). If you include arg list, it is delimited by parentheses (()) immediately following idFunction.
exp is the replacement expression to substitute when the pseudofunction is encountered. Enclose this expression in parentheses to guarantee precedence of evaluation when the pseudofunction is expanded.
Note: #define identifiers are case-sensitive, where #command and #translate identifiers are not.
Description

The #define directive defines an identifier and, optionally, associates a text replacement string. If specified, replacement text operates much like the search and replace operation of a text editor. As each source line from a program file is processed by the preprocessor, the line is scanned for identifiers. If a currently defined identifier is encountered, the replacement text is substituted in its place.

Identifiers specified with #define follow most of the identifier naming rules in CA-Clipper . Defined identifiers can contain any combination of alphabetic and numeric characters, including underscores. Defined identifiers, however, differ from other identifiers by being case- sensitive. As a convention, defined identifiers are specified in uppercase to distinguish them from other identifiers used within a program. Additionally, identifiers are specified with a one or two letter prefix to group similar identifiers together and guarantee uniqueness. Refer to one of the supplied header files in the \CLIP53\INCLUDE directory for examples.

When specified, each definition must occur on a line by itself. Unlike statements, more than one directive cannot be specified on the same source line. You may continue a definition on a subsequent line by employing a semicolon (;). Each #define directive is specified followed by one or more white space characters (spaces or tabs), a unique identifier, and optional replacement text. Definitions can be nested, allowing one identifier to define another.

A defined identifier has lexical scope like a filewide static variable. It is only valid in the program (.prg) file in which it is defined unless defined in std.ch or the header file specified on the compiler command line with the /U option. Unlike a filewide static variable, a defined identifier is visible from the point where it is defined in the program file until it is either undefined, redefined, or the end of the program file is reached.

You can redefine or undefine existing identifiers. To redefine an identifier, specify a new #define directive with the identifier and the new replacement text as its arguments. The current definition is then overwritten with the new definition, and a compiler warning is issued in case the redefinition is inadvertent. To undefine an identifier, specify an #undef directive with the identifier as its argument. #define directives have three basic purposes:

■ To define a control identifier for #ifdef and #ifndef

■ To define a manifest constant—an identifier defined to

represent a constant value

■ To define a compiler pseudofunction

The following discussion expands these three purposes of the #define directive in your program.

Preprocessor Identifiers

The most basic #define directive defines an identifier with no replacement text. You can use this type of identifier when you need to test for the existence of an identifier with either the #ifdef or #ifndef directives. This is useful to either exclude or include code for conditional compilation. This type of identifier can also be defined using the /D compiler option from the compiler command line. See the examples below.

Manifest Constants

The second form of the #define directive assigns a name to a constant value. This form of identifier is referred to as a manifest constant. For example, you can define a manifest constant for the Inkey() code associated with a key press:

#define K_ESC 27 IF LastKey() = K_ESC

. . statements .

ENDIF

Whenever the preprocessor encounters a manifest constant while scanning a source line, it replaces it with the specified replacement text.

Although you can accomplish this by defining a variable, there are several advantages to using a manifest constant: the compiler generates faster and more compact code for constants than for variables; and variables have memory overhead where manifest constants have no runtime overhead, thus saving memory and increasing execution speed. Furthermore, using a variable to represent a constant value is conceptually inconsistent. A variable by nature changes and a constant does not.

Use a manifest constant instead of a constant for several reasons. First, it increases readability. In the example above, the manifest constant indicates more clearly the key being represented than does the Inkey() code itself. Second, manifest constants localize the definition of constant values, thereby making changes easier to make, and increasing reliability. Third, and a side effect of the second reason, is that manifest constants isolate implementation or environment specifics when they are represented by constant values.

To further isolate the effects of change, manifest constants and other identifiers can be grouped together into header files allowing you to share identifiers between program (.prg) files, applications, and groups of programmers. Using this methodology, definitions can be standardized for use throughout a development organization. Merge header files into the current program file by using the #include directive.

For examples of header files, refer to the supplied header files in the \CLIP53\INCLUDE directory.

Compiler Pseudo-functions

In addition to defining constants as values, the #define directive can also define pseudofunctions that are resolved at compile time. A pseudofunction definition is an identifier immediately followed by an argument list, delimited by parentheses, and the replacement expression. For example:

#define AREA(nLength, nWidth) (nLength * nWidth) #define SETVAR(x, y) (x := y) #define Max(x, y) (IF(x > y, x, y))

Pseudofunctions differ from manifest constants by supporting arguments. Whenever the preprocessor scans a source line and encounters a function call that matches the pseudofunction definition, it substitutes the function call with the replacement expression. The arguments of the function call are transported into the replacement expression by the names specified in the argument list of the identifier definition. When the replacement expression is substituted for the pseudofunction, names in the replacement expression are replaced with argument text. For example, the following invocations,

? AREA(10, 12) SETVAR(nValue, 10) ? Max(10, 9)

are replaced by :

? (10 * 12) nValue := 10 ? (IF(10 > 9, 10, 9)

It is important when defining pseudofunctions, that you enclose the result expression in parentheses to enforce the proper order of evaluation. This is particularly important for numeric expressions. In pseudofunctions, you must specify all arguments. If the arguments are not specified, the function call is not expanded as a pseudofunction and exits the preprocessor to the compiler as encountered.

Pseudofunctions do not entail the overhead of a function call and are, therefore, generally faster. They also use less memory. Pseudofunctions, however, are more difficult to debug within the debugger, have a scope different from declared functions and procedures, do not allow skipped arguments, and are case-sensitive.

You can avoid some of these deficiencies by defining a pseudofunction using the #translate directive. #translate pseudofunctions are not case- sensitive, allow optional arguments, and obey the dBASE four-letter rule. See the #translate directive reference in this chapter for more information.

Examples
■  In this example a manifest constant conditionally controls the
   compilation of debugging code:

   #define DEBUG
   .
   . <statements>
   .
   #ifdef DEBUG
      Assert(FILE("System.dbf"))
   #endif

■  This example defines a manifest constant and substitutes it
   for an Inkey() value:

   #define K_ESC      27
   .
   . <statements>
   .
   IF Inkey() != K_ESC
      DoIt()
   ELSE
      StopIt()
   ENDIF

■  This example defines pseudofunctions for the standard
   CA-Clipper functions, Max() and AllTrim():

   #define Max(arg1, arg2)      (IF(arg1 > arg2, ;
      arg1, arg2))
   #define AllTrim(cString)   (RTrim(LTrim(cString)))
   .
   . <statements>
   .
   ? Max(1, 2)
   ? AllTrim("  Hello  ")
Platforms
Available on MS-DOS
See also

#error | 

Generate a compiler error and display a message
Syntax
#error [<messageText>]
Arguments
messageText is the text of the message to be displayed. messageText is a literal character string—do not enclose the message in quotations unless you want them to appear as part of the display.
Description
#error causes the compiler to generate error number C2074. If the messageText parameter is specified, an error message is displayed.
Examples
■  This example displays an error message based on whether or not
   a NETWORK identifier was defined:

   #ifdef NETWORK
      #error Network version not implemented.
   #endif
Platforms
Available on MS-DOS
See also

#ifdef | 

Compile a section of code if an identifier is defined
Syntax
#ifdef <identifier>
   <statements>...
[#else]
   <statements>...
#endif
Arguments
identifier is the name of a definition whose existence is being verified.
Description

#ifdef...#endif lets you perform a conditional compilation. It does this by identifying a section of source code to be compiled if the specified identifier is defined. The identifier can be defined using either the #define directive or the /D compiler option which lets you define an identifier or manifest constant from the compiler command line.

The #else directive specifies the code to compile if identifier is undefined. The #endif terminates the conditional compilation block.

Conditional compilation is particularly useful when maintaining many different versions of the same program. For example, the demo code and full system code could be included in the same program file and controlled by a single #define statement.

Examples
■  This code fragment is a general skeleton for conditional
   compilation with #ifdef:

   #define DEMO
   .
   . <statements>
   .
   #ifdef DEMO
      <demo specific statements>
   #endif

■  This example controls conditional compilation with an
   identifier defined on the compiler command line with the /D option.

   In DOS:

   C>CLIPPER Myfile /DDEBUG

   In the program (.prg) file:

   #ifdef DEBUG
      Assert(<some condition>)
   #endif

■  This example defines a manifest constant to one value if it
   does not exist and redefines it to another if it exists:

   #ifdef M_MARGIN
      #undef  M_MARGIN
      #define M_MARGIN   15
   #else
      #define M_MARGIN   10
   #endif
Platforms
Available on MS-DOS
See also

#ifndef | 

Compile a section of code if an identifier is undefined
Syntax
#ifndef <identifier>
   <statements>...
[#else]
   <statements>...
#endif
Arguments
identifier is the name of a definition whose absence is being verified.
Description

#ifndef...#endif lets you perform conditional compilation by identifying a section of source code to compile if the specified identifier is undefined.

The #else directive specifies the code to compile if identifier is defined. The #endif terminates the conditional compilation block.

Examples
■  This code fragment is a general skeleton for conditional
   compilation with #ifndef:

   #define DEBUG
   .
   . <statements>
   .
   #ifndef DEBUG
      <optimized version of code>
   #else
      <debugging version of code>
   #endif

■  This example compiles a section of code if a specific
   identifier is undefined.

   In DOS:

   C>CLIPPER Myfile

   In the program (.prg) file:

   #ifndef NODEBUG
      Assert(<some condition>)
   #endif

■  This example overrides a default definition in the program
   (.prg) file using a manifest constant defined on the compiler command
   line with the /D option

   In DOS:

   C>CLIPPER Myfile /DM_MARGIN=10

   In the program (.prg) file:

   #ifndef M_MARGIN
      #define M_MARGIN   15
   #endif
Platforms
Available on MS-DOS
See also

#include | 

Include a file into the current source file
Syntax
#include "<headerFileSpec>"
Arguments
headerFileSpec specifies the name of another source file to include in the current source file. As indicated in the syntax, the name must be enclosed in double quotation marks.
headerFileSpec may contain an explicit path and file name as well as a file extension. If, however, no path is specified, the preprocessor searches the following places:
■ Source file directory
■ Directories supplied with the /I option
■ Directories specified in the INCLUDE environment variable
#include directives may be nested up to 15 levels deep—that is, a file that has been included may contain #include directives, up to 15 levels.
Description

#include inserts the contents of the specified file in place of the #include directive in the source file. By convention, the file inserted is referred to as a header file. Header files should contain only preprocessor directives and external declarations. By convention CA-Clipper header files have a .ch extension.

When deciding where to locate your header files, you have two basic choices. You can place them in the source file directory where they are local to the current system; or, you can make them globally available by placing them in the directory specified in the INCLUDE environment variable. A list of one or more directories can be specified.

Header files overcome the one major drawback of defining constants or inline functions—the #define directive only affects the file in which it is contained. This means that every program which needs access to these statements must have a list of directives at the top. The solution to this problem is to place #define statements in a separate file and use the #include directive to tell the preprocessor to include that file before compiling.

For example, suppose the file "Inkey.ch" contains a list of #define directives assigning key values to constants. Instead of including these directives at the top of each program file (.prg) requiring access to them, you can simply place the following line at the top of each program file:

#include "Inkey.ch"

This causes the preprocessor to look for inkey.ch and place all the directives contained within it at the top of this program.

Another advantage of using the #include directive is that all the #define statements are contained in one file. If any modifications to these statements are necessary, only the #include file need be altered; the program itself remains untouched.

Note that the scope of definitions within an included header file is the current program file unless the header file is included on the compiler command line with the /U option. In this case, the scope is all the program files compiled in the current invocation of the compiler.

Notes

■ Supplied header files: CA-Clipper provides a number of header

files containing manifest constants for common operations. Refer to \CLIP53\INCLUDE for more information.

std.ch—the standard header file: std.ch is the standard

header file provided with CA-Clipper. Its default location is \CLIP53\INCLUDE. std.ch contains the definitions of all CA-Clipper commands and the standard functions specified as pseudofunctions. It is strongly recommended that no changes be made to std.ch. If changes are desired, it is advisable to copy std.ch to a new name, make the changes, and compile with /U.

This header file differs somewhat from a header file you might #include in that everything defined in std.ch, with #define, #translate, or #command, has a scope of the entire compile rather than the current source file.

Examples
■  This example uses #include to insert inkey.ch, a file of
   common keyboard definitions, into a key exception handler called by
   an interface function:

   #include "Inkey.ch"

   FUNCTION GetEvent()
      LOCAL nKey, nResult
      nKey = Inkey(0)
      DO CASE
      CASE nKey = K_F10
         nResult := DoMenu("Browse")
      CASE nKey = K_ESC
         nResult := DoQuit()
         .
         . <statements>
         .
      CASE nKey = K_CTRL_RIGHT
         nResult := DoNextRec()
      ENDCASE
      RETURN nResult
Platforms
Available on MS-DOS
See also

#stdout | 

Send literal text to the standard output device
Syntax
#stdout [<messageText>]
Arguments
messageText is the text of the message to display. messageTest is a literal character string. Do not enclose the message in quotation marks unless you want them to appear as part of the display.
Description

#stdout causes the compiler to output the literal text to the standard output device (stdout) during compilation. If messageText is not specified, a carriage return/line feed pair echoes to stdout.

Warning! Manifest constants are not translated in #stdout. Implementation is identical to #error with the following exceptions: output is written to STDOUT and no compiler error is generated.

Examples
This example demonstrates use of #stdout:

#ifdef DEBUG
   #stdout Compiling debugging version...
#endif

PROCEDURE Main()

? "Hello world"
RETURN

#stdout End of "Hello World" program
Platforms
Available on MS-DOS
See also

#undef | 

Remove a #define macro definition
Syntax
#undef <identifier>
Arguments
identifier is the name of the manifest constant or pseudofunction to remove.
Description
#undef removes an identifier defined with the #define directive. After an #undef, the specified identifier becomes undefined. Use #undef to remove an identifier before you redefine it with #define, preventing the compiler warning that occurs when an existing identifier is redefined. Also, use #undef to make conditional compilation specific to certain sections of a program.
Examples
■  To define and then undefine a manifest constant and a
   pseudofunction:

   #define K_ESC  27
   #define Max(x, y)   IF(x > y, x, y)
   .
   . <statements>
   .
   #undef K_ESC
   #undef MAX

■  To use #undef to undefine an identifier before redefining it:

   #define DEBUG
   .
   . <statements>
   .
   #undef DEBUG
   #define DEBUG   .T.

■  To undefine an identifier if it exists, and otherwise define
   it for later portions of the program file:

   #ifdef TEST
      #undef TEST
   #else
      #define TEST
   #endif
Platforms
Available on MS-DOS
See also

#xcommand | #xtranslate | 

Specify a user-defined command or translation directive
Syntax
#xcommand   <matchPattern> => <resultPattern>
#xtranslate <matchPattern> => <resultPattern>
Arguments
matchPattern is the pattern to match in the input text.
resultPattern is the text produced if a piece of input text matches the matchPattern.
Description
The #xcommand and #xtranslate directives work like #command and #translate except that they overcome the dBASE keyword length limitation. They are significant beyond the first four letters, limited only by available memory. All other rules apply.
Platforms
Available on MS-DOS
See also

% | 

Modulus—binary (Mathematical)
Syntax
<nNumber1> % <nNumber2>
Description
% returns a number representing the remainder of nNumber1 divided by nNumber2.
Notes

■ Seeking the modulus of any dividend using a zero as the

divisor causes a runtime error. In versions of CA-Clipper prior to Summer '87, a modulus operation with a zero divisor returned zero.

Examples
■  This example shows modulus results using different operands:

   ?  3 %  0            // Result: Runtime error
   ?  3 % -2            // Result:  1
   ? -3 %  2            // Result: -1
   ? -3 %  0            // Result: Runtime error
   ? -1 %  3            // Result: -1
   ? -2 %  3            // Result: -2
   ?  2 % -3            // Result:  2
   ?  1 % -3            // Result:  1
Platforms
Available on MS-DOS
See also

+ | 

Addition, unary positive, concatenation (Math, Character)
Syntax
<nNumber1> + <nNumber2>           (addition)
<dDate>    + <nNumber>            (addition)
<cString1> + <cString2>           (concatenation)
Description

The (+) operator performs a number of different operations depending on the data types of the operands:

■ Unary positive sign (numeric): A numeric expression prefaced

with the plus (+) operator performs no operation on the operand except to enforce a higher level of precedence than other numeric operations (except the unary minus).

■ Binary addition sign (numeric, date): If both operands are

numeric, nNumber2 is added to nNumber1 and the result is returned as a numeric value. If either operand is date data type and the other operand numeric data type, the nNumber is added as days to the dDate and a date value is returned.

■ Concatenation (character, memo): If both operands are

character, cString2 (the right operand) is concatenated to cString1 (the left operand) returning a character string.

Examples
■  These examples illustrate the various forms of the + operator:

   // Binary addition (numeric)
   ? 1 + 1                           // Result: 2
   ? 1 + 0                           // Result: 1
   ? 0 + 1                           // Result: 1

   // Binary addition (date)
   ? CToD("12/12/88") + 12         // Result: 12/24/88
   ? 12 + CToD("12/12/88")         // Result: 12/24/88

   // Concatenation (character)
   ? "Hi " + "there"               // Result: Hi there
Platforms
Available on MS-DOS
See also

++ | 

Increment—unary (Mathematical)
Syntax
++<idVar>         (prefix increment)
<idVar>++         (postfix increment)
Description

The increment operator (++) increases the value of its operand by one. This operator adds one to the value of idVar and assigns the new value to idVar.

The ++ operator can appear before or after idVar. Specifying the operator before idVar increments and assigns the value before idVar is used. This is called prefix notation, and it is the most common usage. Specifying the operator after idVar, postfix notation, increments and assigns the value after idVar is used. Stated differently, postfix notation delays the assignment portion of the operation until the rest of the expression is evaluated, and prefix notation gives the assignment precedence over all other operations in the expression.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. You can assign field variables by declaring the field variable name in a FIELD statement or referring to the field name prefaced by the FIELD-> alias or the name of the work area.

Examples
■  This code uses the prefix increment operator in an assignment
   statement.  Therefore, both variables have the same value when
   queried:

   nValue := 0
   nNewValue := ++nValue
   ? nNewValue               // Result:   1
   ? nValue                  // Result:   1

■  In this example, the postfix increment operator increases the
   first operand of the multiplication operation by one, making its
   value 11; however, the assignment of this new value to the nValue
   variable will not take place until the entire expression is
   evaluated.  Therefore, its value is still 10 when the multiplication
   operation occurs, and the result of 11 * 10 is 110.  Finally, when
   nValue is queried again after the expression is evaluated, the
   postfix increment assignment is reflected in its new value, 11.

   nValue := 10
   ? nValue++ * nValue       // Result: 110
   ? nValue                  // Result:  11
Platforms
Available on MS-DOS
See also

AAdd()Harbour implementation  | 

Add a new element to the end of an array
Syntax
AAdd(<aTarget>, <expValue>) → Value
Arguments
aTarget is the array to which a new element is to be added.
expValue is the value assigned to the new element.
Returns
AAdd() evaluates expValue and returns its value. If expValue is not specified, AAdd() returns NIL.
Description

AAdd() is an array function that increases the actual length of the target array by one. The newly created array element is assigned the value specified by expValue.

AAdd() is used to dynamically grow an array. It is useful for building dynamic lists or queues. A good example of this is the GetList array used by the Get system to hold Get objects. After a READ or CLEAR GETS, GetList becomes an empty array. Each time you execute an @...GET command, the Get system uses AAdd() to add a new element to the end of the GetList array, and then assigns a new Get object to the new element.

AAdd() is similar to ASize() but only adds one element at a time; ASize() can grow or shrink an array to a specified size. AAdd(), however, has the advantage that it can assign a value to the new element, while ASize() cannot. AAdd() may also seem similar to AIns(), but they are different: AIns() moves elements within an array, but it does not change the array's length.

Note: If expValue is another array, the new element in the target array will contain a reference to the array specified by expValue.

Examples
■  These examples demonstrate the effects of multiple invocations
   of AAdd() to an array:

   aArray := {}                  // Result: aArray is an empty array
   AAdd(aArray, 5)               // Result: aArray is { 5 }
   AAdd(aArray, 10)              // Result: aArray is { 5, 10 }
   AAdd(aArray, { 12, 10 })      // Result: aArray is
                                 // { 5, 10, { 12, 10 } }
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Abs()Harbour implementation  | 

Return the absolute value of a numeric expression
Syntax
Abs(<nExp>) → nPositive
Arguments
nExp is the numeric expression to be evaluated.
Returns
Abs() returns a number representing the absolute value of its argument. The return value is a positive number or zero.
Description

Abs() is a numeric function that determines the magnitude of a numeric value independent of its sign. It lets you, for example, obtain the difference between two numbers as a positive value without knowing in advance which of the two is larger.

As a formalism, Abs(x) is defined in terms of its argument, x, as follows: if x >= 0, Abs(x) returns x; otherwise, Abs(x) returns the negation of x.

Examples
■  These examples show typical results from Abs():

   nNum1 := 100
   nNum2 := 150
   ? nNum1 - nNum2                  // Result: -50
   ? Abs(nNum1 - nNum2)             // Result: 50
   ? Abs(nNum2 - nNum1)             // Result: 50
   ? Abs(-12)                       // Result: 12
   ? Abs(0)                         // Result: 0
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.

ACCEPT*Harbour implementation | 

Place keyboard input into a memory variable
Syntax
ACCEPT [<expPrompt>] TO <idVar>
Arguments
expPrompt is an optional prompt displayed before the input area. The prompt can be an expression of any data type.
idVar is the variable that will hold input from the keyboard. If the specified idVar does not exist or is not visible, a private variable is created.
Description

ACCEPT is a console command and wait state that takes input from the keyboard and assigns it as a character string to the specified variable. When ACCEPT is executed, it first performs a carriage return/linefeed, displays the prompt, and then begins taking characters from the keyboard at the first character position following the prompt. You may input up to 255 characters. When input reaches the edge of the screen, as defined by MaxCol(), the cursor moves to the next line.

ACCEPT supports only two editing keys: Backspace and Return. Esc is not supported. Backspace deletes the last character typed. Return confirms entry and is the only key that can terminate an ACCEPT. If Return is the only key pressed, ACCEPT assigns a null value ("") to idVar.

Examples
■  This example uses ACCEPT to get keyboard input from the user:

   LOCAL cVar
   ACCEPT "Enter a value: " TO cVar
   IF cVar == ""
      ? "User pressed Return"
   ELSE
      ? "User input:", cVar
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

AChoice()Harbour implementation  | 

Execute a pop-up menu
Syntax
AChoice(<nTop>, <nLeft>, <nBottom>, <nRight>,
   <acMenuItems>,
   [<alSelectableItems> | <lSelectableItems>],
   [<cUserFunction>],
   [<nInitialItem>],
   [<nWindowRow>]) → nPosition
Arguments
nTop, nLeft and nBottom, nRight are the upper- left and lower-right window coordinates. Row values can range from zero to MaxRow() and column values can range from zero to MaxCol().
acMenuItems is an array of character strings to display as the menu items. The individual menu items are later identified by their numeric positions in this array.
alSelectableItems is a parallel array of logical values—one element for each item in acMenuItems—that specify the selectable menu items. Elements can be logical values or character strings. AChoice() will not permit a null string and stops displaying if it encounters one. If the element is a character string, it is evaluated as a macro expression which should evaluate to a logical data type. In either case, a value of false (.F.) means that the corresponding menu item is not available, and a value of true (.T.) means that it is available. If you specify lSelectableItems instead of an array, false (.F.) makes all menu items unavailable and true (.T.) makes all menu items available. By default, all menu items are available for selection.
cUserFunction is the name of a user-defined function that executes when an unrecognizable key is pressed. Specify the function name as a character expression without parentheses or arguments. Note that the behavior of AChoice() is affected by the presence of this argument. Refer to the discussion below for further information.
nInitialItem is the position in the acMenuItems array of the item that will be highlighted when the menu is initially displayed. If you specify an unavailable menu item or no argument at all, the initial menu item is the first selectable item in the array.
nWindowRow is the number of the window row on which the initial menu item will appear. Row numbering begins with zero. By default, the initial menu item appears as close to the top of the window as possible, without leaving any empty rows at the bottom. Thus, if there are enough menu items following the initial one to fill up the window, the initial form will appear on the first row (row zero) of the menu. This function argument is used to control the initial menu appearance when there are more menu items than will fit in the window.
As with all functions, optional arguments are omitted by using a comma instead of the actual argument.
Returns
AChoice() returns the numeric position in the acMenuItems array of the menu item selected. If the selection process is aborted, AChoice() returns zero.
Description

AChoice() is a user interface function that can create various kinds of pop-up menus. Each menu uses an array of character strings as menu items and a parallel array of logical values to determine whether items are selectable. When you invoke AChoice(), the list of menu items is displayed within the specified window coordinates. When the user presses Return, the current item is selected, and AChoice() returns the position of the menu item in acMenuItems. When the user presses Esc, AChoice() aborts and returns zero.

The menu items scroll if the number of items in acMenuItems exceeds the number of rows in the menu window, and the user attempts to move the highlight beyond the top or bottom of the menu window. Note that the highlight does not wrap when you reach the top or bottom of the list of items. Pressing the first letter does, however, wrap the highlight within the set of items whose first letter matches the key you press.

■ Navigating the menu: AChoice() has two modes depending on

whether the cUserFunction argument is specified. If it is not specified the following navigation keys are active:

AChoice() Keys (No User Function)

       Key            Action
       Up arrow       Go to previous item
       Down arrow     Go to next item
       Home           Go to first item in menu
       End            Go to last item in menu
       Ctrl+Home      Go to first item in window
       Ctrl+End       Go to last item in window
       PgUp           Go to previous page
       PgDn           Go to next page
       Ctrl+PgUp      Go to the first item in menu
       Ctrl+PgDn      Go to last item in menu
       Return         Select current item
       Esc            Abort selection
       Left arrow     Abort selection
       Right arrow    Abort selection
       First Letter   Go to next item beginning with first letter

■ Color: Menu items are displayed in standard color, the

highlight in enhanced color, and the unavailable items in the unselected color. For example, the following color statement

SetColor("W+/N, BG+/B, , , W/N")

displays a menu that is bright white on black, the highlight is bright cyan on blue, and the unavailable menu items are dim white on black.

■ User function: Like the other user interface functions,

AChoice() supports a user function. The user function is specified when you want to nest AChoice() invocations to create hierarchical menus or to redefine keys.

When a user function is specified, AChoice() processes only a limited set of keys automatically. These are listed in the following table. All other keys generate a key exception which passes control to the user function for handling. Control is also passed to the user function when AChoice() goes idle (i.e., when there are no more keys to process).

AChoice() Keys (User Function Specified)

       Key          Action
       Uparrow      Go to previous item
       Dnarrow      Go to next item
       Ctrl+Home    Go to first item in window
       Ctrl+End     Go to last item in window
       PgUp         Go to previous page
       PgDn         Go to next page
       Ctrl+PgUp    Go to the first item in menu
       Ctrl+PgDn    Go to last item in menu

When AChoice() executes the user function, it automatically passes the following three parameters:

- The current AChoice() mode

- The current element in the array of items

- The relative row position within the menu window

The mode indicates the current state of AChoice() depending on the key pressed and the action taken by AChoice() prior to executing the user function. The mode parameter has the following possible values:

AChoice() Modes

       Mode    Achoice.ch     Description
       0       AC_IDLE        Idle
       1       AC_HITTOP      Attempt to cursor past top of list
       2       AC_HITBOTTOM   Attempt to cursor past bottom of list
       3       AC_EXCEPT      Keystroke exceptions
       4       AC_NOITEM      No selectable items

After the user function has performed whatever operations are appropriate to the AChoice() mode or LastKey(), it must RETURN a value requesting AChoice() to perform an operation from the following set of actions:

AChoice() User Function Return Values

       Value   Achoice.ch     Action
       0       AC_ABORT       Abort selection
       1       AC_SELECT      Make selection
       2       AC_CONT        Continue AChoice()
       3       AC_GOTO        Go to the next item whose first character
                              matches the key pressed

Examples
■  This example uses two literal arrays to specify the menu items
   and selection criteria.  After the menu is displayed and the user
   makes a selection, the name of the selected menu item is displayed:

   acMenuItems := {"One", "Two", "-------", "Three"}
   alSelectableItems := {.T., .T., .F., .T.}
   nPosition := AChoice(10, 10, 12, 15, acMenuItems,;
                            alSelectableItems)
   ? acMenuItems[nPosition]

■  This example declares an array of menu items and supplies a
   user-defined function which displays a message with each highlighted
   choice:

   #include "achoice.ch"
   #include "inkey.ch"

   PROCEDURE Main()

      LOCAL acMenuItems[4], cUserFunction, nRetVal
      LOCAL nKey, nPos

      acMenuItems[1] := "Add"
      acMenuItems[2] := "Edit"
      acMenuItems[3] := "Delete"
      acMenuItems[4] := "Update"

      CLS

      nPos := AChoice( 10, 10, 13, 15, acMenuItems,;
                     .T., "cUserFunction" )
      DO CASE
      CASE nPos == 1
         //  Put ADD routine here
      CASE nPos == 2
         //  Put EDIT routine here
      CASE nPos == 3
         //  Put DELETE routine here
      CASE nPos ==4
         //  Put UPDATE routine here
      ENDCASE

   RETURN


   FUNCTION cUserFunction( nMode, nCurElement, nRowPos )

      LOCAL nRetVal := AC_CONT     // Default, Continue
      LOCAL nKey := LastKey()

      DO CASE
   // After all pending keys are processed, display message
      CASE nMode == AC_IDLE
      DO CASE
         CASE nCurElement == 1
            @ 22, 5 SAY " Adding   "
         CASE nCurElement == 2
            @ 22, 5 SAY " Editing  "
         CASE nCurElement ==  3
            @ 22, 5 SAY " Deleting "
         CASE nCurElement ==  4
            @ 22, 5 SAY " Updating "
      ENDCASE

         nRetVal := AC_CONT            // Continue AChoice()

      CASE nMode == AC_HITTOP          // Attempt to go past Top
         Tone( 100, 3 )
      CASE nMode == AC_HITBOTTOM       // Attempt to go past
                                       // Bottom
         Tone( 100, 3 )

      CASE nMode == AC_EXCEPT          // Key Exception
         DO CASE
         CASE nKey == K_RETURN         // If RETURN key, select
            nRetVal := AC_SELECT
         CASE nKey == K_ESC            // If ESCAPE key, abort
            nRetVal := AC_ABORT
         OTHERWISE
               nRetVal := AC_GOTO      // Otherwise, go to item
         ENDCASE
      ENDCASE

   RETURN nRetVal

■  The next example declares the arrays, specifies a selection
   condition for one of the menu items, and supplies a user function:

   EXTERNAL Updated
   //
   FUNCTION MyMenu
      LOCAL acMenuItems[4], alSelectableItems[4],;
             cUserFunction := "DoIt"
      //
      acMenuItems[1] := "Add Record"
      acMenuItems[2] := "Edit Record"
      acMenuItems[3] := "Delete Record"
      acMenuItems[4] := "Update Record"
      //
      alSelectableItems[1] := .T.
      alSelectableItems[2] := .T.
      alSelectableItems[3] := .T.
      alSelectableItems[4] := "!Updated()"
      // Selection condition

      RETURN AChoice(10, 10, 12, 15, acMenuItems,;
         alSelectableItems, cUserFunction)

■  This example uses two arrays to specify menu items and
   corresponding action blocks.  After the menu is displayed and the
   user makes a selection, the AChoice() return value is used to
   determine which action block of the aActionItems array is evaluated:

   PROCEDURE Main()
      LOCAL nChoice
      LOCAL aMenuItems := { "Add Record   ", ;
                               "Edit Record  ", ;
                               "Delete Record", ;
                               "Update Record"   }

      LOCAL aActionItems := { {|| AddFunc()  }, ;
                               {|| EditFunc() }, ;
                               {|| DelFunc()  }, ;
                               {|| UpdFunc()  }  }

      nChoice := AChoice( 10, 10, 13, 22, aMenuItems )

      IF nChoice == 0
         QUIT      // ESCAPE was pressed
      ENDIF

      Eval( aActionItems[nChoice] )

   RETURN
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, header files are achoice.ch and inkey.ch.
See also

AClone()Harbour implementation  | 

Duplicate a nested or multidimensional array
Syntax
AClone(<aSource>) → aDuplicate
Arguments
aSource is the array to be duplicated.
Returns
AClone() returns a duplicate of aSource.
Description
AClone() is an array function that creates a complete duplicate of the aSource array. If aSource contains subarrays, AClone() creates matching subarrays and fills them with copies of the values in the aSource subarrays. AClone() is similar to ACopy(), but ACopy() does not duplicate nested arrays.
Examples
■  This example creates an array then duplicates it using
   AClone().  The first array is then altered, but the duplicate copy is
   unaffected:

   LOCAL aOne, aTwo
   aOne := { 1, 2, 3 }         // Result: aOne is {1, 2, 3}
   aTwo := AClone(aOne)        // Result: aTwo is {1, 2, 3}
   aOne[1] := 99               // Result: aOne is {99, 2, 3}
                              // aTwo is still {1, 2, 3}
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ACopy()Harbour implementation  | 

Copy elements from one array to another
Syntax
ACopy(<aSource>, <aTarget>,
   [<nStart>], [<nCount>], [<nTargetPos>]) → aTarget
Arguments
aSource is the array to copy elements from.
aTarget is the array to copy elements to.
nStart is the starting element position in the aSource array. If not specified, the default value is one.
nCount is the number of elements to copy from the aSource array beginning at the nStart position. If nCount is not specified, all elements in aSource beginning with the starting element are copied.
nTargetPos is the starting element position in the aTarget array to receive elements from aSource. If not specified, the default value is one.
Returns
ACopy() returns a reference to the target array, aTarget.
Description

ACopy() is an array function that copies elements from the aSource array to the aTarget array. The aTarget array must already exist and be large enough to hold the copied elements. If the aSource array has more elements, some elements will not be copied.

ACopy() copies values of all data types including NIL and code blocks. If an element of the aSource array is a subarray, the corresponding element in the aTarget array will contain a reference to the subarray. Thus, ACopy() will not create a complete duplicate of a multidimensional array. To do this, use the AClone() function.

Examples
■  This example creates two arrays, each filled with a value.
   The first two elements from the source array are then copied into the
   target array:

   LOCAL nCount := 2, nStart := 1, aOne, aTwo
   aOne := { 1, 1, 1 }
   aTwo := { 2, 2, 2 }
   ACopy(aOne, aTwo, nStart, nCount)
   // Result: aTwo is now { 1, 1, 2 }
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ADel()Harbour implementation  | 

Delete an array element
Syntax
ADel(<aTarget>, <nPosition>) → aTarget
Arguments
aTarget is the array to delete an element from.
nPosition is the position of the target array element to be deleted.
Returns
ADel() returns a reference to the target array, aTarget.
Description

ADel() is an array function that deletes an element from an array. The contents of the specified array element is lost, and all elements from that position to the end of the array are shifted up one element. The last element in the array becomes NIL.

Warning! CA-Clipper implements multidimensional arrays by nesting arrays within other arrays. If the aTarget array is a multidimensional array, ADel() can delete an entire subarray specified by nPosition, causing aTarget to describe an array with a different structure than the original.

Examples
■  This example creates a constant array of three elements, and
   then deletes the second element.  The third element is moved up one
   position, and the new third element is assigned a NIL:

   LOCAL aArray
   aArray := { 1, 2, 3 }      // Result: aArray is
                              // now { 1, 2, 3 }
   ADel(aArray, 2)            // Result: aArray is
                              // now { 1, 3, NIL }
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ADir()*Harbour implementation  | 

Fill a series of arrays with directory information
Syntax
ADir([<cFilespec>],
   [<aFilenames>],
   [<aSizes>],
   [<aDates>],
   [<aTimes>],
   [<aAttributes>]) → nFiles
Arguments
cFilespec is the path specification of files to include in the scan of the DEFAULT directory. It is a standard file specification that can include the wildcard characters * and ?, as well as a drive and path reference. If omitted, the default specification is *.*.
aFilenames is the array to fill with the file names matching cFilespec. Each element contains the file name and extension as a character string in all uppercase letters.
aSizes is the array to fill with the sizes of the corresponding files in the aFilenames array. Each element is a numeric data type.
aDates is the array to fill with the dates of the corresponding files in the aFilenames array. Each element is a date data type.
aTimes is the array to fill with the times of the corresponding files in the aFilenames array. Each element filled contains a character string of the form: hh:mm:ss.
aAttributes is the array to fill with attributes of the corresponding files in the aFilenames array. Each element is a character string. If aAttributes is specified, hidden, system, and directory files are included as well as normal files. If aAttributes is not specified, only normal files are included.
Returns
ADir() returns the number of files matching the directory skeleton described in cFilespec.
Description

ADir() is an array function that performs two basic operations. First, it returns the number of files matching the file specification. Second, it fills a series of arrays with file names, sizes, dates, times, and attributes.

ADir() is a compatibility function and therefore not recommended. It is superseded by the Directory() function which returns all file information in a multidimensional array.

Notes

■ Directories: If you specify the aAttributes argument and

cFilespec is *.*, directories will be included in aFilenames. In the aAttributes array, directories are indicated with an attribute value of "D". If ADir() is executed within a subdirectory, the first two entries of the aFilenames array are "." and "..", the parent and current directory aliases. The date and time of last update are reported for directories, but the size of a directory is always zero.

Examples
■  This example creates an array to hold the names of all .txt
   files in the current DEFAULT directory, then uses AEval() to list
   them to the console:

   LOCAL aFiles[ADir("*.TXT")]
   ADir("*.TXT", aFiles)
   AEval(aFiles, { |element| QOut(element) })
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

AEval()Harbour implementation  | 

Execute a code block for each element in an array
Syntax
AEval(<aArray>, <bBlock>,
   [<nStart>], [<nCount>]) → aArray
Arguments
aArray is the array to traverse.
bBlock is a code block to execute for each element encountered.
nStart is the starting element. If not specified, the default is element one.
nCount is the number of elements to process from nStart. If not specified, the default is all elements to the end of the array.
Returns
AEval() returns a reference to aArray.
Description

AEval() is an array function that evaluates a code block once for each element of an array, passing the element value and the element index as block parameters. The return value of the block is ignored. All elements in aArray are processed unless either the nStart or the nCount argument is specified.

AEval() makes no assumptions about the contents of the array elements it is passing to the block. It is assumed that the supplied block knows what type of data will be in each element.

AEval() is similar to dbEval() which applies a block to each record of a database file. Like dbEval(), AEval() can be used as a primitive for the construction of iteration commands for both simple and complex array structures.

Refer to the Code Blocks section in the "Basic Concepts" chapter of the Programming and Utilities Guide for more information on the theory and syntax of code blocks.

Examples
■  This example uses AEval() to display an array of file names
   and file sizes returned from the Directory() function:

   #include "Directry.ch"
   //
   LOCAL aFiles := Directory("*.dbf"), nTotal := 0
   AEval(aFiles,;
      { | aDbfFile |;
         QOut(PadR(aDbfFile[F_NAME], 10), aDbfFile[F_SIZE]),;
         nTotal += aDbfFile[F_SIZE]);
      } )
   //
   ?
   ? "Total Bytes:", nTotal

■  This example uses AEval() to build a list consisting of
   selected items from a multidimensional array:

   #include "Directry.ch"
   //
   LOCAL aFiles := Directory("*.dbf"), aNames := {}
   AEval(aFiles,;
      { | file | AAdd(aNames, file[F_NAME]) };
      )

■  This example changes the contents of the array element
   depending on a condition.  Notice the use of the codeblock
   parameters:

   LOCAL aArray[6]
   AFill(aArray,"old")
   AEval(aArray,;
   {|cValue,nIndex| IF(cValue == "old",;
                     aArray[nIndex] := "new",)})
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

AFields()*Harbour implementation  | 

Fill arrays with the structure of the current database file
Syntax
AFields([<aFieldNames>], [<aTypes>],
   [<aWidths>], [<aDecimals>]) → nFields
Arguments
aFieldNames is the array to fill with field names. Each element is a character string.
aTypes is the array to fill with the type of fields in aFieldNames. Each element is a character string.
aWidths is the array to fill with the widths of fields in aFieldNames. Each element is numeric data type.
aDecimals is the array to fill with the number of decimals defined for fields in aFieldNames. Each element is numeric data type. If the field type is not numeric, the aDecimals element is zero.
Returns
AFields() returns the number of fields or the length of the shortest array argument, whichever is less. If no arguments are specified, or if there is no file in USE in the current work area, AFields() returns zero.
Description

AFields() is an array function that fills a series of arrays (structure attribute arrays) with the structure of the database file currently open, one element in each array per field. AFields() works like ADir(), filling a series of existing arrays with information. To use AFields(), you must first create the arrays to hold the database structure information, each with the same number of elements as the number of fields (i.e. FCount()). Once the structure attribute arrays are created, you can then invoke AFields() to fill the structure arrays with information about each field.

By default, AFields() operates on the currently selected work area. It can operate on an unselected work area if you specify it within an aliased expression (see example below).

AFields() is a compatibility function and therefore is not recommended. It is superseded by dbStruct(), which does not require the existence of any arrays prior to invocation and returns a multidimensional array containing the current database file structure.

Examples
■  This example demonstrates how AFields() and AChoice() can be
   used together to create a fields picklist:

   USE Sales NEW
   PRIVATE aFieldNames[FCount()]
   AFields(aFieldNames)
   @ 1, 0 TO 10, 10 DOUBLE
   nChoice := AChoice(2, 1, 9, 9, aFieldNames)
   @ 12, 0 SAY IF(nChoice != 0, aFieldNames[nChoice],;
                   "None selected")
   RETURN

■  This example uses AFields() with an aliased expression to fill
   arrays with the structure of Sales.dbf, open in an unselected work
   area:

   LOCAL aFieldNames, aTypes, aWidths, aDecimals
   USE Sales NEW
   USE Customer NEW
   //
   aFieldNames := Sales->(Array(FCount()))
   aTypes := Sales->(Array(FCount()))
   aWidths := Sales->(Array(FCount()))
   aDecimals := Sales->(Array(FCount()))
   //
   Sales->(AFields(aFieldNames, aTypes, ;
            aWidths, aDecimals))
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

AFill()Harbour implementation  | 

Fill an array with a specified value
Syntax
AFill(<aTarget>, <expValue>,
   [<nStart>], [<nCount>]) → aTarget
Arguments
aTarget is the array to be filled.
expValue is the value to be placed in each array element. It can be an expression of any valid data type.
nStart is the position of the first element to be filled. If this argument is omitted, the default value is one.
nCount is the number of elements to be filled starting with element nStart. If this argument is omitted, elements are filled from the starting element position to the end of the array.
Returns
AFill() returns a reference to aTarget.
Description

AFill() is an array function that fills the specified array with a single value of any data type (including an array, code block, or NIL) by assigning expValue to each array element in the specified range.

Warning! AFill() cannot be used to fill multidimensional arrays. CA-Clipper implements multidimensional arrays by nesting arrays within other arrays. Using AFill() with a multidimensional array will overwrite subarrays used for the other dimensions of the array.

Examples
■  This example, creates a three-element array.  The array is
   then filled with the logical value, (.F.).  Finally, elements in
   positions two and three are assigned the new value of true (.T.):

   LOCAL aLogic[3]
   // Result: aLogic is { NIL, NIL, NIL }

   AFill(aLogic, .F.)
   // Result: aLogic is { .F., .F., .F. }

   AFill(aLogic, .T., 2, 2)
   // Result: aLogic is { .F., .T., .T. }
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

AIns()Harbour implementation  | 

Insert a NIL element into an array
Syntax
AIns(<aTarget>, <nPosition>) → aTarget
Arguments
aTarget is the array into which a new element will be inserted.
nPosition is the position at which the new element will be inserted.
Returns
AIns() returns a reference to the target array, aTarget.
Description

AIns() is an array function that inserts a new element into a specified array. The newly inserted element is NIL data type until a new value is assigned to it. After the insertion, the last element in the array is discarded, and all elements after the new element are shifted down one position.

Warning! AIns() must be used carefully with multidimensional arrays. Multidimensional arrays in CA-Clipper are implemented by nesting arrays within other arrays. Using AIns() in a multidimensional array discards the last element in the specified target array which, if it is an array element, will cause one or more dimensions to be lost. To insert a new dimension into an array, first add a new element to the end of the array using AAdd() or ASize() before using AIns().

Examples
■  This example demonstrates the effect of using AIns() on an
   array:

   LOCAL aArray
   aArray := { 1, 2, 3 }      // Result: aArray is
                              // now { 1, 2, 3 }
   AIns(aArray, 2)            // Result: aArray is
                              // now { 1, NIL, 2 }
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Alert()Harbour implementation  | 

Display a simple modal dialog box
Syntax
Alert( <cMessage>, [<aOptions>] ) → nChoice
Arguments
cMessage is the message text displayed and centered in the alert box. If the message contains one or more semicolons, the text after the semicolons is centered on succeeding lines in the dialog box.
aOptions defines a list of up to 4 possible responses to the dialog box.
Returns
Alert() returns a numeric value indicating which option was chosen. If the Esc key is pressed, the value returned is zero.
Description

The Alert() function creates a simple modal dialog. It is useful in error handlers and other "pause" functions. The user can respond by moving a highlight bar and pressing the Return or SpaceBar keys, or by pressing the key corresponding to the first letter of the option. If aOptions is not supplied, a single "Ok" option is presented.

Alert() is sensitive to the presence or absence of the CA-Clipper full-screen I/O system. If the full-screen system is not present, Alert() uses standard I/O to display the message and options tty-style (i.e., 80-column, without word wrap, each line ended with carriage return/linefeed).

Examples
■  This example demonstrates use of an alert dialog box.  First,
   the array of options is defined, the Alert() function gets the user's
   selection, and finally, the user's choice is handled with a DO
   CASE...ENDCASE control structure:

   #define AL_SAVE         1
   #define AL_CANCEL      2
   #define AL_CONT         3

   // Define an array of options
   aOptions := {"Save", "Don't Save", "Continue"}

   // Display the dialog box and get the user's selection
   nChoice  := Alert("File has changed...", aOptions)

   // Handle the user's request
   DO CASE
   CASE nChoice == AL_SAVE
      ? "Save"
   CASE nChoice == AL_CANCEL
      ? "Don't Save"
   CASE nChoice == AL_CONT
      ? "Continue"
   OTHERWISE
      ? "Escape"
   ENDCASE
   //
   RETURN
Platforms
Available on MS-DOS
File
Library is LLIBG.LIB.
See also

Alias()Harbour implementation  | 

Return a specified work area alias
Syntax
Alias([<nWorkArea>]) → cAlias
Arguments
nWorkArea is any work area number.
Returns
Alias() returns the alias of the specified work area as a character string in uppercase. If nWorkArea is not specified, the alias of the current work area is returned. If there is no database file in USE for the specified work area, Alias() returns a null string ("").
Description

Alias() is a database function that determines the alias of a specified work area. An alias is the name assigned to a work area when a database file is USEd. The actual name assigned is either the name of the database file, or a name explicitly assigned with the ALIAS clause of the USE command.

Alias() is the inverse of the Select() function. Alias() returns the alias name given the work area number, and Select() returns the work area number given the alias name.

■ This example returns the name of the previously selected work

area:

USE File1 NEW ALIAS Test1 nOldArea := Select() USE File2 NEW ALIAS Test2 ? Alias( nOldArea ) // Returns Test1

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

AllTrim()Harbour implementation  | 

Remove leading and trailing spaces from a character string
Syntax
AllTrim(<cString>) → cTrimString
Arguments
cString is the character expression to be trimmed.
Returns
AllTrim() returns a character string with leading and trailing spaces removed.
Description
AllTrim() is a character function that removes both leading and trailing spaces from a string. It is related to LTrim() and RTrim() which remove leading and trailing spaces, respectively. The inverse of AllTrim(), LTrim(), and RTrim() are the PadC(), PadL(), and PadR() functions which center, left-justify, or right-justify character strings by padding them with fill characters.
Notes

■ Space characters: The AllTrim() function treats carriage

returns, line feeds, and tabs as space characters and removes these as well.

Examples
■  This example creates a string with both leading and trailing
   spaces, and then trims them with AllTrim():

   cString := Space(10) + "string" + Space(10)
   ? Len(cString)                     // Result: 26
   ? Len(AllTrim(cString))            // Result: 6
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

AltD()Harbour implementation  | 

Invoke the CA-Clipper debugger
Syntax
AltD([<nAction>]) → NIL
Arguments
nAction defines what action AltD() performs when invoked. The following is a complete list of nAction values and their actions:
AltD() Actions
    Argument     Action
    None         Invokes the debugger if it is enabled
    0            Disables Alt+D
    1            Enables Alt+D
    Other        No action
Returns
AltD() always returns NIL.
Description
AltD() performs differently depending on its argument as shown in the table above. For more information on using the debugger, refer to "CA-Clipper Debugger-CLD.LIB" chapter in the Programming and Utilities Guide. Also refer to the "Debugging Your Applications" chapter in the Workbench User Guide.
Examples
■  This example demonstrates a series of manifest constants that
   can be used as arguments for AltD() before invoking the debugger
   programmatically:

   #define ALTD_DISABLE      0
   #define ALTD_ENABLE      1
   //
   AltD(ALTD_ENABLE)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ANNOUNCE | 

Declare a module identifier
Syntax
ANNOUNCE <idModule>
Arguments
idModule is a module identifier name.
Description

ANNOUNCE is a declaration statement that defines a module identifier. A linker may use this identifier later to satisfy pending module REQUESTs. ANNOUNCE and REQUEST provide a mechanism for managing application modules (.prg files).

Specify ANNOUNCE statements prior to any executable statements in a program file. A source (.prg) file can only have one module identifier; all subsequent ANNOUNCE declarations produce a compiler warning and will be ignored. Module identifiers must be unique and should not duplicate the name of any procedures or user-defined functions in a source (.prg) file.

Examples
■  This example illustrates the ANNOUNCE declaration:

   ANNOUNCE CustomInit

   INIT PROCEDURE MyInit
      ? "Hypothetical Industries, Inc."
      RETURN

   The above program module, CustomInit, should be compiled with the /N
   option.  Subsequently, the program is addressed in the source code of
   another program module through use of the REQUEST statement,

   REQUEST CustomInit

   which causes the module CustomInit to be linked into the resultant
   executable (.EXE) file.
Platforms
Available on MS-DOS
See also

APPEND BLANKHarbour implementation | 

Add a new record to the current database file
Syntax
APPEND BLANK
Description

APPEND BLANK is a database command that adds a new record to the end of the current database file and then makes it the current record. The new field values are initialized to the empty values for each data type: character fields are assigned with spaces; numeric fields are assigned zero; logical fields are assigned false (.F.); date fields are assigned CToD(""); and memo fields are left empty.

If operating under a network with the current database file shared, APPEND BLANK attempts to add and then lock a new record. If another user has locked the database file with FLock() or locked LastRec() + 1 with RLock(), NetErr() returns true (.T.). Note that a newly APPENDed record remains locked until you lock another record or perform an UNLOCK. APPEND BLANK does not release an FLock() set by the current user.

Examples
■  This example attempts to add a record to a shared database
   file and uses NetErr() to test whether the operation succeeded:

   USE Sales SHARED NEW
   .
   . <statements>
   .
   APPEND BLANK
   IF !NetErr()
      <update empty record>...
   ELSE
      ? "Append operation failed"
      BREAK
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

APPEND FROMHarbour implementation | 

Import records from a database (.dbf) file or ASCII text file
Syntax
APPEND FROM <xcFile>
   [FIELDS <idField list>]
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
   [SDF | DELIMITED [WITH BLANK | <xcDelimiter>] |
   [VIA <xcDriver>]]
Arguments
FROM xcFile specifies the name of the source file. You can specify xcFile either as a literal file name or as a character expression enclosed in parentheses. If a file extension is not specified, .dbf is the default input file type. If SDF or DELIMITED is specified, the file extension is assumed to be .txt unless otherwise specified.
FIELDS idField list specifies the list of fields to copy from xcFile. The default is all fields.
scope is the portion of the source database file to APPEND FROM. NEXT n APPENDs the first n records. RECORD n APPENDs only record number n from xcFile. The default scope is ALL records in xcFile.
WHILE lCondition specifies the set of records meeting the condition from the first record in the source file until the condition fails.
FOR lCondition specifies the conditional set of records to APPEND FROM within the given scope.
SDF identifies a System Data Format ASCII file. Records and fields are fixed length.
DELIMITED identifies an ASCII text file where character fields are enclosed in double quotation marks (the default delimiter). Note that delimiters are not required and CA-Clipper correctly APPENDs character fields not enclosed in them. Fields and records are variable length.
DELIMITED WITH BLANK identifies an ASCII text file in which fields are separated by one space and character fields are not enclosed in delimiters.
DELIMITED WITH xcDelimiter identifies a delimited ASCII text file where character fields are enclosed using the specified delimiter. You can specify xcDelimiter as a literal character or as a character expression enclosed in parentheses.
See the tables below for more information regarding the format specification requirements for ASCII text files that you want to APPEND using these arguments.
VIA xcDriver specifies the replaceable database driver (RDD) to use to import the desired data. cDriver is the name of the RDD specified as a character expression. If cDriver is specified as a literal value, it must be enclosed in quotes.
If the VIA clause is omitted, APPEND FROM uses the driver in the current work area. If you specify the VIA clause, you must REQUEST the appropriate RDDs to be linked into the application.
Warning! If the DELIMITED WITH clause is specified on a COPY TO or APPEND FROM command line, it must be the last clause specified.
Description

APPEND FROM adds records to the current database file from an ASCII text file or another database file. Only fields with the same names and types are APPENDed. Fields with the same name from both the current database file and xcFile must be the same data type. If they are not, a runtime error occurs when the APPEND FROM command is invoked.

Any date information in xcFile must be in the format yyyymmdd to be properly APPENDed.

In a network environment, APPEND FROM does not require that the current database file be USEed EXCLUSIVEly or locked with FLock() to perform its operation. As each record is added, CA-Clipper automatically arbitrates contention for the new record.

When you invoke APPEND FROM, CA-Clipper attempts to open xcFile as shared and read-only. If access is denied, APPEND FROM terminates with a runtime error. Refer to the "Network Programming" chapter in the Programming and Utilities Guide for more information. No error is raised if you attempt to open a .dbf file that is already open.

This table shows the format specifications for SDF text files:

SDF Text File Format Specifications

    File Element        Format
    Character fields    Padded with trailing blanks
    Date fields         yyyymmdd
    Logical fields      T or F
    Memo fields         Ignored
    Numeric fields      Padded with leading blanks or zeros
    Field separator     None
    Record separator    Carriage return/linefeed
    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED and DELIMITED WITH xcDelimiter ASCII text files:

DELIMITED Text File Format Specifications

    File Element        Format
    Character fields    May be delimited, with trailing blanks truncated
    Date fields         yyyymmdd
    Logical fields      T or F
    Memo fields         Ignored
    Numeric fields      Leading zeros may be truncated
    Field separator     Comma
    Record separator    Carriage return/linefeed
    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED WITH BLANK ASCII text files:

DELIMITED WITH BLANK Text File Format Specifications

    File Element        Format
    Character fields    Not delimited, trailing blanks may be truncated
    Date fields         yyyymmdd
    Logical fields      T or F
    Memo fields         Ignored
    Numeric fields      Leading zeros may be truncated
    Field separator     Single blank space
    Record separator    Carriage return/linefeed
    End of file marker  1A hex or Chr(26)

Notes

■ Deleted records: If DELETED is OFF, deleted records in

xcFile are APPENDed to the current database file and retain their deleted status. If DELETED is ON, however, none of the deleted xcFile records are APPENDed.

■ Unmatched field widths: If a field in the current database

file is a character type and has a field length greater than the incoming xcFile data, CA-Clipper pads the xcFile data with blanks. If the current field is a character data type and its field length is less than the incoming xcFile data, the xcFile data is truncated to fit. If the current field is a numeric type and the incoming xcFile data has more digits than the current field length, a runtime error occurs.

Examples
■  This example demonstrates an APPEND FROM command using a
   fields list and a FOR condition:

   USE Sales NEW
   APPEND FROM BranchFile FIELDS Branch, Salesman, Amount;
      FOR Branch = 100

■  This example demonstrates how a <scope> can be specified to
   import a particular record from another database file:

   APPEND RECORD 5 FROM Temp
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Array()Harbour implementation  | 

Create an uninitialized array of specified length
Syntax
Array(<nElements> [, <nElements>...]) aArray
Arguments
nElements is the number of elements in the specified dimension. The maximum number of elements in a dimension is 4096. Arrays in CA-Clipper can have an unlimited number of dimensions.
Returns
Array() returns an array of specified dimensions.
Description

Array() is an array function that returns an uninitialized array with the specified number of elements and dimensions. If more than one nElements argument is specified, a multidimensional array is created with the number of dimensions equal to the number of nElements arguments specified. Any nElements that is itself an array creates a nested array.

In CA-Clipper, there are several ways to create an array. You can declare an array using a declaration statement such as LOCAL or STATIC; you can create an array using a PRIVATE or PUBLIC statement; you can assign a literal array to an existing variable; or you can use the Array() function. Array() has the advantage that it can create arrays within expressions or code blocks.

Examples
■  This example creates a one-dimensional array of five elements
   using the Array() function, and then shows the equivalent action by
   assigning a literal array of NIL values:

   aArray := Array(5)
   aArray := { NIL, NIL, NIL, NIL, NIL }

■  This example shows three different statements which create the
   same multidimensional array:

   aArray := Array(3, 2)
   aArray := { {NIL, NIL}, {NIL, NIL}, {NIL, NIL} }
   aArray := { Array(2), Array(2), Array(2) }

■  This example creates a nested, multidimensional array:

   aArray := Array(3, {NIL,NIL})
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Asc()Harbour implementation  | 

Convert a character to its ASCII value
Syntax
Asc(<cExp>) → nCode
Arguments
cExp is the character expression to be converted to a number.
Returns
Asc() returns an integer numeric value in the range of zero to 255, representing the ASCII value of cExp.
Description
Asc() is a character conversion function that returns the ASCII value of the leftmost character in a character string. Asc() is used primarily on expressions requiring numeric calculations on the ASCII value of a character. Chr() and Asc() are inverse functions.
Examples
■  These examples illustrate various results of Asc():

   ? Asc("A")                     // Result: 65
   ? Asc("Apple")                 // Result: 65
   ? Asc("a")                     // Result: 97
   ? Asc("Z") - Asc("A")          // Result: 25
   ? Asc("")                      // Result: 0
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

AScan()Harbour implementation  | 

Scan an array for a value or until a block returns true (.T.)
Syntax
AScan(<aTarget>, <expSearch>,
   [<nStart>], [<nCount>]) → nStoppedAt
Arguments
aTarget is the array to be scanned.
expSearch is either a simple value to scan for, or a code block. If expSearch is a simple value it can be character, date, logical, or numeric type.
nStart is the starting element of the scan. If this argument is not specified, the default starting position is one.
nCount is the number of elements to scan from the starting position. If this argument is not specified, all elements from the starting element to the end of the array are scanned.
Returns
AScan() returns a numeric value representing the array position of the last element scanned. If expSearch is a simple value, AScan() returns the position of the first matching element, or zero if a match is not found. If expSearch is a code block, AScan() returns the position of the element where the block returned true (.T.).
Description

AScan() is an array function that scans an array for a specified value and operates like SEEK when searching for a simple value. The expSearch value is compared to the target array element beginning with the leftmost character in the target element and proceeding until there are no more characters left in expSearch. If there is no match, AScan() proceeds to the next element in the array.

Since AScan() uses the equal operator (=) for comparisons, it is sensitive to the status of EXACT. If EXACT is ON, the target array element must be exactly equal to the result of expSearch to match.

If the expSearch argument is a code block, AScan() scans the aTarget array executing the block for each element accessed. As each element is encountered, AScan() passes the element's value as an argument to the code block, and then performs an Eval() on the block. The scanning operation stops when the code block returns true (.T.), or AScan() reaches the last element in the array.

Examples
■  This example demonstrates scanning a three-element array using
   simple values and a code block as search criteria.  The code block
   criteria shows how to perform a case-insensitive search:

   aArray := { "Tom", "Mary", "Sue" }
   ? AScan(aArray, "Mary")               // Result: 2
   ? AScan(aArray, "mary")               // Result: 0
   //
   ? AScan(aArray, { |x| Upper(x) ;
         == "MARY" })                    // Result: 2

■  This example demonstrates scanning for multiple instances of a
   search argument after a match is found:

   LOCAL aArray := { "Tom", "Mary", "Sue",;
                      "Mary" }, nStart := 1
   //
   // Get last array element position
   nAtEnd := Len(aArray)
   DO WHILE (nPos := AScan(aArray, "Mary", ;
                nStart)) > 0
      ? nPos, aArray[nPos]
      //
      // Get new starting position and test
      // boundary condition
      IF (nStart := ++nPos) > nAtEnd
         EXIT
      ENDIF
   ENDDO

■  This example scans a two-dimensional array using a code block.
   Note that the parameter aVal in the code block is an array:

   LOCAL aArr:={}
   CLS
   AAdd(aArr,{"one","two"})
   AAdd(aArr,{"three","four"})
   AAdd(aArr,{"five","six"})
   ? AScan(aArr, {|aVal| aVal[2] == "four"})         // Returns 2
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ASize()Harbour implementation  | 

Grow or shrink an array
Syntax
ASize(<aTarget>, <nLength>) → aTarget
Arguments
aTarget is the array to grow or shrink.
nLength is the new size of the array.
Returns
ASize() returns a reference to the target array, aTarget.
Description

ASize() is an array function that changes the actual length of the aTarget array. The array is shortened or lengthened to match the specified length. If the array is shortened, elements at the end of the array are lost. If the array is lengthened, new elements are added to the end of the array and assigned NIL.

ASize() is similar to AAdd() which adds a single new element to the end of an array and optionally assigns a new value at the same time. Note that ASize() is different from AIns() and ADel(), which do not actually change the array's length.

Note: ASize() only supports single-dimensional arrays.

Examples
■  These examples demonstrate adding new elements and deleting
   existing elements:

   aArray := { 1 }          // Result: aArray is { 1 }
   ASize(aArray, 3)         // Result: aArray is { 1, NIL, NIL }
   ASize(aArray, 1)         // Result: aArray is { 1 }
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ASort()Harbour implementation  | 

Sort an array
Syntax
ASort(<aTarget>, [<nStart>],
   [<nCount>], [<bOrder>]) → aTarget
Arguments
aTarget is the array to be sorted.
nStart is the first element of the sort. If not specified, the default starting position is one.
nCount is the number of elements to be sorted. If not specified, all elements in the array beginning with the starting element are sorted.
bOrder is an optional code block used to determine sorting order. If not specified, the default order is ascending.
Returns
ASort() returns a reference to the aTarget array.
Description

ASort() is an array function that sorts all or part of an array containing elements of a single data type. Data types that can be sorted include character, date, logical, and numeric.

If the bOrder argument is not specified, the default order is ascending. Elements with low values are sorted toward the top of the array (first element), while elements with high values are sorted toward the bottom of the array (last element).

If the bOrder block argument is specified, it is used to determine the sorting order. Each time the block is evaluated, two elements from the target array are passed as block parameters. The block must return true (.T.) if the elements are in sorted order. This facility can be used to create a descending or dictionary order sort. See the examples below.

When sorted, character strings are ordered in ASCII sequence; logical values are sorted with false (.F.) as the low value; date values are sorted chronologically; and numeric values are sorted by magnitude.

Notes

ASort() is only guaranteed to produce sorted output (as

defined by the block), not to preserve any existing natural order in the process.

■ Because CA-Clipper implements multidimensional arrays by

nesting subarrays within other arrays, ASort() will not directly sort a multidimensional array. To sort a nested array, you must supply a code block which properly handles the subarrays.

Examples
■  This example creates an array of five unsorted elements, sorts
   the array in ascending order, then sorts the array in descending
   order using a code block:

   aArray := { 3, 5, 1, 2, 4 }
   ASort(aArray)
   // Result: { 1, 2, 3, 4, 5 }

   ASort(aArray,,, { |x, y| x > y })
   // Result: { 5, 4, 3, 2, 1 }


■  This example sorts an array of character strings in ascending
   order, independent of case.  It does this by using a code block that
   converts the elements to uppercase before they are compared:

   aArray := { "Fred", Kate", "ALVIN", "friend" }
   ASort(aArray,,, { |x, y| Upper(x) < Upper(y) })

■  This example sorts a nested array using the second element of
   each subarray:

   aKids := { {"Mary", 14}, {"Joe", 23}, {"Art", 16} }
   aSortKids := ASort(aKids,,, { |x, y| x[2] < y[2] })

   Result:

   { {"Mary", 14}, {"Art", 16}, {"Joe", 23} }
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

At()Harbour implementation  | 

Return the position of a substring within a character string
Syntax
At(<cSearch>, <cTarget>) → nPosition
Arguments
cSearch is the character substring to be searched for.
cTarget is the character string to be searched.
Returns
At() returns the position of the first instance of cSearch within cTarget as an integer numeric value. If cSearch is not found, At() returns zero.
Description
At() is a character function used to determine the position of the first occurrence of a character substring within another string. If you only need to know whether a substring exists within another string, use the $ operator. To find the last instance of a substring within a string, use RAt().
Examples
■  These examples show typical use of At():

   ? At("a", "abcde")                  // Result: 1
   ? At("bcd", "abcde")                // Result: 2
   ? At("a", "bcde")                   // Result: 0

■  This example splits a character string based on the position
   of a comma within the target string:

   cTarget := "Langtree, Lilly"
   ? SubStr(cTarget, 1, At(",", cTarget) - 1)
   // Result: Langtree

   ? SubStr(cTarget, At(",", cTarget) + 2)
   // Result: Lilly
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ATail()Harbour implementation  | 

Return the highest numbered element of an array
Syntax
ATail(<aArray>) → Element
Arguments
aArray is the array.
Returns
ATail() returns either a value or a reference to an array or object. The array is not changed.
Description
ATail() is an array function that returns the highest numbered element of an array. It can be used in applications as shorthand for aArray[Len(aArray)] when you need to obtain the last element of an array.
Examples
■  The following example creates a literal array and returns that
   last element of the array:

   aArray := {"a", "b", "c", "d"}
   ? ATail(aArray)                     // Result: d
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

AVERAGEHarbour implementation | 

Average numeric expressions in the current work area
Syntax
AVERAGE <nExp list> TO <idVar list>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
Arguments
nExp list is a list of the numeric values to AVERAGE for each record processed.
TO idVar list identifies a list of receiving variables which will contain the average results. Variables that either do not exist or are not visible are created as private variables. idVar list must contain the same number of elements as nExp list.
scope defines the portion of the current database file to AVERAGE. The default scope is ALL.
WHILE lCondition specifies the set of records meeting the condition from the current record until the condition fails.
FOR lCondition specifies the conditional set of records to AVERAGE within the given scope.
Description
AVERAGE calculates the average of one or more numeric expressions to variables for a range of records in the current database file. Zero values are counted in the AVERAGE unless explicitly ruled out with a FOR condition.
Examples
■  This example averages a single numeric field using a condition
   to select a subset of records from the database file:

   USE Sales NEW
   AVERAGE Amount TO nAvgAmount FOR Branch = "100"

■  This example finds the average date for a range of dates:

   AVERAGE (SaleDate - CToD("00/00/00")) ;
      TO nAvgDays FOR !Empty(SaleDate)
   dAvgDate := CToD("00/00/00") + nAvgDays
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

BEGIN SEQUENCE | 

Define a sequence of statements for a BREAK
Syntax
BEGIN SEQUENCE
   <statements>...
[BREAK [<exp>]]
   <statements>...
[RECOVER [USING <idVar>]]
   <statements>...
END [SEQUENCE]
Arguments
BREAK exp branches execution to the statement immediately following the nearest RECOVER statement if one is specified or the nearest END SEQUENCE statement. exp is the value returned into the idVar specified in the USING clause of the RECOVER statement.
RECOVER USING idVar defines a recover point in the SEQUENCE construct where control branches after a BREAK statement. If USING idVar clause is specified, idVar receives the value returned by the BREAK statement. In general, this is an error object.
END defines the end point of the SEQUENCE control structure. If no RECOVER statement is specified, control branches to the first statement following the END statement after a BREAK.
Description

BEGIN SEQUENCE...END is a control structure used for exception and runtime error handling. It delimits a block of statements, including invoked procedures and user-defined functions. When a BREAK is encountered anywhere in a block of statements following the BEGIN SEQUENCE statement up to the corresponding RECOVER statement, control branches to the program statement immediately following the RECOVER statement. If a RECOVER statement is not specified, control branches to the statement following the END statement, terminating the SEQUENCE. If control reaches a RECOVER statement without encountering a BREAK, it branches to the statement following the corresponding END.

The RECOVER statement optionally receives a parameter passed by a BREAK statement that is specified with a return value. This is usually an error object, generated and returned by the current error handling block defined by ErrorBlock(). If an error object is returned, it can be sent messages to query information about the error. With this information, a runtime error can be handled within the context of the operation rather than in the current runtime error handler. See the example below.

Within a SEQUENCE construct there are some restrictions on what statements are allowed between the BEGIN SEQUENCE and RECOVER statements. You cannot RETURN, LOOP, or EXIT between a BEGIN SEQUENCE and RECOVER statement. From within the RECOVER statement block, however, you can LOOP, EXIT, BREAK, or RETURN since the SEQUENCE is essentially completed at that point. Using LOOP from within the RECOVER statement block is useful for re-executing the SEQUENCE statement block. See the example below.

SEQUENCE constructs are quite flexible. They can be nested and more than one can be defined in the same procedure or user-defined function. If more than one SEQUENCE construct is specified, each SEQUENCE should delimit one discrete operation.

For more information on error objects, refer to the Error class in this chapter.

Examples
■  This code fragment demonstrates a SEQUENCE construct in which
   the BREAK occurs within the current procedure:

   BEGIN SEQUENCE
      <statements>...
      IF lBreakCond
         BREAK
      ENDIF
   RECOVER
      <recovery statements>...
   END

   <recovery statements>...

■  This example demonstrates an error handler returning an error
   object to the variable specified in the USING clause of the RECOVER
   statement:

       LOCAL objLocal, bLastHandler
       //
       // Save current and set new error handler
       bLastHandler := ErrorBlock({ |objErr| ;
             MyHandler(objErr, .T.) })
       //
       BEGIN SEQUENCE
          .
          . <operation that might fail>
          .
       RECOVER USING objLocal
          //
          // Send messages to objLocal and handle the error
          ? "Error: "
          IF objLocal:genCode != 0
             ?? objLocal:description
          ENDIF
          .
          .
          .
       END
       //
       // Restore previous error handler
       ErrorBlock( bLastHandler )

       FUNCTION MyHandler( objError, lLocalHandler )
          //
          // Handle locally returning the error object
          IF lLocalHandler
             BREAK objError
          ENDIF
          .
          . <other statements to handle the error>
          .
          RETURN NIL

■  This example re-executes a SEQUENCE statement block by LOOPing
   from within the RECOVER statement block:

   DO WHILE .T.
      BEGIN SEQUENCE
         .
         . <operation that may fail>
         .
      RECOVER
         IF PrintRecover()
            LOOP      // Repeat the SEQUENCE statement block
         ENDIF
      END
      EXIT            // Escape from the operation
   ENDDO
Platforms
Available on MS-DOS
See also

Bin2I()Harbour implementation  | 

Convert a 16-bit signed integer to a numeric value
Syntax
Bin2I(<cSignedInt>) → nNumber
Arguments
cSignedInt is a character string in the form of a 16-bit signed integer number—least significant byte first. Only the first two characters are used by the function; all others are ignored.
Returns
Bin2I() returns an integer numeric value.
Description
Bin2I() is a low-level file function that is used with FRead() to convert a two-byte character string formatted as a signed integer to a CA-Clipper numeric data type. This is most useful when you are reading foreign file types and want to read numeric data in its native format.
Examples
■  This example opens a database file using low-level file
   functions and reads the date of last update (bytes 1-3).  The result
   is the same as with LUpdate():

   #include "Fileio.ch"
   //
   nHandle := FOpen("Sales.dbf", FO_READ)
   //
   // Point to byte 1 in the file
   FSeek(nHandle, 1, FS_SET)
   //
   // Read date of last update
   nYear := Bin2I(FReadStr(nHandle, 1) + Chr(0))
   nMonth := Bin2I(FReadStr(nHandle, 1) + Chr(0))
   nDay := Bin2I(FReadStr(nHandle, 1) + Chr(0))
   //
   ? LTrim(Str(nMonth)), LTrim(Str(nDay)), LTrim(Str(nYear))
   FClose(nHandle)
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM
See also

Bin2L()Harbour implementation  | 

Convert a 32-bit signed integer to a numeric value
Syntax
Bin2L(<cSignedInt>) → nNumber
Arguments
cSignedInt is a character string in the form of a 32-bit signed integer number—least significant byte first. Only the first four characters are used by the function; all others are ignored.
Returns
Bin2L() returns an integer numeric value.
Description
Bin2L() is a low-level file function that is used with FRead() to convert a four-byte character string formatted as a signed integer to a CA-Clipper numeric data type. This is most useful when you are reading foreign file types and want to read numeric data in its native format.
Examples
■  This example opens a database file using low-level file
   functions and reads the number of records (bytes 4-7).  The result is
   the same as with LastRec():

   #include "Fileio.ch"
   //
   nHandle := FOpen("Sales.dbf", FO_READ)
   // Note:  Sales.dbf contains 84 records
   //
   // Point to byte 4
   FSeek(nHandle, 4, FS_SET)
   //
   // Read the number of records
   cRecords := Space(4)
   FRead(nHandle, @cRecords, 4)
   //
   ? LTrim(Str(Bin2L(cRecords)))         // Result: 84
   FClose(nHandle)
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM
See also

Bin2W()Harbour implementation  | 

Convert a 16-bit unsigned integer to a numeric value
Syntax
Bin2W(<cUnsignedInt>) → nNumber
Arguments
cUnsignedInt is a character string in the form of a 16-bit unsigned integer number—least significant byte first. Only the first two characters are used by the function; all others are ignored.
Returns
Bin2W() returns an integer numeric value.
Description
Bin2W() is a low-level file function that is used with FRead() to convert a two-byte character string formatted as an unsigned integer to a CA-Clipper numeric data type. This is most useful when you are reading from a binary file and want to read data in its native format.
Examples
■  This example opens a database file using low-level file
   functions and reads the number of bytes per record (bytes 10-11).
   The result is the same as with RecSize():

   #include "Fileio.ch"
   //
   nHandle := FOpen("Sales.dbf", FO_READ)
   // Note:  The length of a record in Sales.dbf is 124
   //
   // Point to byte 10, the first record size byte
   FSeek(nHandle, 10, FS_SET)
   //
   // Read record size
   cRecSize := Space(2)
   FRead(nHandle, @cRecSize, 2)
   //
   ? LTrim(Str(Bin2W(cRecSize)))            // Result: 124
   FClose(nHandle)
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM
See also

BLOBDIRECTEXPORT()  | 

Export the contents of a binary large object (BLOB) pointer to a file
Syntax
BLOBDirectExport(<nPointer>, <cTargetFile>, [<nMode>])
   → lSuccess
Arguments
nPointer is a pointer to the BLOB data. This pointer can be obtained using BLOBDIRECTPUT(), BLOBDIRECTEXPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos).
cTargetFile is the name of the target file where the BLOB data will be written, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.
If cTargetFile does not exist, it is created. If it exists, this function attempts to open the file in exclusive mode and, if successful, the file is written to without warning or error. If access is denied because another process is using the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBDIRECTEXPORT()
nMode is a constant defining the copy mode, as shown in the table below:
Copy Mode Constants
    Constant                 Description
    BLOB_EXPORT_APPEND       Appends to the file
    BLOB_EXPORT_OVERWRITE    Overwrites the file (this is the default)
Returns
BLOBDIRECTEXPORT() returns true (.T.) if successful; otherwise, it returns false (.F.).
Description
By default, BLOBDIRECTEXPORT() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.
Examples
■  This example extracts an array of pointers from the BLOB
   file's root area, then uses one of the pointers to export a picture
   to a file:

   FUNCTION PUTPIX()
      LOCAL cPixFile
      LOCAL nPointer
      LOCAL aBLOBPtrs


      cPixFile := "picture.gif"

      // Customer database with a picture of
      // each customer stored in a field called Pix
      USE Customer NEW VIA "DBFCDX"

      // Assumes that the program previously
      // stored an array of direct BLOB pointers
      // into the root area of the BLOB file.
      // The picture that we want is assumed to
      // be the second array element.
      aBLOBPtrs := BLOBROOTGET()
      nPointer := aBLOBPtrs[2]

      // Export picture pointed to by nPointer to a file
      IF !BLOBDirectExport(nPointer, cPixFile, ;
         BLOB_EXPORT_OVERWRITE)
            Alert("Export of picture " + cPixFile + ";
               failed!")
      ELSE
         // Code for displaying picture would go here
      ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

BLOBDIRECTGET()  | 

Retrieve data stored in a BLOB file without referencing a specific field
Syntax
BLOBDIRECTGET(<nPointer>,   [<nStart>],   [<nCount>])
    → expBLOB
Arguments
nPointer is a pointer to the BLOB data. This pointer can be obtained using BLOBDIRECTPUT(), BLOBDIRECTIMPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos).
nStart is the starting position in nPointer. If nStart is positive, the starting position is relative to the leftmost character in nPointer. If nStart is negative, it is relative to the rightmost character in nPointer. If nStart is omitted, it is assumed to be 1.
nCount is the number of bytes of data to retrieve beginning at nStart. If nCount is larger than the amount of data stored, excess data is ignored. If omitted, BLOBDIRECTGET() retrieves to the end of the data.
Note: nStart and nCount apply to string data only. They are ignored for any other data types.
Returns
BLOBDIRECTGET() returns the data retrieved from the BLOB file. The data type of the return value depends on the actual data stored. Use ValType() to determine the data type.
Description

BLOBDIRECTGET() retrieves data stored in a BLOB file without the need to reference a particular field in the database file. It is particularly useful when accessing data that is larger than 64 KB (such as memo fields created with the BLOBIMPORT() function).

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples
■  This example illustrates storing setup information in a BLOB
   file, then selectively retrieving the stored information:

   FUNCTION PutSettings(aColors,;
                  aPaths, ;
                  aPassWords)

      LOCAL aSettings

      RDDSETDEFAULT ( "DBFCDX" )
      MEMOSETSUPER ( "DBFCDX" )

      USE Setup NEW via "DBFMEMO"

      aSettings := {}
      AAdd(aSettings, BLOBDIRECTPUT(0, aColors))
      AAdd(aSettings, BLOBDIRECTPUT(0, aPaths))
      AAdd(aSettings, BLOBDIRECTPUT(0, aPassWords))

      BLOBROOTPUT(aSettings)

      CLOSE

   FUNCTION GETCOLORS()
      LOCAL aSettings
      LOCAL aColors

      USE Setup NEW VIA "DBFMEMO"

      aSettings := BLOBROOTGET()
      aColors := BLOBDIRECTGET(aSettings[1])

      CLOSE


      RETURN aColors
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

BLOBDIRECTIMPORT()  | 

Import a file into a BLOB file and return a pointer to the data
Syntax
BLOBDIRECTIMPORT(<nOldPointer>, <cSourceFile>)
    → nNewPointer
Arguments
nOldPointer is a pointer to the BLOB data which will be released after the import. This pointer can be obtained using BLOBDIRECTPUT(), BLOBDIRECTIMPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos). Passing zero (0) disables the release of data.
Important! If specified, BLOBDIRECTIMPORT() releases the space associated with nOldPointer for reuse by other data. Therefore, it is illegal to use nOldPointer with any of the BLOB functions after passing it as an argument to this function. Use the function's return value to refer to the newly stored data.
cSourceFile is the name of the file from which to read the BLOB data, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.
This function attempts to open cSourceFile in shared mode. If the file does not exist, a runtime error is raised. If the file is successfully opened, the operation proceeds. If access is denied because another process has exclusive use of the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBDIRECTIMPORT()
Note: There are no restrictions on the size of cSourceFile except that you must have enough disk space to make the copy.
Returns
BLOBDIRECTIMPORT() returns a numeric pointer to the BLOB image stored in cSourceFile.
Description

BLOBDIRECTIMPORT() provides a mechanism for copying the contents of a file into a BLOB file. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

BLOBDIRECTIMPORT() is used in conjunction with BLOBDIRECTEXPORT() to transfer data back and forth between external files and BLOB files. You can use BLOBDIRECTIMPORT() with a variety of file types, including graphic images, word processor files, and printer fonts. These two functions are excellent for creating databases for documents, graphics, sounds, etc.

Important! After importing a file with BLOBDIRECTIMPORT(), nNewPointer, the return value, is the only way to access the data from the BLOB file. It is up to you to provide permanent storage for this reference (see example below).

Note: dbFieldInfo(DBS_BLOB_TYPE, nFieldPos) will return "C" (string) for any memo field created using BLOBDIRECTIMPORT().

Examples
■  This example imports a bitmap (.bmp) file to be part of an
   array of startup data.  The data, stored in the root area of the BLOB
   file, could then be used to display the application's startup screen:

   FUNCTION PUTPIX()
      LOCAL cBMPFile
      LOCAL aSettings

      cBMPFile := "logo.bmp"
      aSettings := {}

      // Customer database where startup parameters
      // are stored for convenience
      USE Customer NEW VIA "DBFMEMO"

      // Get default path settings
      AAdd(aSettings, STARTPATHS())

      // Get default color settings
      AAdd(aSettings, DEFAULTCOLORS())

      // Get company logo for display at startup.
      // There is nothing to free because this
      // is the first time importing.
      nPointer := BLOBDIRECTIMPORT(0, cBMPFile)
      AAdd(aSettings, nPointer)

      // Store the settings in the root area of
      // the customer.fpt file

      BLOBROOTPUT(aSettings)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

BLOBDIRECTPUT()  | 

Put data in a BLOB file without referencing a specific field
Syntax
BLOBDIRECTPUT(<nOldPointer>, <uBLOB>) → nNewPointer
Arguments
nOldPointer is a reference to previously stored BLOB data. This reference can be obtained using BLOBDIRECTPUT(), BLOBDIRECTIMPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos). If other than zero (0), the data referenced by nOldPointer is replaced by uBLOB; otherwise, uBLOB is added to the current contents of the BLOB file.
Important! If specified, BLOBDIRECTPUT() releases the space associated with nOldPointer for reuse by other data. Therefore, it is illegal to use nOldPointer with any of the BLOB functions after passing it as an argument to this function. Use the function's return value to refer to the newly stored data.
uBLOB is the data you want to put into the BLOB file. uBLOB can be any CA-Clipper data type except code block or an object.
Returns
BLOBDIRECTPUT() returns a numeric pointer to the uBLOB data.
Description

BLOBDIRECTPUT() stores variable length BLOB data without creating a link with a particular memo field in a database file. After adding data to a BLOB file using BLOBDIRECTPUT(), you should store the function's return value, as this is the only way to access the data from the BLOB file. It is up to you, the developer, to provide permanent storage for this reference (see BLOBROOTPUT()).

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples
■  This example illustrates storing setup information in a BLOB
   file, then selectively retrieving the stored information:

   FUNCTION PutSettings(aColors,;
      aPaths, aPassWords)

      LOCAL aSettings

      USE Setup NEW VIA "DBFMEMO"

      aSettings := {}
      AAdd(aSettings, BLOBDIRECTPUT(0, aColors))

      AAdd(aSettings, BLOBDIRECTPUT(0, aPaths))
      AAdd(aSettings, BLOBDIRECTPUT(0, aPassWords))

      BLOBROOTPUT(aSettings)

      CLOSE

   FUNCTION GETCOLORS()
      LOCAL aSettings
      LOCAL aColors

      USE Setup NEW VIA "DBFMEMO"

      aSettings := BLOBROOTGET()
      aColors := BLOBDIRECTGET(aSettings[1])

      CLOSE

      RETURN aColors
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

BLOBEXPORT()  | 

Copy the contents of a BLOB, identified by its memo field number, to a file
Syntax
BLOBEXPORT(<nFieldPos>, <cTargetFile>, [<nMode>])
    → lSuccess
Arguments
nFieldPos is the position of the field in the database file structure.
cTargetFile is the name of the target file where the BLOB data will be written, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.
If cTargetFile does not exist, it is created. If it exists, this function attempts to open the file in exclusive mode and, if successful, the file is written to without warning or error. If access is denied because another process is using the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBEXPORT()
nMode is a constant defining the copy mode, as shown in the table below:
Field Information Type Constants
    Constant                 Description
    BLOB_EXPORT_APPEND       Number of decimal places for the field
    BLOB_EXPORT_OVERWRITE    Length of the field
Returns
BLOBEXPORT() returns true (.T.) if successful; otherwise, it returns false (.F.).
Description
By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.
Examples
■  This example exports the contents of a field that stores a
   picture to a graphic interchange format (.gif) file, so that the file
   can be programmatically displayed:

   FUNCTION SHOWPIX()
      LOCAL cPixFile := "Picture.gif"
      LOCAL nPos

      // Customer database with a picture of each
      // customer stored in a field called Pix
      USE Customer NEW VIA "DBFCDX"
      nPos := FieldPos("Pix")

      // Export the BLOB file's data
      // for the current Pix field
      IF !BLOBEXPORT(nPos, cPixFile,;
         BLOB_EXPORT_OVERWRITE)
            Alert("Export of picture " + cPixFile + ";
               failed!")
      ELSE
         // Code for displaying picture would go here
      ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

BLOBGET()  | 

Get the contents of a BLOB, identified by its memo field number
Syntax
BLOBGet(<nFieldPos>, [<nStart>], [<nCount>]) → uBLOB
Arguments
nFieldPos is the position of the field in the database file structure.
nStart is the starting position in the memo field of the BLOB data. If nStart is positive, the starting position is relative to the leftmost character in nFieldPos. If nStart is negative, it is relative to the rightmost character in nFieldPos. If nStart is omitted, it is assumed to be 1.
nCount is the number of bytes of data to retrieve beginning at nStart. If nCount is larger than the amount of data stored, excess data is ignored. If omitted, BLOBGET() retrieves to the end of the data.
Note: nStart and nCount apply to string data only. They are ignored for any other data types.
Returns
BLOBGET() returns the BLOB data retrieved from the memo field. The data type of the return value depends on the actual data stored. Use ValType() to determine the data type. If the indicated field is not a memo field, BLOBGET() returns NIL.
Description

BLOBGET() is very similar to FieldGet(). However, because string type variables cannot be larger than 64 KB, FieldGet() will raise a runtime error when attempting to retrieve memo fields of this magnitude or greater.

BLOBGET() will also raise an error if you attempt to retrieve a field greater than this magnitude; however, you can retrieve any subset of the BLOB data by using an nCount less than 64 KB.

Note: BLOB data less than 64 KB can be retrieved from a memo field using standard means (for example, referring to the field by name in an expression or using the FieldGet() function).

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples
■  This example imports information from a word processing
   document into a field, then uses BLOBGET() to extract the first 25
   characters of the field:

   FUNCTION GETFIRST25()
      LOCAL nPos
      LOCAL cStr

      USE customer NEW VIA "DBFCDX"

      // Field that contains word processor
      // documentation
      nPos := FieldPos("WP_DOC")

      // Import a file (can be larger than 64 KB), then
      // obtain the first 25 characters to show to the
      // user
      IF BLOBImport(nPos, "c:\application\temp.doc")
         cStr := BLOBGet(nPos, 1, 25)
      ELSE
         cStr := "Error: could not import file!"
      ENDIF

   CLOSE

   RETURN cStr
Platforms
Available on MS-DOS
See also

BLOBIMPORT()  | 

Read the contents of a file as a BLOB, identified by a memo field number
Syntax
BLOBImport(<nFieldPos>, <cSourceFile>) → lSuccess
Arguments
nFieldPos is the position of the field in the database file structure.
cSourceFile is the name of the file from which to read the BLOB data, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.
This function attempts to open cSourceFile in shared mode. If the file does not exist, a runtime error is raised. If the file is successfully opened, the operation proceeds. If access is denied because another process has exclusive use of the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBIMPORT()
Note: There are no restrictions on the size of cSourceFile except that you must have enough disk space to make the copy.
Returns
BLOBIMPORT() returns true (.T.) if successful; otherwise, it returns false (.F.).
Description

BLOBIMPORT() provides a mechanism for copying the contents of a file into a memo field as BLOB data. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

BLOBIMPORT() is used in conjunction with BLOBEXPORT() to transfer BLOB data back and forth between files and memo fields. You can use BLOBIMPORT() with a variety of file types, including graphic images, word processor files, and printer fonts. These two functions are excellent for creating databases for documents, graphics, sounds, etc.

Note: dbFieldInfo(DBS_BLOB_TYPE, nFieldPos) will return "C" (string) for any memo field created using BLOBIMPORT().

Examples
■  This example imports information from a word processing
   document into a field, and then uses BLOBGET() to extract the first
   25 characters of the field:

   FUNCTION POPULATE()
      USE customer NEW VIA "DBFCDX"

      // Construct unique file name based on last
      // name and id
      DO WHILE .NOT. Eof()
         GetPix("Pix", SubStr(LastName, 1, 4) + CustID)
         Customer->dbSkip()
      ENDDO
   FUNCTION GetPix(cPixField, cPixFile)
      LOCAL nPos

      nPos := FieldPos(cPixField)

      // Import the picture file into indicated field
      IF !BLOBImport(nPos, cPixFile)
         Alert("Import of picture " + cPixFile + ";
         failed!")
      ENDIF
Platforms
Available on MS-DOS
See also

BLOBROOTGET()  | 

Retrieve the data from the root area of a BLOB file
Syntax
BLOBROOTGET() → uBLOB
Returns
BLOBROOTGET() returns the data retrieved from the root of the BLOB file. The data type of the return value depends on the actual data stored. Use ValType() or USUALTYPE() to determine the data type. Note that BLOBROOTGET() returns NIL if the root reference has never been written to with BLOBROOTPUT().
Description

BLOBROOTGET() allows the retrieval of a BLOB from the root of a BLOB file in a work area. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Note: Because the root data does not reference a particular record in the database file, the dbRLock() will not protect this root storage reference. Therefore, if the database file is opened in shared mode, you should use BLOBROOTLOCK() before calling BLOBROOTGET().

Examples
■  This example uses BLOBROOTGET() to read system settings from a
   BLOB file into an array, and then demonstrates how to allow the user
   to modify the settings and restore them in the BLOB file:

   FUNCTION UPDATESETTINGS()
      LOCAL aSettings

      USE customer NEW SHARED VIA "DBFCDX"

      IF BLOBROOTLOCK()
         // Get any existing settings
         aSettings := BLOBROOTGET()

         IF Empty(aSettings)
            // This function would populate aSettings
            // with default data
            aSettings := GETDEFAULTSETTINGS()
         ENDIF

         // This function would allow the user to
         // modify the settings.
         IF ModifySettings(aSettings)
            // Finally, store the settings
            BLOBRootPut(aSettings)
         ENDIF
         BLOBROOTUNLOCK()
      ELSE
         aSettings := {}
         Alert("Could not obtain a lock on the root;
            area")
      ENDIF

      CLOSE

      RETURN aSettings
Platforms
Available on MS-DOS
See also

BLOBROOTLOCK()  | 

Obtain a lock on the root area of a BLOB file
Syntax
BLOBROOTLOCK() → lSuccess
Returns
BLOBROOTLOCK() returns true (.T.) if successful; otherwise, it returns false (.F.).
Description

Use BLOBROOTLOCK() when accessing the database file in shared mode to obtain a lock on the root area of a BLOB file for reading from or writing to the root area.

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples
■  This example illustrates how to properly lock and unlock the
   root area of a BLOB file for a database file opened in shared mode:

   FUNCTION GETSETTINGS()
   LOCAL aCustSettings

   // Open a customer file in shared mode
   USE customer NEW SHARED DBFCDX

   IF BLOBROOTLOCK()
      aCustSettings := BLOBROOTGET()
      BLOBROOTUNLOCK()
   ELSE
      Alert("Could not obtain root lock of Customer;
         file")
   ENDIF

   CLOSE

   RETURN aCustSettings
Platforms
Available on MS-DOS
See also

BLOBROOTPUT()  | 

Store data in the root area of a BLOB file
Syntax
BLOBRootPut(<uBLOB>) → lSuccess
Arguments
uBLOB is the data you want to put into the BLOB file's root area. uBLOB can be any CA-Clipper usual data type except code block and object.
Returns
BLOBROOTPUT() returns true (.T.) if successful; otherwise, it returns false (.F.).
Description

BLOBROOTPUT() allows the storage of one—and only one—piece of data to a BLOB file's root area (there is no size limitation on this one piece of data). After storing the new data, BLOBROOTPUT() releases the space associated with any data previously stored in the BLOB file's root area.

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Note: Because the root data does not reference a particular record in the database file, the dbRLock() will not protect this root storage reference. Therefore, if the database file is opened in shared mode, you should use BLOBROOTLOCK() before calling BLOBROOTPUT().

Examples
■  This example uses BLOBROOTPUT() to store system settings to a
   BLOB file after modification:

   FUNCTION UPDATESETTINGS()
      LOCAL aSettings

      USE customer NEW SHARED VIA "DBFCDX"

      IF BLOBROOTLOCK()
         // Get any existing settings
         aSettings := BLOBROOTGET()

         IF Empty(aSettings)
            // This function would populate aSettings
            // with default data
            aSettings := GETDEFAULTSETTINGS()
         ENDIF

         // This function would allow the user to
         // modify the settings.
         IF ModifySettings(aSettings)
            // Finally, store the settings
            BLOBRootPut(aSettings)
         ENDIF
         BLOBROOTUNLOCK()
      ELSE
         aSettings := {}

         Alert("Could not obtain a lock on the root;
            area")
      ENDIF

      CLOSE

      RETURN aSettings
Platforms
Available on MS-DOS
See also

BLOBROOTUNLOCK()  | 

Release the lock on a BLOB file's root area
Syntax
BLOBROOTUNLOCK() → NIL
Description

Use BLOBROOTUNLOCK() to release a lock previously obtained using BLOBROOTLOCK().

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Note: The only functions that require the use of BLOBROOTLOCK() or BLOBROOTUNLOCK() are BLOBROOTGET() and BLOBROOTPUT().

Examples
■  This example illustrates how to properly lock and unlock the
   root area of a BLOB file for a database file opened in shared mode:

   FUNCTION GETSETTINGS()
      LOCAL aCustSettings

      // Open a customer file in shared mode
      USE customer NEW SHARED VIA DBFCDX

      IF BLOBROOTLOCK()
         aCustSettings := BLOBROOTGET()
         BLOBROOTUNLOCK()
      ELSE
         Alert("Could not obtain root lock of Customer;
            file")
      ENDIF

      CLOSE

      RETURN aCustSettings
Platforms
Available on MS-DOS
See also

Bof()Harbour implementation  | 

Determine when beginning of file is encountered
Syntax
Bof() → lBoundary
Returns
Bof() returns true (.T.) after an attempt to SKIP backward beyond the first logical record in a database file; otherwise, it returns false (.F.). If there is no database file open in the current work area, Bof() returns false (.F.). If the current database file contains no records, Bof() returns true (.T.).
Description

Bof() is a database function used to test for a boundary condition when you are moving the record pointer backward through a database file using the SKIP command. A simple usage example is a descending order record list with an ascending order index file. A more sophisticated example is a screen paging routine that pages forward or backward through the current database file based on the key the user presses. When the user attempts to page backward, you would use Bof() to test for a beginning of file condition before using the SKIP command to move the record pointer and repaint the screen.

Once Bof() is set to true (.T.), it retains its value until there is another attempt to move the record pointer.

By default, Bof() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression (see example below).

The SKIP command is the only record movement command that can set Bof() to true (.T.).

Examples
■  This example demonstrates Bof() by attempting to move the
   record pointer before the first record:

   USE Sales NEW
   ? RecNo(), Bof()               // Result: 1 .F.
   SKIP -1
   ? RecNo(), Bof()               // Result: 1 .T.

■  This example uses aliased expressions to query the value of
   Bof() in unselected work areas:

   USE Sales NEW
   USE Customer NEW
   USE Invoices NEW

   ? Sales->(Bof()), Customer->(Bof())
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Break()Harbour implementation  | 

Branch out of a BEGIN SEQUENCE...END construct
Syntax
Break(<exp>) → NIL
Arguments
exp is the value passed to the RECOVER clause, if any. Note that exp is not optional. NIL may be specified if there is no break value.
Returns
Break() always returns NIL.
Description
The Break() function is identical in functionality to the BREAK statement. The function must be executed during a SEQUENCE. Break() has the advantage that, as an expression, it can be executed from a code block.
Examples
■  This example illustrates exiting a SEQUENCE from a code block:

   bSave := ErrorBlock( {|x| Break(x)} )

   BEGIN SEQUENCE
      .
      .
      .
   RECOVER USING objError
      .
      .
      .
   END

   ErrorBlock(bSave)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Browse()*Harbour implementation  | 

Browse records within a window
Syntax
Browse([<nTop>], [<nLeft>],
   [<nBottom>], [<nRight>]) lSuccess
Arguments
nTop, nLeft, nBottom, and nRight define the window coordinates. If not specified, the default window coordinates are 1, 0 to MaxRow(), and MaxCol().
Returns
Browse() returns false (.F.) if there is no database file in use; otherwise, it returns true (.T.).
Description
Browse() is a user interface function that invokes a general purpose table-oriented browser and editor for records in the current work area. For a list of the navigation keys which are used by Browse(), refer to the dbEdit() function. Note that Browse() is a compatibility function. dbEdit() should be used in its place. For a more complicated Browse(), TBrowse() should be used.
Notes

■ Status line: Browse() supports a status line in the upper

right corner of the browse window indicating one of the following:

Browse() Status Line Messages

       Message   Meaning
       <new>     Append mode
       <bof>     Top of file
       <delete>  Current record is deleted
       Record    Record number display

Browse() has the following three modes:

- Browsing: This is the default mode of Browse(). Pressing any

dbEdit() navigation key moves the highlight to a new column or row.

- Field edit: Pressing Return on any field enters field edit

using a GET. Pressing Return terminates the edit mode, saving the changes. Esc terminates without saving changes. Since the field edit mode uses GET, all navigation and editing keys are READ keys.

- Append: GOing BOTTOM with Ctrl+PgDn and then pressing Down

arrow enters append mode with the indicating message "new" on the status line. A new blank record is then inserted. Pressing Up arrow terminates the append mode, saving the new record if data has been entered. If no data has been entered, the new record is not saved.

Examples
■  This is an example of browsing a file:

   USE File1 NEW
   Browse()
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/BROWSE.PRG
See also

CALL*Harbour implementation | 

Execute a C or Assembler procedure
Syntax
CALL <idProcedure> [WITH <exp list>]
Arguments
idProcedure is the name of the external procedure to CALL.
WITH exp list is an optional list of up to seven expressions of any data type to pass to the external procedure.
Description

CALL executes a separately compiled or assembled procedure. The procedure must be defined as FAR and end with a FAR return instruction. Place parameters on the stack using the C parameter passing convention. Each parameter consists of a FAR (four-byte) pointer to the actual parameter value. When necessary you may use the Word() function to pass a two-byte binary value in the WITH expression. The DX:BX and ES:BX registers also contain a copy of the first four bytes of parameter information.

The procedure must preserve the BP, SS, SI, DI, ES, and DS registers as well as clear the direction flag.

CALL is a compatibility command and therefore not recommended. It is superseded by the Extend system which provides functions for passing data to and from CA-Clipper.

Notes

■ Character strings: Pass a character argument as a FAR pointer

to a null-terminated string (a string with a 00 hex byte at the end).

■ Numeric values: Pass each numeric argument as a FAR pointer

to an eight-byte IEEE floating point value. To pass a parameter as an integer, use the Word() function. The Word() function converts the numeric value to a two-byte binary integer, and passes the integer value directly rather than through a pointer. Note that Word() will not work for values outside of the ▒32,767 range since these values cannot be accurately represented as two-byte integers.

■ Date values: Pass each date argument as a FAR pointer to a

four-byte (long) integer containing a Julian day number.

■ Logical values: Pass each logical argument as a FAR pointer

to a two-byte binary integer containing zero for false (.F.) and one for true (.T.) .

■ Compiling and linking: CALLed programs must conform to the

following rules:

- Procedures must be in INTEL 8086 relocatable object file

format with the .OBJ file extension.

- Procedures must follow the C calling and parameter passing

conventions.

- Procedures must be available to the linker at link time, along

with the library of the source compiler. You will need runtime support for any language other than assembly language. See your compiler manual for further information.

■ Screen position: When using a CALL statement to access a C or

Assembler routine, the cursor is set to the current screen position within the C or Assembler routine.

■ Microsoft C: Microsoft C versions 5.0 and above place a

leading underscore on function names when they are compiled. To call them, therefore, you must CALL _function.

■ dBASE III PLUS: To convert a dBASE III PLUS load module to a

CA-Clipper-compatible module, add the following statements to your .asm file:

PUBLIC proc

and

push ds mov ds, dx

Warning! Modifying the parameter values may produce incorrect or unexpected results and, therefore, is strongly discouraged.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CANCEL*Harbour implementation | 

Terminate program processing
Syntax
CANCEL* | QUIT
Description
CANCEL and QUIT both terminate the current program, closing all open files, and returning control to the operating system. You can use either command from anywhere in a CA-Clipper program system. A RETURN executed at the highest level procedure performs the same action. Note that CANCEL is a compatibility command. QUIT should be used in its place.
Notes

■ Return code: When a CA-Clipper program terminates, the return

code is set to 1 if the process ends with a fatal error. If the process ends normally, the return code is set to 0 or the last ErrorLevel() set in the program.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CDoW()Harbour implementation  | 

Convert a date value to a character day of the week
Syntax
CDoW(<dExp>) → cDayName
Arguments
dExp is the date value to convert.
Returns
CDoW() returns the name of the day of the week as a character string. The first letter is uppercase and the rest of the string is lowercase. For a null date value, CDoW() returns a null string ("").
Description
CDoW() is a date conversion function used in formatting date displays for reports, labels, and screens.
Examples
■  These examples illustrate CDoW():

   ? Date()                      // Result: 09/01/90
   ? CDoW(Date())                // Result: Friday
   ? CDoW(Date() + 7)            // Result: Friday
   ? CDoW(CToD("06/12/90"))      // Result: Tuesday
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CheckBox class | 

Create check boxes, which are controls that can be toggled on or off by a user
Description

Check boxes present a choice to the user which can be either on or off. When a check box is clicked, its state is toggled (as indicated by an X in the box) between checked (on) and unchecked (off).

The CheckBox class has been designed to be easily integrated into the standard CA-Clipper GET/READ system in addition to providing the necessary functionality to be utilized on its own.

Methods link
Class Function
CheckBox() Create a new CheckBox object
CheckBox(nRow, nColumn,
[,cCaption]) → oCheckBox
Arguments
nRow is a numeric value that indicates the screen row of the check box.
nColumn is a numeric value that indicates the screen column of the check box.
nCaption is an optional character string that describes the check box on the screen. If omitted, the default is an empty string.
Returns
Returns a CheckBox object when all of the required arguments are present; otherwise, CheckBox() returns NIL.
Exported Instance Variables
bitmaps An array of bitmap files to be displayed
bitmaps (Assignable)
Contains an array of exactly two elements that indicates the bitmap files to be displayed. The first element indicates the file name of the bitmap to be displayed when the check box is selected. The second element indicates the file name of the bitmap to be displayed when the check box is not selected.
Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.
CA-Clipper will search for the file name first, and if it is not found, then search in the bitmap library. If no file is found either on disk or in the library, no bitmap will be displayed.
If this instance variable is not used, and the application is running in graphic mode, the files CHECK_F.BMU and CHECK_E.BMU will be used for the selected bitmap and unselected bitmap, respectively.
This instance variable only affects applications running in graphic mode and is ignored in text mode.
buffer Logical value indicating checked or unchecked
buffer
Contains a logical value that indicates whether the check box is checked or unchecked. A value of true (.T.) indicates that it is checked and a value of false (.F.) indicates that it is not checked.
capCol Numeric value indicating screen column
capCol (Assignable)
Contains a numeric value that indicates the screen column where the check box's caption is displayed.
capRow Numeric value indicating screen row
capRow (Assignable)
Contains a numeric value that indicates the screen row where the check box's caption is displayed.
caption Character string describing the check box
caption (Assignable)
Contains an optional character string that concisely describes the check box on the screen. If omitted, the default is an empty string.
When present, the & character specifies that the character immediately following it in the caption is the check box's accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the check box. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.
cargo User-definable variable
cargo (Assignable)
Contains a value of any type that is ignored by the CheckBox object. CheckBox:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a CheckBox object and retrieved later.
col Numeric value indicating screen column
col (Assignable)
Contains a numeric value that indicates the screen column where the check box is displayed.
colorSpec Character string indicating color attributes
colorSpec (Assignable)
Contains a character string that indicates the color attributes that are used by the check box's display() method. The string must contain four color specifiers.
Note: In graphic mode, colorSpec positions 1 and 2 have no affect and are ignored.
CheckBox Color Attributes
       Position        Applies To                  Default Value from System
       in colorSpec                                Color setting
       1               The check box when it does  Unselected
                       not have input focus
       2               The check box when it has   Enhanced
                       input focus
       3               The check box's caption     Standard
       4               The check box caption's     Background
                       accelerator key
Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are those listed in the drop-down list box of the Workbench Properties window for that item.
fBlock Code block evaluated at each input focus change
fBlock (Assignable)
Contains an optional code block that, when present, is evaluated each time the CheckBox object receives or loses input focus. The code block takes no implicit arguments. Use CheckBox:hasFocus to determine if the check box is receiving or losing input focus. A value of true (.T.) indicates that it is receiving input focus; otherwise, a value of false (.F.) indicates that it is losing input focus.
This code block is included in the CheckBox class to provide a method of indicating when an input focus change event has occurred. The name "fBlock" refers to focus block.
hasFocus Logical value indicating the input focus
hasFocus
Contains a logical value that indicates whether the CheckBox object has input focus. CheckBox:hasFocus contains true (.T.) if it has input focus; otherwise, it contains false (.F.).
message Character string describing check box
message (Assignable)
Contains a character string that describes the check box. It is displayed on the screen's status bar line.
row Numeric value indicating screen row
row (Assignable)
Contains a numeric value that indicates the screen row where the check box is displayed.
sBlock Code block evaluated at every state change
sBlock (Assignable)
Contains an optional code block that, when present, is evaluated each time the CheckBox object's state changes. The code block takes no implicit arguments. Use the buffer instance variable to determine if the check box is being checked or unchecked. A value of true (.T.) indicates that it is being checked; otherwise, a value of false (.F.) indicates that it is being unchecked.
This code block is included in the CheckBox class to provide a method of indicating when a state change event has occurred. The name "sBlock" refers to state block.
style Character string indicating delimiter characters
style (Assignable)
Contains a character string that indicates the delimiter characters that are used by the check box's display() method. The string must contain four characters. The first is the left delimiter. Its default value is the left square bracket ([) character. The second is the checked indicator. Its default value is the square root character. The third is the unchecked indicator. Its default is the space character (" "). The fourth character is the right delimiter. Its default value is the right square bracket (]) character.
Note: The style instance variable is ignored in graphic mode.
typeOut Logical value false (.F.)
typeOut
Contains the logical value false (.F.). CheckBox:typeOut never changes. It is not used by the CheckBox object and is only provided for compatibility with the other GUI control classes.
Exported Methods
display() Shows a check box and caption on the screen
oCheckBox:display() → self
display() is a method of the CheckBox class that is used for showing a check box and its caption on the screen. display() uses the values of the following instance variables to correctly show the check box in its current context in addition to providing maximum flexibility in the manner a check box appears on the screen: buffer, caption, capCol, capRow, col, colorSpec, hasFocus, row, and style.
HitTest() Indicates position of mouse cursor relative to check box
oCheckBox:hitTest(nMouseRow, nMouseCol)
→ nHitStatus
nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.
nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.
Returns a numeric value that indicates the relationship of the mouse cursor with the check box. HitTest() is a method of the CheckBox class that is used for determining if the mouse cursor is within the region of the screen that the check box or its caption occupies.
Applicable Hit Test Return Values
       Value     Constant    Description
       0         HTNOWHERE   The mouse cursor is not within the region of
                             the screen that the check box occupies
       -1025     HTCAPTION   The mouse cursor is on the check box's caption
       -2049     HTCLIENT    The mouse cursor is on the check box
Button.ch contains manifest constants for the HitTest() return value.
killFocus() Takes input focus away from the CheckBox object
oCheckBox:killFocus() → self
killFocus() is a method of the CheckBox class that is used for taking input focus away from a CheckBox object. Upon receiving this message, the CheckBox object redisplays itself and, if present, evaluates the code block within its fBlock variable.
This message is meaningful only when the CheckBox object has input focus.
Select() Determines whether check box should be checked
oCheckBox:select([lNewState]) → self
lNewState is a logical value that indicates whether the check box should be checked or not. Set to true (.T.) to check the box or false to uncheck the box. If omitted, the check box state will toggle to its opposing state.
Select() is a method of the CheckBox class that is used for changing the state of a check box. Its state is typically changed when the space bar is pressed or the mouse's left button is pressed when its cursor is within the check box's region of the screen.
setFocus() Gives input focus to the CheckBox object
oCheckBox:setFocus() → self
setFocus() is a method of the CheckBox class that is used for giving focus to a CheckBox object. Upon receiving this message, the CheckBox object redisplays itself and if present, evaluates the code block within its fBlock variable.
This message is meaningful only when the CheckBox object does not have input focus.
Examples
■  This example creates and integrates a check box within a Get
   List and activates it by performing a READ:

   STORE SPACE (25) TO Name
   STORE .T. TO Married
   STORE SPACE (19) TO Phone

   CLS

   @    5,10 SAY "Customer Name: " GET Name
   @  7,10 SAY "Married?:     " GET Married CHECKBOX
   @  9,10 SAY "Home Phone:    " GET Phone

   READ

   ? ALLTRIM (Name) + " IS " + IIF(Married,"","NOT") + "Married."
   WAIT
Platforms
Available on MS-DOS

Chr()Harbour implementation  | 

Convert an ASCII code to a character value
Syntax
Chr(<nCode>) → cChar
Arguments
nCode is an ASCII code in the range of zero to 255.
Returns
Chr() returns a single character value whose ASCII code is specified by nCode.
Description

Chr() is a numeric conversion function that converts an ASCII code to a character. It is the inverse of Asc(). Chr() serves a number of common tasks including:

■ Sending control codes and graphics characters to the screen or

printer

■ Ringing the bell

■ Converting Inkey() return values to characters

■ Stuffing the keyboard buffer

Notes

■ The null character: Chr(0) has a length of one (1) and is

treated like any other character. This lets you send it to any device or file, including a database file.

Examples
■  These examples illustrate Chr() with various arguments:

   ? Chr(72)                    // Result: H
   ? Chr(Asc("A") + 32)         // Result: a
   ? Chr(7)                     // Result: bell sounds

■  These lines of code show the difference between a null string
   and the null character:

   ? Len("")                   // Result: 0
   ? Len(Chr(0))               // Result: 1
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CLEAR ALL*Harbour implementation | 

Close files and release public and private variables
Syntax
CLEAR ALL
Description

CLEAR ALL releases all public and private variables, closes all open databases and related files in all active work areas, and SELECTs work area 1. Related files are index, alternate, and memo files. CLEAR ALL, however, does not release local or static variables.

CLEAR ALL is a compatibility command and therefore not recommended. Its usage in CA-Clipper is superseded by the command or function that performs the specific action you need. You can close files associated with work areas with one of the various forms of the CLOSE command. You can release private and public variables using the RELEASE command although explicitly releasing variables is discouraged in most instances. For more information on the scope and lifetime of variables, refer to the "Basic Concepts" chapter in the Programming and Utilities Guide.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CLEAR GETSHarbour implementation | 

Release Get objects from the current GetList array
Syntax
CLEAR GETS
Description

CLEAR GETS explicitly releases all Get objects in the current and visible GetList array, and terminates the calling READ, releasing any remaining objects in the calling READ, if executed within a SET KEY procedure or a user-defined function invoked by a VALID clause. CLEAR GETS releases Get objects by assigning an empty array to the variable GetList. GetList is the name of the variable used to hold an array of Get objects for subsequent READ commands. There are two other mechanisms that automatically release Get objects: CLEAR specified without the SCREEN clause, and READ specified without the SAVE clause.

CLEAR GETS has two basic uses. First, it can be used to terminate a READ from a SET KEY procedure or VALID user-defined function. Second, it can be used to delete Get objects from the GetList array when you have not executed a READ or you have saved the Get objects by using READ SAVE.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CLEAR MEMORYHarbour implementation | 

Release all public and private variables
Syntax
CLEAR MEMORY
Description

CLEAR MEMORY deletes both public and private memory variables from the memory variable table. It operates in contrast to RELEASE ALL, which does not actually delete public and private memory variables but assigns NIL to those whose scope is the current procedure. CLEAR MEMORY is the only way to delete all public memory variables from current memory. Local and static variables, however, are unaffected by CLEAR MEMORY.

For more information on variables, refer to the Variables section of the "Basic Concepts" chapter in the Programming and Utilities Guide.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CLEAR SCREENHarbour implementation | 

Clear the screen and return the cursor home
Syntax
CLEAR [SCREEN] | CLS
Arguments
SCREEN suppresses the automatic releasing of Get objects from the current and visible GetList array when the screen is CLEARed.
Description

CLEAR is a full-screen command that erases the screen, releases pending GETs, and positions the cursor at row and column zero. If the SCREEN clause is specified, Get objects are not released.

CLS is a synonym for CLEAR SCREEN.

Notes

SET KEY and VALID: If you are editing GETs, executing a CLEAR

within a SET KEY procedure or within a VALID user-defined function will abort the active READ when control returns. To clear the screen without CLEARing GETs, use either the CLEAR SCREEN or CLS commands.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CLEAR TYPEAHEADHarbour implementation | 

Empty the keyboard buffer
Syntax
CLEAR TYPEAHEAD
Description

CLEAR TYPEAHEAD is a keyboard command that clears all pending keys from the CA-Clipper keyboard buffer. This is useful in user interface procedures or user-defined functions to guarantee that keys processed from the keyboard buffer are appropriate to the current activity and not pending from a previous activity. User functions called by AChoice() and dbEdit() are especially sensitive to such keys.

Note that both the SET TYPEAHEAD and KEYBOARD commands also clear the keyboard buffer.

Examples
■  This example empties the keyboard buffer before invoking
   dbEdit(), guaranteeing that any pending keys will not be executed:

   CLEAR TYPEAHEAD
   dbEdit()
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CLOSEHarbour implementation | 

Close a specific set of files
Syntax
CLOSE [<idAlias> | ALL | ALTERNATE | DATABASES |
   FORMAT | INDEXES]
Arguments
idAlias specifies the work area where all files are to be closed.
ALL closes alternate, database, and index files in all work areas, releasing all active filters, relations, and format definitions.
ALTERNATE closes the currently open alternate file, performing the same action as SET ALTERNATE TO with no argument.
DATABASES closes all open databases, memo and associated index files in all work areas, and releases all active filters and relations. It does not, however, have any effect on the active format.
FORMAT releases the current format, performing the same action as SET FORMAT TO with no argument.
INDEXES closes all index files open in the current work area.
Description

CLOSE is a general purpose command that closes various types of CA-Clipper files depending on the specified option. CLOSE with no option closes the current database and associated files, the same as USE with no arguments.

In CA-Clipper, a number of other commands also close files including:

QUIT

■ CANCEL*

RETURN from the highest level procedure

CLEAR ALL*

USE with no argument

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CMonth()Harbour implementation  | 

Convert a date to a character month name
Syntax
CMonth(<dDate>) → cMonth
Arguments
dDate is the date value to convert.
Returns
CMonth() returns the name of the month as a character string from a date value with the first letter uppercase and the rest of the string lowercase. For a null date value, CMonth() returns a null string ("").
Description
CMonth() is a date conversion function useful for creating formatted date strings that can be used in reports, labels, or screens.
Examples
■  These examples illustrate CMonth():

   ? CMonth(Date())                     // Result: September
   ? CMonth(Date() + 45)                // Result: October
   ? CMonth(CToD("12/01/94"))           // Result: December
   ? SubStr(CMonth(Date()), 1, 3) +;
      Str(Day(Date()))                  // Result: Sep 1
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Col()Harbour implementation  | 

Return the screen cursor column position
Syntax
Col() → nCol
Returns
Col() returns an integer numeric value. The range of the return value is zero to MaxCol().
Description

Col() is a screen function that returns the current column position of the cursor. The value of Col() changes whenever the cursor position changes on the screen. Both console and full-screen commands can change the cursor position. In addition, Col() is automatically set to zero whenever a CLEAR, CLEAR SCREEN, or CLS command is executed.

Use Col() to position the cursor to a column relative to the current column. It is generally used in combination with Row() and all variations of the @ command. In particular, use Col() and Row() to create screen position-independent procedures or functions that pass the upper-left row and column as parameters.

If DEVICE is SET TO PRINTER, all the output of @...SAY commands is directed to the printer and PRow() and PCol() are updated instead of Row() and Col(). Use these functions when you need to determine the position of the printhead.

Examples
■  This example displays a Customer name beginning at column 10.
   The customer's account status is then displayed to the right of the
   last character of the customer name using Col():

USE Sales NEW

   CLS
   @ 1, 10 SAY "Customer Name: " + Trim(Customer)
   @ Row(), Col() + 1 SAY "Account status: " + Status
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ColorSelect()Harbour implementation  | 

Activate attribute in current color settings
Syntax
ColorSelect(<nColorIndex>) → NIL
Arguments
nColorIndex is a number corresponding to the ordinal positions in the current list of color attributes, as set by SetColor().
Returns
Always returns NIL.
Description

ColorSelect() activates the specified color pair from the current list of color attributes (established by SetColor()). Manifest constants for nColorIndex are defined in color.ch.

Color.ch constants

    Constant          Value
    CLR_STANDARD      0
    CLR_ENHANCED      1
    CLR_BORDER        2
    CLR_BACKGROUND    3
    CLR_UNSELECTED    4

ColorSelect() does not alter the current SET Color setting.

This table describes the scope of the CA-Clipper color settings affected by SetColor():

Color settings

    Setting        Scope
    Standard       All screen output commands and functions
    Enhanced       GETs and selection highlights
    Border         Screen border (not supported on EGA and VGA monitors)
    Background     Not supported
    Unselected     Unselected GETs

Examples
■  This example demonstrates use of ColorSelect() with the
   color.ch manifest constants:

   USE Sales NEW
   ? SetColor()                   // displays "W/B,N/B,W/N,W/N,W/N"
                                  // in white on blue

   ColorSelect(CLR_ENHANCED)      // enhanced is active color pair
   ? "I'm black and blue"         // displayed in black on blue
   ColorSelect(CLR_STANDARD)      // restore standard color
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is color.ch.
See also

COMMITHarbour implementation | 

Perform a solid-disk write for all active work areas
Syntax
COMMIT
Description

COMMIT is a database command that flushes CA-Clipper buffers and performs a solid-disk write for all work areas with open database and index files. The solid-disk write capability is available under DOS version 3.3 and above. Under DOS 3.2 or less, COMMIT flushes CA-Clipper buffers to DOS.

In a network environment, issuing a GO TO RecNo() or a SKIP0 will flush CA-Clipper's database and index buffers, but only a COMMIT will flush the buffers and perform a solid-disk write. Thus to insure updates are visible to other processes, you must issue a COMMIT after all database update commands (e.g., APPEND, REPLACE). To insure data integrity, COMMIT should be issued before an UNLOCK operation. Refer to the "Network Programming" chapter in the Programming and Utilities Guide for more information on update visibility.

Notes

COMMIT uses DOS interrupt 21h function 68h to perform the

solid-disk write. It is up to the network operating system to properly implement this request. Check with the network vendor to see if this is supported.

Examples
■  In this example, COMMIT forces a write to disk after a series
   of memory variables are assigned to field variables:

   USE Sales EXCLUSIVE NEW
   MEMVAR->Name := Sales->Name
   MEMVAR->Amount := Sales->Amount
   //
   @ 10, 10 GET MEMVAR->Name
   @ 11, 10 GET MEMVAR->Amount
   READ
   //
   IF Updated()
      APPEND BLANK
      REPLACE Sales->Name WITH MEMVAR->Name
      REPLACE Sales->Amount WITH MEMVAR->Amount
      COMMIT
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CONTINUEHarbour implementation | 

Resume a pending LOCATE
Syntax
CONTINUE
Description

CONTINUE is a database command that searches from the current record position for the next record meeting the most recent LOCATE condition executed in the current work area. It terminates when a match is found or end of file is encountered. If CONTINUE is successful, the matching record becomes the current record and Found() returns true (.T.); if unsuccessful, Found() returns false (.F.).

Each work area may have an active LOCATE condition. In CA-Clipper, a LOCATE condition remains pending until a new LOCATE condition is specified. No other commands release the condition.

Notes

■ Scope and WHILE condition: Note that the scope and WHILE

condition of the initial LOCATE are ignored; only the FOR condition is used with CONTINUE. If you are using a LOCATE with a WHILE condition and want to continue the search for a matching record, use SKIP and then repeat the original LOCATE statement adding REST as the scope.

Examples
■  This example scans records in Sales.dbf for a particular
   salesman and displays a running total sales amounts:

   LOCAL nRunTotal := 0
   USE Sales NEW
   LOCATE FOR Sales->Salesman = "1002"
   DO WHILE Found()
      ? Sales->Salesname, nRunTotal += Sales->Amount
      CONTINUE
   ENDDO

■  This example demonstrates how to continue if the pending
   LOCATE scope contains a WHILE condition:

   LOCAL nRunTotal := 0
   USE Sales INDEX Salesman NEW
   SEEK "1002"
   LOCATE REST WHILE Sales->Salesman = "1002";
         FOR Sales->Amount > 5000
   DO WHILE Found()
      ? Sales->Salesname, nRunTotal += Sales->Amount
      SKIP
      LOCATE REST WHILE Sales->Salesman = "1002";
         FOR Sales->Amount > 5000
   ENDDO
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

COPY FILEHarbour implementation | 

Copy a file to a new file or to a device
Syntax
COPY FILE <xcSourceFile> TO <xcTargetFile>|<xcDevice>
Arguments
xcSourceFile is the name of the source file to copy including the extension.
xcTargetFile is the name of the target file including the extension.
Both arguments can be specified as literal file names or as character expressions enclosed in parentheses. COPY FILE supplies no default extensions.
xcDevice is the name of the device where all subsequent output will be sent. You can specify a device name as a literal character string or a character expression enclosed in parentheses. Additionally, a device can be either local or network. If you COPY TO a non-existing device, you create a file with the name of the device. When specifying device names, do not use a trailing colon.
Description
COPY FILE is a file command that copies files to and from the CA-Clipper default drive and directory unless you specify a drive and/or path. If the xcTargetFile exists, it is overwritten without warning or error.
Examples
■  This example copies a file to a new file and then tests for
   the existence of the new file:

   COPY FILE Test.prg TO Real.prg
   ? FILE("Real.prg")                  // Result: .T.
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

COPY STRUCTUREHarbour implementation | 

Copy the current .dbf structure to a new database (.dbf) file
Syntax
COPY STRUCTURE [FIELDS <idField list>]
   TO <xcDatabase>
Arguments
FIELDS idField list defines the set of fields to copy to the new database structure in the order specified. The default is all fields.
TO xcDatabase is the name of the target database file and can be specified either as a literal database file name or as a character expression enclosed in parentheses. The default extension is .dbf unless another is specified.
Description

COPY STRUCTURE is a database command that creates an empty database file with field definitions from the current database file. If xcDatabase exists, it is overwritten.

COPY STRUCTURE creates empty structures that can be used to archive records from the current database file or to create a temporary database file for data entry.

Examples
■  In this example, COPY STRUCTURE creates a temporary file.
   After the user enters data into the temporary file, the master
   database file is updated with the new information:

   USE Sales NEW
   COPY STRUCTURE TO Temp
   USE Temp NEW
   lMore := .T.
   DO WHILE lMore
      APPEND BLANK
      @ 10, 10 GET Temp->Salesman
      @ 11, 11 GET Temp->Amount
      READ
      IF Updated()
         SELECT Sales
         APPEND BLANK
         REPLACE Sales->Salesman WITH Temp->Salesman
         REPLACE Sales->Amount WITH Temp->Amount
         SELECT Temp
         ZAP
      ELSE
         lMore := .F.
      ENDIF
   ENDDO
   CLOSE DATABASES
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

COPY STRUCTURE EXTENDEDHarbour implementation | 

Copy field definitions to a .dbf file
Syntax
COPY STRUCTURE EXTENDED
   TO <xcExtendedDatabase>
Arguments
TO xcExtendedDatabase is the name of the target structure extended database file. This argument can be specified either as a literal database file name or as a character expression enclosed in parentheses.
Description

COPY STRUCTURE EXTENDED creates a database file whose contents is the structure of the current database file with a record for the definition of each field. The structure extended database file has the following structure:

Structure of an Extended File

    Field   Name           Type         Length    Decimals
    1       Field_name     Character    10
    2       Field_type     Character    1
    3       Field_len      Numeric      3         0
    4       Field_dec      Numeric      4         0

Used in application programs, COPY STRUCTURE EXTENDED permits you to create or modify the structure of a database file programmatically. To create a new database file from the structure extended file, use CREATE FROM. If you need an empty structure extended file, use CREATE.

Notes

■ Character field lengths greater than 255: In CA-Clipper, the

maximum character field length is 64K. For compatibility reasons, field lengths greater than 255 are represented as a combination of the Field_dec and Field_len fields. After COPYing STRUCTURE EXTENDED, you can use the following formula to determine the length of any character field:

nFieldLen := IF(Field_type = "C" .AND. ;

Field_dec != 0, Field_dec * 256 + ; Field_len, Field_len)

Examples
■  This example creates Struc.dbf from Sales.dbf as a structure
   extended file and then lists the contents of Struc.dbf to illustrate
   the typical layout of field definitions:

   USE Sales NEW
   COPY STRUCTURE EXTENDED TO Struc
   USE Struc NEW
   LIST Field_name, Field_type, Field_len, Field_dec

   Result:

   1 BRANCH        C      3      0
   2 SALESMAN      C      4      0
   3 CUSTOMER      C      4      0
   4 PRODUCT       C     25      0
   5 AMOUNT        N      8      2
   6 NOTES         C      0    125
   // Field length is 32,000 characters
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

COPY TOHarbour implementation | 

Export records to a new database (.dbf) file or ASCII text file
Syntax
COPY [FIELDS <idField list>] TO <xcFile>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
   [SDF | DELIMITED [WITH BLANK | <xcDelimiter>] |
   [VIA <xcDriver>]]
Arguments
FIELDS idField list specifies the list of fields to copy to the target file. The default is all fields.
TO xcFile specifies the name of the target file. The file name can be specified either as a literal file name or as a character expression enclosed in parentheses. If SDF or DELIMITED is specified, .txt is the default extension. Otherwise, .dbf is the default extension.
scope defines the portion of the current database file to COPY. The default is ALL records.
WHILE lCondition specifies the set of records meeting the condition from the current record until the condition fails.
FOR lCondition specifies the conditional set of records to copy within the given scope.
SDF specifies the output file type as a System Data Format ASCII text file. Records and fields are fixed length.
DELIMITED specifies the output file type as a delimited ASCII text file where character fields are enclosed in double quotation marks (the default delimiter). Records and fields are variable length.
DELIMITED WITH BLANK identifies an ASCII text file in which fields are separated by one space and character fields have no delimiters.
DELIMITED WITH xcDelimiter identifies a delimited ASCII text file where character fields are enclosed using the specified delimiter. xcDelimiter can be specified either as a literal character or as a character expression enclosed in parentheses.
See the tables below for more information regarding the format specifications for ASCII text files created using these arguments.
VIA xcDriver specifies the replaceable database driver (RDD) to use to create the resulting copy. cDriver is name of the RDD specified as a character expression. If cDriver is specified as a literal value, it must be enclosed in quotes.
If the VIA clause is omitted, COPY TO uses the driver in the current work area. If you specify the VIA clause, you must REQUEST the appropriate RDDs to be linked into the application.
Note: If the DELIMITED WITH clause is specified on a COPY or APPEND command, it must be the last clause specified.
Description

COPY TO is a database command that copies all or part of the current database file to a new file. Records contained in the active database file are copied unless limited by a scope, a FOR|WHILE clause, or a filter.

If DELETED is OFF, deleted records in the source file are copied to xcFile where they retain their deleted status. If DELETED is ON, however, no deleted records are copied. Similarly, if a FILTER has been SET, invisible records are not copied.

Records are copied in controlling index order if there is an index open in the current work area and SET ORDER is not zero. Otherwise, records are copied in natural order.

In a network environment, CA-Clipper opens the target database file EXCLUSIVEly before the COPY TO operation begins. Refer to the "Network Programming" chapter in the Programming and Utilities Guide for more information.

This table shows the format specifications for SDF text files:

SDF Text File Format Specifications

    File Element        Format
    Character fields    Padded with trailing blanks
    Date fields         yyyymmdd
    Logical fields      T or F
    Memo fields         Ignored
    Numeric fields      Padded with leading blanks for zeros
    Field separator     None
    Record separator    Carriage return/linefeed
    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED and DELIMITED WITH xcDelimiter ASCII text files:

DELIMITED Text File Format Specifications

    File Element        Format
    Character fields    Delimited, with trailing blanks truncated
    Date fields         yyyymmdd
    Logical fields      T or F
    Memo fields         Ignored
    Numeric fields      Leading zeros truncated
    Field separator     Comma
    Record separator    Carriage return/linefeed
    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED WITH BLANK ASCII text files:

DELIMITED WITH BLANK Text File Format Specifications

    File Element        Format
    Character fields    Not delimited, trailing blanks truncated
    Date fields         yyyymmdd
    Logical fields      T or F
    Memo fields         Ignored
    Numeric fields      Leading zeros truncated
    Field separator     Single blank space
    Record separator    Carriage return/linefeed
    End of file marker  1A hex or Chr(26)

Examples
■  This example demonstrates copying to another database file:

   USE Sales NEW
   COPY TO Temp

■  This example demonstrates the layout of a DELIMITED file:

   COPY NEXT 1 TO Temp DELIMITED
   TYPE Temp.txt

   Result:

   "Character",12.00,19890801,T

■  This example demonstrates the layout of an SDF file with four
   fields, one for each data type:

   USE Testdata NEW
   COPY NEXT 1 TO Temp SDF
   TYPE Temp.txt

   Result:

   Character     12.0019890801T

■  This example demonstrates the layout of a DELIMITED file WITH
   a different delimiter:

   COPY NEXT 1 TO Temp DELIMITED WITH '
   TYPE Temp.txt

   Result:

   'Character',12.00,19890801,T
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

COUNTHarbour implementation | 

Tally records to a variable
Syntax
COUNT TO <idVar>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
Arguments
TO idVar identifies the variable that holds the COUNT result. A variable that either does not exist or is invisible is created as a private variable whose scope is the current procedure.
scope is the portion of the current database file to COUNT. The default is ALL records.
WHILE lCondition specifies the set of records meeting the condition from the current record until the condition fails.
FOR lCondition specifies the conditional set of records to COUNT within the given scope.
Description
COUNT tallies the number of records from the current work area that match the specified record scope and conditions. The result is then placed in the specified variable. idVar can be a variable of any storage class including a field.
Examples
■  This example demonstrates a COUNT of Branches in Sales.dbf:

   USE Sales NEW
   COUNT TO nBranchCnt FOR Branch = 100
   ? nBranchCnt                           // Result: 4

■  This example tallies the number of records in Sales.dbf whose
   Branch has the value of 100 and assigns the result to the Count field
   in Branch.dbf for branch 100:

   USE Branch INDEX Branch NEW
   SEEK 100
   USE Sales INDEX SalesBranch NEW
   SEEK 100
   COUNT TO Branch->Count WHILE Branch = 100
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CREATEHarbour implementation | 

Create an empty structure extended (.dbf) file
Syntax
CREATE <xcExtendedDatabase>
Arguments
xcExtendedDatabase is the name of the empty structure extended database file. This argument can be specified either as a literal database file name or as a character expression enclosed in parentheses. If no extension is specified, .dbf is the default extension.
Description

CREATE produces an empty structure extended database file with the following structure:

Structure of an Extended File

    Field   Name           Type        Length    Decimals
    1       Field_name     Character   10
    2       Field_type     Character   1
    3       Field_len      Numeric     3         0
    4       Field_dec      Numeric     4         0

Like COPY STRUCTURE EXTENDED, CREATE can be used in conjunction with CREATE FROM to form a new database file. Unlike COPY STRUCTURE EXTENDED, CREATE produces an empty database file and does not require the presence of another database file to create it.

xcExtendedDatabase is automatically opened in the current work area after it is created.

Examples
■  This example creates a new structure extended file, places the
   definition of one field into it, and then CREATEs a new database file
   FROM the extended structure:

   CREATE TempStru
   APPEND BLANK
   REPLACE Field_name WITH "Name",;
      Field_type WITH "C",;
      Field_len WITH 25,;
      Field_dec WITH 0
   CLOSE
   CREATE NewFile FROM TempStru
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CREATE FROMHarbour implementation | 

Create a new .dbf file from a structure extended file
Syntax
CREATE <xcDatabase> FROM <xcExtendedDatabase> [NEW]
   [ALIAS <xcAlias>] [VIA <cDriver>]
Arguments
xcDatabase is the name of the new database file to create from the structure extended file.
xcExtendedDatabase is the name of a structure extended file to use as the structure definition for the new database file.
Both of these arguments can be specified either as literal database file names or as character expressions enclosed in parentheses. If an extension is not specified, the default is .dbf.
NEW opens xcDatabase in the next available work area making it the current work area. If this clause is not specified, xcDatabase is opened in the current work area.
ALIAS xcAlias is the name to associate with the work area when xcDatabase is opened. You may specify the alias name as a literal name or as a character expression enclosed in parentheses. A valid xcAlias may be any legal identifier (i.e., it must begin with an alphabetic character and may contain numeric or alphabetic characters and the underscore). Within a single application, CA-Clipper will not accept duplicate aliases. If this clause is not specified, the alias defaults to the database file name.
VIA cDriver specifies the replaceable database driver (RDD) to use to process the current work area. cDriver is the name of the RDD specified as a character expression. If you specify cDriver as a literal value, you must enclose it in quotes.
Description

CREATE FROM produces a new database file with the field definitions taken from the contents of a structure extended file. To qualify as a structure extended file, a database file must contain the following four fields:

Structure of an Extended File

    Field   Name           Type        Length    Decimals
    1       Field_name     Character   10
    2       Field_type     Character   1
    3       Field_len      Numeric     3         0
    4       Field_dec      Numeric     4         0

xcDatabase is automatically opened in the current work area after it is created.

Notes

■ Data dictionaries: For data dictionary applications, you can

have any number of other fields within the structure extended file to describe the extended field attributes. You may, for example, want to have fields to describe such field attributes as a description, key flag, label, color, picture, and a validation expression for the VALID clause. When you CREATE FROM, CA-Clipper creates the new database file from the required fields only, ignoring all other fields in the extended structure. Moreover, CA-Clipper is not sensitive to the order of the required fields.

■ Character field lengths greater than 255: There is one method

for creating a character field with a length greater than 255 digits:

- Specify the field length using both the Field_len and

Field_dec fields according to the following formulation:

FIELD->Field_len := nFieldLength % 256 FIELD->Field_dec := INT(nFieldLength / 256)

Examples
■  This example is a procedure that simulates an interactive
   CREATE utility:

   CreateDatabase("NewFile")
   RETURN

   FUNCTION CreateDatabase( cNewDbf )
      CREATE TmpExt          // Create empty structure extended
      USE TmpExt
      lMore := .T.
      DO WHILE lMore         // Input new field definitions
         APPEND BLANK
         CLEAR
         @ 5, 0 SAY "Name.....: " GET Field_name
         @ 6, 0 SAY "Type.....: " GET Field_type
         @ 7, 0 SAY "Length...: " GET Field_len
         @ 8, 0 SAY "Decimals.: " GET Field_dec
         READ
         lMore := (!Empty(Field_name))
      ENDDO

      // Remove all blank records
      DELETE ALL FOR Empty(Field_name)
      PACK
      CLOSE

      // Create new database file
      CREATE (cNewDbf) FROM TmpExt
      ERASE TmpExt.dbf
      RETURN NIL

■  This example creates a new definition in a structure extended
   file for a character field with a length of 4000 characters:

   APPEND BLANK
   REPLACE Field_name WITH "Notes",;
      Field_type WITH "C",;
      Field_len  WITH 4000 % 256,;
      Field_dec  WITH INT(4000 / 256)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CToD()Harbour implementation  | 

Convert a date string to a date value
Syntax
CToD(<cDate>) → dDate
Arguments
cDate is a character string consisting of numbers representing the month, day, and year separated by any character other than a number. The month, day, and year digits must be specified in accordance with the SET DATE format. If the century digits are not specified, the century is determined by the rules of SET EPOCH.
Returns
CToD() returns a date value. If cDate is not a valid date, CToD() returns an empty date.
Description

CToD() is a character conversion function that converts a character string to a date. To initialize an empty date for date entry, specify cDate as a null string (""), Space(8), or " / / ".

CToD() is used whenever you need a literal date value. Some examples are:

■ Initializing a variable to a date value

■ Specifying a literal date string as an argument of a RANGE

clause of @...GET

■ Specifying a literal date string in order to perform date

arithmetic

■ Comparing the result of a date expression to a literal date

string

REPLACEing a date field with a literal date string

CToD() is the inverse of DToC() which converts a date value to a character string in the format specified by SET DATE and SET CENTURY. DToS() also converts a date value to a character string in the form yyyymmdd.

Examples
■  This example uses CToD() to initialize two date variables,
   using one as a GET and the other for RANGE validation:

   SET CENTURY ON
   dBegin := CToD("01-26-1876")
   dCurrent := CToD("")
   @ 10, 10 SAY "Enter date:" GET dCurrent ;
         RANGE dBegin, Date()
   READ

■  This example uses CToD() to create a date value within a FOR
   condition:

   USE Inventory NEW
   REPLACE ALL Inventory->Price WITH ;
      Inventory->Price * 1.1 FOR ;
      Inventory->InvDate < CToD("10/10/90")
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

CurDir()Harbour implementation  | 

Return the current DOS directory
Syntax
CurDir([<cDrivespec>]) → cDirectory
Arguments
cDrivespec specifies the letter of the disk drive to query. If not specified, the default is the current DOS drive.
Returns
CurDir() returns the current DOS directory of the drive specified by cDrivespec as a character string without either leading or trailing backslash () characters.
If an error occurs, or the current directory of the specified drive is the root directory, CurDir() returns a null string ("").
Description
CurDir() is an environment function that gives you the name of the current DOS directory, ignoring the SET DEFAULT and SET PATH settings.
Examples
■  These examples illustrate various CurDir() results:

   ? CurDir("E:")     // Result: null string--root directory
   ? CurDir("C")      // Result: CLIP53\SOURCE
   ? CurDir("C:")     // Result: CLIP53\SOURCE
   ? CurDir()         // Result: null string--root directory
   ? CurDir("A")      // Result: null string--drive not ready

■  This example changes the current DOS directory to a new value
   if it does not match a specified directory:

   IF CurDir("C:") != "CLIP53\SOURCE"
      RUN CD \CLIP53\SOURCE
   ENDIF
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM
See also

dbAppend()Harbour implementation  | 

Append a new record to the database open in the current work area
Syntax
dbAppend([<lReleaseRecLocks>]) → NIL
Arguments
lReleaseRecLocks is a logical data type that if true (.T.), clears all pending record locks, then appends the next record. If lReleaseRecLocks is false (.F.), all pending record locks are maintained and the new record is added to the end of the Lock List. The default value of lReleaseRecLocks is true (.T.).
Returns
dbAppend() always returns NIL.
Description

dbAppend() is a database function that lets you add records to the current database. The enhancement to this function lets you maintain multiple record locks during an append.

dbAppend() without a parameter as in earlier versions of CA-Clipper, clears all pending record locks prior to an append. This is the same as dbAppend(.T.).

Examples
■  This example appends a blank record to the database, Sales,
   without releasing the record locks in the current Lock List, and then
   checks for a network error:

   USE Sales NEW
   SET INDEX TO Sales
   dbAppend(.F.)
   IF NetErr()
      ? "A network error has occurred!"
   ENDIF
Platforms
Available on MS-DOS
See also

dbClearFilter()Harbour implementation  | 

Clear a filter condition
Syntax
dbClearFilter() → NIL
Returns
dbClearFilter() always returns NIL.
Description

dbClearFilter() clears the logical filter condition, if any, for the current work area.

dbClearFilter() performs the same function as the standard SET FILTER command with no expression specified. For more information, refer to the SET FILTER command.

Notes

■ Logical records: dbClearFilter() affects the logical

visibility of records in the current work area. For more information, refer to dbSetFilter() and the SET FILTER command.

Examples
■  The following example sets a filter, lists data as filtered,
   and then clears the filter:

   USE Employee NEW
   dbSetFilter( {|| Age < 40}, "Age < 40" )
   LIST Employee->Name
   dbClearFilter()
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbClearIndex()  | 

Close all indexes for the current work area
Syntax
dbClearIndex() → NIL
Returns
dbClearIndex() always returns NIL.
Description

dbClearIndex() closes any active indexes for the current work area. Any pending index updates are written and the index files are closed.

dbClearIndex() performs the same function as the standard SET INDEX command with no indexes specified. For more information, refer to the SET INDEX command.

Examples
■  The following example clears index files if any are set:

   cFirst := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "FIRSTNAM" )
   dbSetIndex( "LASTNAME" )
   //
   IF IndexOrd() > 0               // is there an index?
      dbClearIndex()               // clear index files
   ELSE
      COPY TO FILE TEMP SDF      // copy to SDF in natural
   ENDIF                           // order
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbClearRelation()Harbour implementation  | 

Clear active relations
Syntax
dbClearRelation() → NIL
Returns
dbClearRelation() always returns NIL.
Description

dbClearRelation() clears any active relations for the current work area.

dbClearRelation() performs the same function as the standard SET RELATION TO command with no clauses specified. For more information, refer to the SET RELATION command.

Examples
■  The following example sets a relation, lists data, and then
   clears the relation:

   USE Employee NEW
   USE Department NEW INDEX Dept
   //
   SELECT Employee
   dbSetRelation("Department", ;
      {|| Employee->Dept}, "Employee->Dept")
   LIST Employee->Name, Department->Name
   dbClearRelation()
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbCloseAll()Harbour implementation  | 

Close all occupied work areas
Syntax
dbCloseAll() → NIL
Returns
dbCloseAll() always returns NIL.
Description
dbCloseAll() releases all occupied work areas from use. It is equivalent to calling dbCloseArea() on every occupied work area. dbCloseAll() has the same effect as the standard CLOSE DATABASES command. For more information, refer to the USE and CLOSE commands.
Examples
■  The following example closes all work areas:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //

   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() )
         IF RLock()
            Sales->( dbRecall() )
            ? "Record deleted: ", Sales( Deleted() )
         ENDIF
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
   dbCloseAll()                  // close all work areas
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbCloseArea()Harbour implementation  | 

Close a work area
Syntax
dbCloseArea() → NIL
Returns
dbCloseArea() always returns NIL.
Description
dbCloseArea() releases the current work area from use. Pending updates are written, pending locks are released, and any resources associated with the work area are closed or released. dbCloseArea() is equivalent to the standard CLOSE command or the USE command with no clauses. For more information, refer to the USE and CLOSE commands.
Examples
■  The following example closes a work area via an alias
   reference:

   cLast := "Winston"
   //
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //
   IF ( Sales->(dbSeek(cLast)) )

      IF Sales->( Deleted() ) .AND. Sales->( RLock() )
         Sales->( dbRecall() )
         ? "Record deleted: ", Sales( Deleted() )
      ENDIF
   ELSE
      ? "Not found"
      Colls->( dbCloseArea() )
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbCommit()Harbour implementation  | 

Flush pending updates
Syntax
dbCommit() → NIL
Returns
dbCommit() always returns NIL.
Description

dbCommit() causes all updates to the current work area to be written to disk. All updated database and index buffers are written to DOS and a DOS COMMIT request is issued for the database (.dbf) file and any index files associated with the work area.

dbCommit() performs the same function as the standard COMMIT command except that it operates only on the current work area. For more information, refer to the COMMIT command.

Notes

■ Network environment: dbCommit() makes database updates visible

to other processes. To insure data integrity, issue dbCommit() before an UNLOCK operation. For more information, refer to the "Network Programming" chapter in the Programming and Utilities Guide.

dbCommit() uses DOS interrupt 21h function 68h to perform the

solid-disk write. It is up to the network operating system to properly implement this request. Check with the network vendor to see if this is supported.

Examples
■  In this example, COMMIT is used to force a write to disk after
   a series of memory variables are assigned to field variables:

   USE Sales EXCLUSIVE NEW
   MEMVAR->Name := Sales->Name

   MEMVAR->Amount := Sales->Amount
   //
   @ 10, 10 GET MEMVAR->Name
   @ 11, 10 GET MEMVAR->Amount
   READ
   //
   IF Updated()
      APPEND BLANK
      REPLACE Sales->Name WITH MEMVAR->Name
      REPLACE Sales->Amount WITH MEMVAR->Amount
      Sales->( dbCommit() )
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbCommitAll()Harbour implementation  | 

Flush pending updates in all work areas
Syntax
dbCommitAll() → NIL
Returns
dbCommitAll() always returns NIL.
Description

dbCommitAll() causes all pending updates to all work areas to be written to disk. It is equivalent to calling dbCommit() for every occupied work area.

For more information, refer to dbCommit() and the COMMIT command.

Notes

dbCommitAll() uses DOS interrupt 21h function 68h to perform

the solid-disk write. It is up to the network operating system to properly implement this request. Check with the network vendor to see if this is supported.

Examples
■  The following example writes all pending updates to disk:

   cLast := "Winston"
   //
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //

   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )

   dbSelectArea( "Sales" )      // select "Sales" work area

   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() ) .AND. Sales( RLock() )
         Sales->( dbRecall() )
         ? "Deleted record has been recalled."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
   //
   // processing done, write updates to disk and close
   dbCommitAll()
   dbCloseAll()
   QUIT
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbCreate()Harbour implementation  | 

Create a database file from a database structure array
Syntax
dbCreate(<cDatabase>, <aStruct>
   [<cDriver>]) → NIL
Arguments
cDatabase is the name of the new database file, with an optional drive and directory, specified as a character string. If specified without an extension, .dbf is assumed.
aStruct is an array that contains the structure of cDatabase as a series of subarrays, one per field. Each subarray contains the definition of each field's attributes and has the following structure:
Field Definition Subarray
    Position     Metasymbol     Dbstruct.ch
    1            cName          DBS_NAME
    2            cType          DBS_TYPE
    3            nLength        DBS_LEN
    4            nDecimals      DBS_DEC
cDriver specifies the replaceable database driver (RDD) to use to process the current work area. cDriver is the name of the RDD specified as a character expression. If you specify cDriver as a literal value, you must enclose it in quotes.
Returns
dbCreate() always returns NIL.
Description

dbCreate() is a database function that creates a database file from an array containing the structure of the file. You may create the array programmatically or by using dbStruct(). dbCreate() is similar to the CREATE FROM command which creates a new database file structure from a structure extended file. Use CREATE or COPY STRUCTURE EXTENDED commands to create a structure extended file.

Before using dbCreate(), you must first create the aStruct array and fill it with the field definition arrays according to the structure in Field Definition Subarray table (above). There are some specific rules for creating a field definition array, including:

■ Specify all field attributes with a value of the proper data

type for the attribute. The decimals attribute must be specified— even for non-numeric fields. If the field does not have a decimals attribute, specify zero.

■ Specify the type attribute using the first letter of the data

type as a minimum. Use longer and more descriptive terms for readability. For example, both "C" and "Character" can be specified as the type attribute for character fields.

■ In CA-Clipper, character fields contain up to 64,000

characters. Unlike the CREATE FROM command, dbCreate() does not use the decimals attribute to specify the high-order part of the field length. Specify the field length directly, regardless of its magnitude.

To make references to the various elements of the field definition subarray more readable, the header file called dbstruct.ch is supplied. It contains the #defines to assign a name to the array position for each field attribute. It is located in \CLIP53\INCLUDE.

Notes

■ Duplicate field names: dbCreate() does not check for duplicate

field names. Therefore, be careful not to use the same field name twice.

EG_ARG error: dbCreate() generates an EG_ARG error if the

filename is NIL.

Examples
■  This example creates an empty array and then adds field
   definition subarrays using the AAdd() function before creating
   People.dbf.  You might use this technique to add field definitions to
   your structure array dynamically:

   aDbf := {}
   AAdd(aDbf, { "Name", "C", 25, 0 })
   AAdd(aDbf, { "Address", "C", 1024, 0 })
   AAdd(aDbf, { "Phone", "N", 13, 0 })
   //
   dbCreate("People", aDbf)

■  This example performs the same types of actions but declares
   the structure array as a two-dimensional array, and then uses
   subscript addressing to specify the field definitions.  It will be
   created using the DBFMDX RDD:

   #include "Dbstruct.ch"
   //
   LOCAL aDbf[1][4]
   aDbf[1][ DBS_NAME ] := "Name"
   aDbf[1][ DBS_TYPE ] := "Character"
   aDbf[1][ DBS_LEN ]  := 25
   aDbf[1][ DBS_DEC ]  := 0
   //
   dbCreate("Name", aDbf, "DBFMDX")
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is dbstruct.ch.
See also

dbCreateIndex()Harbour implementation  | 

Create an index file
Syntax
dbCreateIndex(<cIndexName>, <cKeyExpr>,
   [<bKeyExpr>], [<lUnique>]) → NIL
Arguments
cIndexName is a character value that specifies the file name of the index file to be created.
cKeyExpr is a character value that expresses the index key expression in textual form.
bKeyExpr is a code block that expresses the index key expression in executable form.
lUnique is an optional logical value that specifies whether a unique index is to be created. If lUnique is omitted, the current global _SET_UNIQUE setting is used.
Returns
dbCreateIndex() always returns NIL.
Description

dbCreateIndex() creates an index for the database (.dbf) file associated with the current work area. If the work area has active indexes, they are closed. After the new index is created, it becomes the controlling index for the work area and is positioned to the first logical record.

dbCreateIndex() performs the same function as the standard INDEX command. For more information, refer to the INDEX command.

Notes

■ Side effects: dbCreateIndex() is guaranteed to create an index

that, when made active, will impose the specified logical order on the database. The key expression is not necessarily evaluated at any particular time, by any particular means, or on any particular record or series of records. If the key expression relies on information external to the database file or work area, the effect is unpredictable. If the key expression changes the state of the work area (e.g., by moving to a different record or changing the contents of a record), the effect is unpredictable.

■ Evaluation context: When the key expression is evaluated, the

associated work area is automatically selected as the current work area before the evaluation; the previously selected work area is automatically restored afterward.

■ Network environment: dbCreateIndex() creates the new index for

the exclusive use of the current process.

■ Illegal expression: If cKeyExpr evaluates to an illegal

expression, the code block will always evaluate to end-of-file (EOF).

Examples
■  This example creates an index file, Name, indexed on the Name
   field:

   USE Employees NEW
   dbCreateIndex( "Name", "Name", { || Name })
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbDelete()Harbour implementation  | 

Mark a record for deletion
Syntax
dbDelete() → NIL
Returns
dbDelete() always returns NIL.
Description

dbDelete() marks the current record as deleted. Records marked for deletion can be filtered using SET DELETED or removed from the file using the PACK command.

dbDelete() performs the same function as the standard DELETE command with a scope of the current record. For more information, refer to the DELETE command.

Notes

■ Logical records: If the global _SET_DELETED status is true

(.T.), deleted records are not logically visible. That is, database operations which operate on logical records will not consider records marked for deletion. Note, however, that if _SET_DELETED is true (.T.) when the current record is marked for deletion, the record remains visible until it is no longer the current record.

■ Network environment: For a shared database on a network,

dbDelete() requires the current record to be locked. For more information, refer to the "Network Programming" chapter of the Programming and Utilities Guide.

Examples
■  The following example deletes a record after a successful
   record lock:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( RLock() )
         Sales->( dbDelete() )
         ? "Record deleted: ", Sales->( Deleted() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbEdit()Harbour implementation  | 

Browse records in a table layout
Syntax
dbEdit([<nTop>], [<nLeft>],
   [<nBottom>], <nRight>],
   [<acColumns>],
   [<cUserFunction>],
   [<acColumnSayPictures> | <cColumnSayPicture>],
   [<acColumnHeaders> | <cColumnHeader>],
   [<acHeadingSeparators> | <cHeadingSeparator>],
   [<acColumnSeparators> | <cColumnSeparator>],
   [<acFootingSeparators> | <cFootingSeparator>],
   [<acColumnFootings> | <cColumnFooting>]) → NIL
Arguments
nTop, nLeft, nBottom, and nRight define the upper-left and lower-right coordinates of the dbEdit() window. Row values can range from zero to MaxRow() and column positions can range from zero to MaxCol(). If not specified, the default coordinates are 0, 0, MaxRow(), and MaxCol().
acColumns is an array of character expressions containing database field names or expressions to use as column values for each row displayed. If this argument is not specified, dbEdit() displays all fields in the current work area as columns.
cUserFunction is the name of a user-defined function that executes when an unrecognizable key is pressed or there are no keys pending in the keyboard buffer. Specify the function name as a character expression without parentheses or arguments. Note that the behavior of dbEdit() is affected by the presence of this argument. Refer to the discussion below for more information.
acColumnSayPictures is a parallel array of picture clauses to format each column. Specifying cColumnSayPicture instead of an array displays all columns with the same format. Refer to Transform() or @...SAY for more information on pictures.
acColumnHeaders is a parallel array of character expressions that define the headings for each column. Specifying cColumnHeader gives the same heading for all columns. To display a multi-line heading, embed a semicolon in the heading expression where you want the string to break. If not specified, column headings are taken from the acColumns array or the field names in the current work area, if the acColumns argument is not specified.
acHeadingSeparators is a parallel array of character expressions that define the characters used to draw horizontal lines separating column headings from the field display area. Specifying cHeadingSeparator instead of an array uses the same heading separator for all columns. If this argument is not specified, the default separator is a double graphics line.
acColumnSeparators is a parallel array of character expressions that define the characters used to draw vertical lines separating the columns. Specifying cColumnSeparator instead of an array uses the same separator for all columns. If this argument is not specified, the default separator is a single graphics line.
acFootingSeparators is a parallel array of character expressions that define the characters used to draw horizontal lines separating column footings from the field display area. Specifying cFootingSeparator instead of an array uses the same footing separator for all columns. If this argument is not specified, there is no footing separator.
acColumnFootings is a parallel array of character expressions that define footings for each column. Specifying cColumnFooting instead of an array gives the same footing for all columns. To display a multi- line footing, embed a semicolon in the footing expression where you want the string to break. If this argument is not specified, there are no column footings.
Returns
dbEdit() always returns NIL.
Description

dbEdit() is a user interface and compatibility function that displays records from one or more work areas in a table form. The dbEdit() window display is a grid of cells divided into columns and rows. Columns correspond to database fields and rows correspond to database records. Each column is defined by an element of the acColumns array. The display width of each column is determined by the evaluation of the column expression in acColumns array or the column picture specified in the acColumnSayPictures array.

All cursor movement keys are handled within dbEdit(), including Page up, Page down, Home, End, the four arrow keys, and all Ctrl key combinations that produce cursor movement. The navigation keys that dbEdit() responds to when a user function argument is not specified are listed in the Active Keys table below:

dbEdit() Active Keys

    Key                 Action
    Up arrow            Up one row
    Down arrow          Down one row
    Left arrow          Column left
    Right arrow         Column right
    Ctrl+Left arrow     Pan left one column
    Ctrl+Right arrow    Pan right one column
    Home                Leftmost current screen column
    End                 Rightmost current screen column
    Ctrl+Home           Leftmost column
    Ctrl+End            Rightmost column
    PgUp                Previous screen
    PgDn                Next screen
    Ctrl+PgUp           First row of current column
    Ctrl+PgDn           Last row of current column
    Return              Terminate dbEdit()
    Esc                 Terminate dbEdit()

When the user function argument (cUserFunction) is specified, all keys indicated in the Active Keys table are active with the exception of Esc and Return. When dbEdit() calls the user function, it automatically passes two arguments:

■ The current mode passed as a numeric value

■ The index of the current column in acColumns passed as a

numeric value

The mode parameter indicates the current state of dbEdit() depending on the last key executed. The possible mode values are listed in the dbEdit() Modes table below:

dbEdit() Modes

    Status  Dbedit.ch      Description
    0       DE_IDLE        Idle, any cursor movement keystrokes have been
                           handled and no keystrokes are pending
    1       DE_HITTOP      Attempt to cursor past top of file
    2       DE_HITBOTTOM   Attempt to cursor past bottom of file
    3       DE_EMPTY       No records in work area
    4       DE_EXCEPT      Key exception

The index parameter points to the position of the current column definition in the acColumns array. If acColumns is not specified, the index parameter points to the position of the field in the current database structure. Access the field name using Field().

A user-defined function must return a value that indicates to dbEdit() the action to perform. The User Function Return Values table below lists the possible return values and the corresponding actions:

dbEdit() User Function Return Values

    Value   Dbedit.ch      Description
    0       DE_ABORT       Abort dbEdit()
    1       DE_CONT        Continue dbEdit()
    2       DE_REFRESH     Force reread/repaint and continue; after repaint,
                           process keys and go to idle

A number of instances affect calls to the user function:

■ A key exception occurs. This happens when dbEdit() fetches a

keystroke that it does not recognize from the keyboard. Any pending keys remain in the keyboard buffer until fetched within the user function or until dbEdit() continues.

dbEdit() enters the idle mode (i.e., all pending keys have

been processed). This happens when the keyboard is empty or after a screen refresh. In this instance, there is one call to the user function and then dbEdit() waits for a key.

■ Beginning or end of file is encountered. This is the same as

idle. All executable keys are performed, and there is one call to the user function with the appropriate status message.

Note that when dbEdit() is first executed, all keys pending in the keyboard buffer are executed and then dbEdit() enters the idle mode with a user function call. If no keys are pending, the idle mode is immediate.

The user function should handle all modes and status messages received from dbEdit().

A user-defined function must ensure that the dbEdit() status is equivalent to DE_EXCEPT (4); otherwise, the value of LastKey() is meaningless and a Return value of DE_REFRESH (2) will place the application into an endless loop. For example:

FUNCTION DBEditFunc ( nMode, nColumnPos )

LOCAL RetVal := DE_CONT

IF ( nMode == DE_EXCEPT )

IF ( LastKey() == K_F5 )

RetVal := DE_REFRESH

ENDIF

ENDIF RETURN( RetVal )

dbEdit() is fully re-entrant, which means you can make nested calls to it. Using this feature, you can have multiple browse windows on the screen at the same time.

dbEdit() is a compatibility function and, therefore, no longer recommended as a programmable browse facility. As such, it is superseded by the TBrowse object class. For more information, refer to TBrowse class in this chapter.

Examples
■  This example demonstrates a generic call to dbEdit():

   USE Names NEW
   dbEdit()

■  This example demonstrates calling dbEdit() with a user
   function:

   #include "dbedit.ch"
   #include "inkey.ch"

   // Array must be visible to other user-defined programs in
   // program

   STATIC acColumns := {}

   PROCEDURE Main()

      USE Names NEW
      INDEX ON Names->Lastname + Names->FirstName TO Names

      CLS

      acColumns := { "LastName", "FirstName" }

      dbEdit( 5, 5, 20, 70, acColumns, "UserFunc" )

   RETURN


   FUNCTION UserFunc( nMode, nCol )
      LOCAL nKey := LastKey()
      LOCAL nRetVal := DE_CONT         // Default return value

      DO CASE
      CASE nMode == DE_IDLE
         nRetVal := IdleFunc()
      CASE nMode == DE_HITTOP
         Tone( 100, 3 )
      CASE nMode == DE_HITBOTTOM
         Tone( 100, 3 )
         nRetVal := AppendFunc( nKey )
      CASE nMode == DE_EMPTY
         nRetVal := EmptyFunc()
      CASE nMode == DE_EXCEPT
         nRetVal := ExceptFunc( nKey, nCol )
      OTHERWISE
         Tone( 100, 3 )
      ENDCASE

   RETURN nRetVal

   FUNCTION AppendFunc( nKey )
      LOCAL nRetVal := DE_CONT         // Default return value

      IF nKey == K_DOWN                  // If DOWN ARROW
         APPEND BLANK                  // Append blank record
   // Note: The appended record will appear at the top of the
   //       dbEdit() screen when the database file is indexed.

         nRetVal := DE_REFRESH         // Refresh screen
      ENDIF


   RETURN nRetVal

   FUNCTION ExceptFunc( nKey, nCol )
      LOCAL nRetVal := DE_CONT         // Default return value

      DO CASE
      CASE nKey == K_ESC                  // If ESCAPE
         nRetVal := DE_ABORT               // Exit
      CASE nKey == K_RETURN               // If RETURN
         nRetVal := EditFunc( nCol )      // Function to edit
                                          // field

      // Toggle DELETED status
      CASE nKey == K_DEL .AND. LastRec() != 0  // DELETE pressed
         IF Deleted()
            RECALL
         ELSE
            DELETE
         ENDIF
      OTHERWISE
            Tone( 100, 1 )
      ENDCASE

   RETURN nRetVal


   FUNCTION EditFunc( nCol )
      LOCAL cIndexVal         // Value of current key expression
      LOCAL nRetVal            // Return value
      LOCAL nField            // Position of current field
      LOCAL cFieldVal         // Value of current field
      LOCAL nCursSave         // Preserve state of cursor

      // This will return an error if no index is open
      cIndexVal := &( IndexKey(0) )

      nField := FieldPos( acColumns[nCol] )

      IF nField != 0
         nCursSave := SetCursor()         // Save state of cursor
         SetCursor(1)                     // Change cursor shape
         cFieldVal := FieldGet( nField )         // Save contents
                                                // of field
         @ Row(), Col() GET cFieldVal            // GET new value
         READ
         FieldPut( nField, cFieldVal )            // REPLACE with
                                                // new value
         SetCursor( nCursSave )                  // Restore cursor
                                                // shape
      ENDIF


      IF cIndexVal != &( IndexKey(0) )         // If key expression

                                             // changed
         nRequest := DE_REFRESH               // Refresh screen
      ELSE                                    // Otherwise
         nRequest := DE_CONT                  // Continue
      ENDIF

   RETURN nRequest

   FUNCTION IdleFunc()
      // Idle routine
   RETURN DE_CONT

   FUNCTION EmptyFunc()
      // Empty Records routine
   RETURN DE_CONT
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, header files are dbedit.ch and inkey.ch.
See also

dbEval()Harbour implementation  | 

Evaluate a code block for each record matching a scope and condition
Syntax
dbEval(<bBlock>,
   [<bForCondition>],
   [<bWhileCondition>],
   [<nNextRecords>],
   [<nRecord>],
   [<lRest>]) → NIL
Arguments
bBlock is a code block to execute for each record processed.
bForCondition is an optional condition specified as a code block that is evaluated for each record in the scope. It provides the same functionality as the FOR clause of record processing commands.
bWhileCondition is an optional condition specified as a code block that is evaluated for each record from the current record until the condition returns false (.F.). It provides the same functionality as the WHILE clause of record processing commands.
nNextRecords is an optional number that specifies the number of records to process starting with the current record. It is the same as the NEXT clause.
nRecord is an optional record number to process. If this argument is specified, bBlock will be evaluated for the specified record. This argument is the same as the RECORD clause.
lRest is an optional logical value that determines whether the scope of dbEval() is all records, or, starting with the current record, all records to the end of file. This argument corresponds to the REST and ALL clauses of record processing commands. If true (.T.) , the scope is REST; otherwise, the scope is ALL records. If lRest is not specified the scope defaults to ALL.
Returns
dbEval() always returns NIL.
Description

dbEval() is a database function that evaluates a single block for each record within the current work area that matches a specified scope and/or condition. On each iteration, dbEval() evaluates the specified block. All records within the scope or matching the condition are processed until the end of file is reached.

By default, dbEval() operates on the currently selected work area. It will operate on an unselected work area if you specify it as part of an aliased expression.

dbEval() is similar to AEval() which applies a block to each element in an array. Like AEval(), dbEval() can be used as a primitive for the construction of user-defined commands that process database files. In fact, many of the standard CA-Clipper database processing commands are created using dbEval().

Refer to the Code Blocks section in the "Basic Concepts" chapter of the Programming and Utilities Guide for more information on the syntax and theory of code blocks; and refer also to the Database System section in the same chapter for information on record scoping and conditions. Also refer to the CA-Clipper standard header file, std.ch, found in \CLIP53\INCLUDE for examples of CA-Clipper database command definitions that use dbEval().

Examples
■  This example uses dbEval() to implement Count(), a user-
   defined function that counts the number of records in a work area
   matching a specified scope.  The scope is passed as an array to
   Count().  To make the example more interesting, there is a user-
   defined command to create the scope array, thereby allowing you to
   specify the scope in a familiar form.  Additionally, there is a set
   of manifest constants that define the attributes of the scope object.

   // Scope command definition
   #command CREATE SCOPE <aScope> [FOR <for>] ;
      [WHILE <while>] [NEXT <next>] [RECORD <rec>] ;
      [<rest:REST>] [ALL];
   =>;
      <aScope> := { <{for}>, <{while}>, <next>, ;
         <rec>, <.rest.> }
   //

   // Scope attribute constants
   #define FOR_COND      1
   #define WHILE_COND    2
   #define NEXT_SCOPE    3
   #define REC_SCOPE     4
   #define REST_SCOPE    5
   //
   // Create a scope and count records using it
   LOCAL mySet, myCount
   USE Customer NEW
   CREATE SCOPE mySet FOR Customer = "Smith" WHILE ;
             Zip > "90000"
   myCount := Count( mySet )
   RETURN

   FUNCTION Count( aScope )
      LOCAL nCount := 0
      dbEval( {|| nCount++},;
         aScope[ FOR_COND ],;
         aScope[ WHILE_COND ],;
         aScope[ NEXT_SCOPE ],;
         aScope[ REC_SCOPE ],;
         aScope[ REST_SCOPE ];
      )
      RETURN nCount
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB
See also

dbFieldInfo()Harbour implementation  | 

Return and optionally change information about a field
Syntax
dbFieldInfo(<nInfoType>,
   <nFieldPos>,
   [<expNewSetting>]) → uCurrentSetting
Arguments
nInfoType determines the type of information as specified by the constants below. Note, however, that not all constants are supported for all RDDs, nor are all constants supported by all field types. These constants are defined in the dbstruct.ch header file, which must be included (#include) in your application.
Field Information Type Constants
    Constant            Description
    DBS_BLOB_LEN        Returns the storage length of the data in a BLOB
                        (memo) file.
    DBS_BLOB_OFFSET     Returns the file offset of the data in a BLOB (memo)
                        file.
    DBS_BLOB_POINTER    Returns a numeric pointer to the data in a blob
                        file. This pointer can be used with BLOBDirectGet(),
                        BLOBDirectImport(), etc.
    DBS_BLOB_TYPE       Returns the data type of a BLOB (memo) field. This
                        is more efficient than using Type() or ValType()
                        since the data itself does not have to be retrieved
                        from the BLOB file in order to determine the type.
    DBS_DEC             Number of decimal places for the field.
    DBS_LEN             Length of the field.
    DBS_NAME            Name of the field.
    DBS_TYPE            Data type of the field.
nFieldPos is the position of the field in the database file structure.
expNewSetting is reserved for CA-Clipper future use. It can be omitted or specified as NIL.
Returns
dbFieldInfo() returns the current setting.
Description

dbFieldInfo() retrieves information about the state of a field. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

The field information that is available is defined by the RDD.

To support RDDs for other database models (such as dictionary-based databases) that store more information about each field or column, the CA-Clipper 5.3 RDD API has been enhanced. The dbFieldInfo() is designed to allow for additional nInfoType values that can be defined by third- party RDD developers.

Examples
■  The following example uses dbFieldInfo() to retrieve field
   information:

   #include dbstruct.ch

   QOut(dbFieldInfo(DBS_NAME, 1))         // Same as FieldName(1)

   FUNCTION DBOUTSTRUCT()
      LOCAL aStruct := {}
      LOCAL nFcount, i

      nFcount := FCount()
      FOR i := 1 TO nFcount
         AAdd(aStruct, {FieldName(i), ;
                           dbFieldInfo(DBS_TYPE, i), ;
                           dbFieldInfo(DBS_LEN, i),  ;
                           dbFieldInfo(DBS_DEC, i)})
      NEXT
      RETURN aStruct
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is dbstruct.ch.
See also

dbFileGet()Harbour implementation  | 

Insert the contents of a field into a file
Syntax
dbFileGet(<nFieldPos>, <cTargetFile>, <nMode>)
   → lSuccess
Arguments
nFieldPos is the position of the field in the database file structure.
cTargetFile is the name of the file where the field data will be written, including an optional drive, directory and extension. See SetDefault() and SetPath() for file searching and creation rules. No default extension is assumed.
If cTargetFile does not exist, it is created. If it exists, this function attempts to open the file in exclusive mode and if successful, the file is written to without warning or error. If access is denied because, for example, another proess is using the file, NetErr() is set to TRUE.
nMode is a constant defining the copy mode, as shown in the table below:
dbFileGet() Constants
    Constant            Description
    FILEGET_APPEND      Appends to the file.
    FILEGET_OVERWRITE   Overwrites the file.  This is the default.
Returns
dbFileGet() returns true (.T.) if successful; otherwise it returns false (.F.).
Description

dbFileGet() provides a mechanism for copying the contents of a field into a file. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

dbFileGet() is used in conjunction with dbFilePut() to transfer data back and forth between files and database fields.

Examples
■  This example exports the contents of a field that stores a
   picture to a .GIF file, so that the file can be programmatically
   displayed:

   FUNCTION ShowPix()
      LOCAL cPixFile := "picture.gif"
      LOCAL nPos

      // Customer database with a picture of each
      // customer stored in a field called "Pix"
      USE customer NEW VIA "DBFCDX"
      nPos := FieldPos("Pix")

      // Export the file's data for the current Pix field
      IF ! dbFileGet(nPos, cPixFile, FILEGET_OVERWRITE )
         Alert("Export of picture " + cPixFile +
         " failed!")

      ELSE
         // Code for displaying picture would go here
      ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header is dbinfo.ch
See also

dbFilePut()Harbour implementation  | 

Insert the contents of a file into a field
Syntax
dbFilePut(<nFieldPos>, <cSourceFile>)
   → lSuccess
Arguments
nFieldPos is the position of the field in the database file structure.
cSourceFile is the name of the file containing the data to insert into the specified field, including an optional drive, directory and extension. See SetDefault() and SetPath() for file searching rules. No default extension is assumed.
This function attempts to open cSourceFile in shared mode. If the file does not exist, a runtime error is raised. If the file is successfully opened, the operation proceeds. If access is denied because, for example, another process has exclusive use of the file, NetErr() is set to true (.T.).
Note: There are no restrictions on the size of cSourceFile except that you must have enough disk space to make the copy.
Returns
dbFilePut() returns true (.T.) if successful; otherwise, it returns false (.F.).
Description

dbFilePut() provides a mechanism for copying the contents of a file into a field. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

dbFilePut() is used in conjunction with dbFileGet() to transfer data back and forth between files and database fields. You can use dbFilePut() with a variety of field types, including graphics images, word processor files, and printer fonts. These two functions are excellent for creating databases of documents, graphics, sounds, etc.

Note: DBFieldInfo ( DBS_BLOB_TYPE, nFieldPos ) will return "C" (string) for any memo field created using dbFilePut().

Examples
■  This example imports information from a word processing
   document into a field, then uses BLOBGet() to extract the first 25
   characters of the field:

   FUNCTION Populate()
      USE customer NEW VIA "DBFCDX"
      DO WHILE .NOT. Eof()
         GetPix( "Pix", SubStr(LastName, 1, 4) + CustID)
         Customer->dbSkip()
      ENDDO

   FUNCTION GetPix(cPixField, cPixFile)
      LOCAL nPos
      nPos := FieldPos(cPixField)

      // Import the picture field into the indicated field
      IF ! dbFilePut(nPos, cPixFile)
         Alert("Import of picture " + cPixFile + ;
               " failed!")
      ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB
See also

dbFilter()Harbour implementation  | 

Return the current filter expression as a character string
Syntax
dbFilter() → cFilter
Returns
dbFilter() returns the filter condition defined in the current work area as a character string. If no FILTER has been SET, dbFilter() returns a null string ("").
Description

dbFilter() is a database function used to save and re-execute an active filter by returning the filter expression as a character string that can be later recompiled and executed using the macro operator (&). This function operates like the dbRelation() and dbRSelect() functions which save and re-execute the linking expression of a relation within a work area.

Since each work area can have an active filter, dbFilter() can return the filter expression of any work area. This is done by referring to dbFilter() within an aliased expression as demonstrated below.

Notes

■ Declared variables: A character string returned by dbFilter()

may not operate correctly when recompiled and executed using the macro operator (&) if the original filter expression contained references to local or static variables, or otherwise depended on compile-time declarations.

Examples
■  This example opens two database files, sets two filters, and
   then displays the filter expressions for both work areas:

   USE Customer INDEX Customer NEW
   SET FILTER TO Last = "Smith"
   USE Invoices INDEX Invoices NEW
   SET FILTER TO CustId = "Smi001"
   SELECT Customer
   //
   ? dbFilter()                      // Result: Last = "Smith"
   ? Invoices->(dbFilter())      // Result: Custid = "Smi001"

■  This user-defined function, CreateQry(), uses dbFilter() to
   create a memory file containing the current filter expression in the
   private variable cFilter:

   FUNCTION CreateQry( cQryName )
      PRIVATE cFilter := dbFilter()
      SAVE ALL LIKE cFilter TO (cQryName + ".qwy")
      RETURN NIL

■  You can later RESTORE a query file with this user-defined
   function, SetFilter():

   FUNCTION SetFilter()
   PARAMETER cQryName
      RESTORE FROM &cQryName..qwy ADDITIVE
      SET FILTER TO &cFilter.
      RETURN NIL
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbGoBottom()Harbour implementation  | 

Move to the last logical record
Syntax
dbGoBottom() → NIL
Returns
dbGoBottom() always returns NIL.
Description

dbGoBottom() moves to the last logical record in the current work area.

dbGoBottom() performs the same function as the standard GO BOTTOM command. For more information, refer to the GO command.

Notes

■ Logical records: dbGoBottom() operates on logical records. If

there is an active index, dbGoBottom() moves to the last record in indexed order. If a filter is set, only records which meet the filter condition are considered.

■ Controlling order: If more than one index is active in the

work area, the operation is performed using the controlling order as set by dbSetOrder() or the SET ORDER command. For more information, refer to the SET ORDER command.

■ Network environment: For a shared file on a network, moving to

a different record may cause updates to the current record to become visible to other processes. For more information, refer to the "Network Programming" chapter in the Programming and Utilities Guide. This function will not affect the locked status of any record.

Examples
■  The following example uses dbGoBottom() to position the record
   pointer on the last logical record:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   Sales->( dbGoBottom() )
   IF ( Sales->Last == "Winston" )
      IF RLock()
         Sales->( dbDelete() )
         ? "Record deleted: ", Sales->( Deleted() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   END
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbGoto()Harbour implementation  | 

Position record pointer to a specific identity
Syntax
dbGoto(<xIdentity>) → NIL
Arguments
xIdentity is a unique value guaranteed by the structure of the data file to reference a specific item in a data source (database). In a Xbase data structure (.dbf) xIdentity is the record number. In other data formats, xIdentity is the unique primary key value. xIdentity could be an array offset or virtual memory handle if the data set is in memory instead of on disk.
Returns
dbGoto() always returns NIL.
Description
dbGoto() is a database function that positions the record pointer in the current work area at the specified xIdentity. In an Xbase data structure, this identity is the record number because every record, even an empty record, has a record number. In non-Xbase data structures, identity may be defined as something other than record number.
Examples
■  This example saves the current record number, searches for a
   key, and then restores the record pointer to the saved position:

   FUNCTION KeyExists( xKeyExpr )

      LOCAL nSavRecord := RecNo()      // Save the current record
                                       // pointer position
      LOCAL lFound

      SEEK xKeyExpr
      IF ( lFound := Found() )
      .
      .< statements >
      .
      ENDIF

      dbGoto( nSavRecord )               // Restore the record
                                       // pointer position
      RETURN ( lFound )
Platforms
Available on MS-DOS
See also

dbGoTop()Harbour implementation  | 

Move to the first logical record
Syntax
dbGoTop() → NIL
Returns
dbGoTop() always returns NIL.
Description

dbGoTop() moves to the first logical record in the current work area.

dbGoTop() performs the same function as the standard GO TOP command. For more information, refer to the GO TOP command.

Notes

■ Logical records: dbGoTop() operates on logical records. If

there is an active index, dbGoTop() moves to the first record in indexed order. If a filter is set, only records which meet the filter condition are considered.

■ Controlling order: If more than one index is active in the

work area, the operation is performed using the controlling order as set by dbSetOrder() or the SET ORDER command. For more information, refer to the SET ORDER command.

■ Network environment: For a shared file on a network, moving to

a different record may cause updates to the current record to become visible to other processes. For more information, refer to the "Network Programming" chapter in the Programming and Utilities Guide. This function will not affect the locked status of any record.

Examples
■  This example demonstrates the typical use of dbGoTop():

   dbGoTop()
   WHILE ( !Eof() )
      ? FIELD->Name
      dbSkip()
   END
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbInfo()Harbour implementation  | 

Return and optionally change information about a database file opened in a work area
Syntax
dbInfo(<nInfoType>, [<expNewSetting>])
   → uCurrentSetting
Arguments
nInfoType determines the type of information, as specified by the constants below. Note, however, that not all constants are supported for all RDDs. These constants are defined in the dbinfo.ch header file, which must be included (#include) in your application.
File Information Type Constants
    Constant                 Description
    DBI_ALIAS                Alias name of the work area as a string.
    DBI_BLOB_DIRECT_LEN      Returns the storage length of a data item in a
                             BLOB file.  <expNewSetting> must specify a
                             valid BLOB pointer obtained from
                             dbFieldInfo(DBS_BLOB_POINTER, <nFieldpos>),
                             BLOBDirectPut() or BLOBDirectImport().
    DBI_BLOB_DIRECT_TYPE     Returns the data type of a data item in a BLOB
                             file. <expNewSetting> must specify a valid BLOB
                             pointer obtained from
                             DbFieldInfo (DBS_BLOB_POINTER, <nFieldpos>),
                             BLOBDirectPut(), or BLOBDirectImport().
    DBI_BLOB_INTEGRITY       Tests a BLOB file for the integrity of its
                             internal tables and returns a logical value
                             indicating the success, true (.T.) or failure,
                             false (.F.) of the integrity check.  If the
                             integrity check fails, you can run
                             dbInfo(DBI_BLOB_RECOVER) which will
                             automatically correct the BLOB file's tables.
                             Checking a BLOB file's integrity is a disk
                             intensive operation and should only be
                             performed when the file's integrity is in
                             question.
    DBI_BLOB_OFFSET          Returns the file offset of a data item in a
                             BLOB file. <expNewSetting> must specify a valid
                             BLOB pointer obtained from
                             dbFieldInfo(DBS_BLOB_POINTER, <nFieldpos>),
                             BLOBDirectPut(), or BLOBDirectImport().
    DBI_BLOB_RECOVER         Recovers a damaged BLOB file by correcting its
                             internal tables. You should run this function
                             only is dbInfo(DBI_BLOB_INTEGRITY) returns
                             false (.F.). Note that this function can only
                             correct the BLOB file's internal tables, it
                             cannot restore any data that may have become
                             corrupted.
    DBI_BOF                  Logical value indicating the work area's
                             beginning of file status (see Bof()).
    DBI_CANPUTREC            Logical value indicating whether the work area
                             supports putting records.
    DBI_CHILDCOUNT           Number of relations set from this work area.
    DBI_DB_VERSION           String containing version information of the
                             host RDD.  If the optional <expNewSetting>
                             parameter is provided, and it is one (1), the
                             result is a more detailed version of the
                             version being returned.
    DBI_DBFILTER             Filter expression as a string (see dbFilter()).
    DBI_EOF                  Logical value indicating the work area's end of
                             file status (see Eof()).
    DBI_FCOUNT               Number of fields (see FCount()).
    DBI_FILEHANDLE           Integer representing the DOS file handle for
                             this database file.
    DBI_FOUND                Logical value indicating the success or failure
                             of the last seek operation in the work area
                             (see Found()).
    DBI_FCOUNT               Number of fields (see FCount()).
    DBI_FULLPATH             Returns the full path name of the opened
                             database file.
    DBI_GETDELIMITER         Default delimiter.
    DBI_GETHEADERSIZE        Header size of the file (see Header()).
    DBI_GETLOCKARRAY         Array of locked records.
    DBI_GETRECSIZE           Record size of the file (see RecSize()).
    DBI_ISDBF                Logical value indicating whether the RDD
                             provides support for the .dbf file format.
    DBI_ISFLOCK              File lock status.
    DBI_LASTUPDATE           Last date on which the file was updated (see
                             LUpdate()).
    DBI_LOCKCOUNT            Number of locked records.
    DBI_LOCKOFFSET           Current locking offset as a numeric value.
    DBI_MEMOBLOCKSIZE        Block size for the memo file associated with
                             this database.
    DBI_MEMOEXT              Default extension for the memo file associated
                             with this database.
    DBI_MEMOHANDLE           Integer representing the DOS file handle for
                             the memo file associated with this database
                             file.
    DBI_RDD_VERSION          String containing version information of the
                             RDD for this database.  If the optional
                             <expNewSetting> parameter is provided, and it
                             is one (1), the result is a more detailed
                             version of the version being returned.
    DBI_SETDELIMITER         Default delimiter.
    DBI_SHARED               Shared flag value.
    DBI_TABLEEXT             Database file extension.
    DBI_VALIDBUFFER          Logical value indicating whether the current
                             buffer is valid.
Important! DBI_USER is a constant that returns the minimum value that third-party RDD developers can use for defining new nInfoType parameters. Values less than DBI_USER are reserved for Computer Associates development.
expNewSetting is reserved for RDDs that allow the file information to be changed, in addition to being retrieved. None of the RDDs supplied with CA-Clipper support this argument. It can be omitted or specified as NIL.
Returns
dbInfo() returns the current setting if expNewSetting is not specified, . If expNewSetting is specified, the previous setting is returned.
Description
dbInfo() retrieves information about a database file. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.
Examples
■  The following examples return work area information:

   #include dbinfo.ch

   ? dbInfo(DBI_GETHEADERSIZE)         // Same as Header()
   ? dbInfo(DBI_LASTUPDATE)            // Same as LUpdate()
   ? dbInfo(DBI_GETRECSIZE)            // Same as RecSize()
   ? dbInfo(DBI_FILEHANDLE)            // DOS file handle for
                                       // the current database
                                       // file
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is dbinfo.ch.

dbOrderInfo()Harbour implementation  | 

Return and optionally change information about orders and index files
Syntax
dbOrderInfo(<nInfoType>,   [<cIndexFile>],
   [<cOrder> | <nPosition>],
   [<expNewSetting>]) → uCurrentSetting
Arguments
nInfoType determines the type of information as specified by the constants below. Note, however, that not all constants are supported for all RDDs. These constants are defined in the dbinfo.ch header file, which must be included (#include) in your application.
Order/Index Information Type Constants
    Constant                      Description
    DBOI_CONDITION                For condition of the specified order as a
                                  string.
    DBOI_CUSTOM                   Logical flag indicating whether the
                                  specified order is custom-built (for RDDs
                                  that support custom-built orders).  Note
                                  that although you can turn the custom-
                                  built flag on for a standard order by
                                  specifying true (.T.) for the <uNewSetting>
                                  argument, you cannot turn a custom-built
                                  order into a standard order.  Specifying
                                  false (.F.) for <uNewSetting> is the same
                                  as not specifying the argument at all--
                                  both return the current setting.
    DBOI_EXPRESSION               Order key expression of the specified
                                  order as a string.
    DBOI_FILEHANDLE               Handle of the specified index file as a
                                  number.
    DBOI_HPLOCKING                Logical flag indicating whether the
                                  specified index file uses the high
                                  performance index locking schema.
    DBOI_INDEXEXT (DBOI_BAGEXT)   Default index file extension as a string.
    DBOI_INDEXNAME (DBOI_BAGNAME) Name of the specified index file as a
                                  string.
    DBOI_ISCOND                   Logical flag that determines whether the
                                  specified order was defined using a FOR
                                  condition.
    DBOI_ISDESC                   Logical flag that determines if the
                                  specified order is descending.  For
                                  drivers that support dynamically setting
                                  the descending flag at runtime, specify
                                  the new value as a logical, using
                                  dbOrderInfo(DBOI_ISDESC, [<cIndexFile>],
                                  [<cOrder> | <nPosition>], <lNewSetting>).
                                  The current setting is returned before it
                                  is changed.
    DBOI_KEYADD                   Logical flag indicating whether a key has
                                  been successfully added to the specified
                                  custom-built order.
    DBOI_KEYCOUNT                 Number of keys in the specified order.
    DBOI_KEYDEC                   Number of decimals in the key of the
                                  specified order.
    DBOI_KEYDELETE                Logical flag indicating whether a key has
                                  been successfully deleted from the
                                  specified custom-built order.
    DBOI_KEYGOTO                  Logical flag indicating whether the record
                                  pointer has been successfully moved to a
                                  record specified by its logical record
                                  number in the controlling order.
    DBOI_KEYSINCLUDED             Number of keys included in the specified
                                  order so far.  This is primarily useful
                                  for conditional orders.  It can be used
                                  during the status display process (with
                                  the EVAL clause of the INDEX command).
    DBOI_KEYSIZE                  Size of the key in the specified order as
                                  a number.
    DBOI_KEYTYPE                  Data type of the key in the specified
                                  order as a string.
    DBOI_KEYVAL                   Key value of the current record from the
                                  controlling order.
    DBOI_LOCKOFFSET               Locking offset for the specified index
                                  file as a numeric value.
    DBOI_NAME                     Name of the specified order as a string.
    DBOI_NUMBER                   Numeric position of the specified order in
                                  the order list.
    DBOI_ORDERCOUNT               Number of orders in the specified index
                                  file.
    DBOI_POSITION                 Logical record number of the current
                                  record within the specified order.
    DBOI_RECNO                    Physical record number of the current
                                  record within the specified order.
    DBOI_SCOPEBOTTOM              Bottom boundary of the scope (as a number)
                                  for the specified order.
    DBOI_SCOPEBOTTOMCLEAR         Clears the bottom boundary of the scope
                                  for the specified order.
    DBOI_SCOPETOP                 Top boundary of the scope (as a number)
                                  for the specified order.
    DBOI_SCOPETOPCLEAR            Clears the top boundary of the scope for
                                  the specified order.
    DBOI_SETCODEBLOCK             Key for the specified order as a code
                                  block.
    DBOI_SKIPUNIQUE               Logical flag indicating whether the record
                                  pointer has been successfully moved to the
                                  next or previous unique key in the
                                  controlling order.
    DBOI_UNIQUE                   Logical flag indicating whether the
                                  specified order has the unique attribute
                                  set.
Important! DBOI_USER is a constant that returns the minimum value that third-party RDD developers can use for defining new nInfoType parameters. Values less than DBOI_USER are reserved for Computer Associates development.
cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.
cOrder | nPosition is the name of the order about which you want to obtain information or a number representing its position in the order list. For single-order index files, the order name is the eight-letter index file name. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. Invalid values are ignored. If no index file or order is specified, the controlling order is assumed.
expNewSetting is reserved for RDDs that allow the file information to be changed, in addition to being retrieved. None of the RDDs supplied with CA-Clipper support this argument. It can be omitted or specified as NIL.
Returns
If expNewSetting is not specified, dbOrderInfo() returns the current setting. If expNewSetting is specified, the previous setting is returned.
Description
dbOrderInfo() retrieves information about the orders and index files. By default, dbOrderInfo() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.
Examples
■  This example uses DBOI_NAME to save the current controlling
   order.  After changing to a new controlling order, it uses the saved
   value to restore the original order:

   #include dbinfo.ch

   USE Customer INDEX Name, Serial NEW
   cOrder := dbOrderInfo(DBOI_NAME)               // Name
   Customer->dbSetOrder("Serial")
   ? dbOrderInfo(DBOI_NAME)                     // Serial
   Customer->dbSetOrder(cOrder)
   ? dbOrderInfo(DBOI_NAME)                     // Name

■  This example uses aliased expressions to return the default
   index file extension (using DBOI_INDEXEXT) in two different work
   areas:

   #include dbinfo.ch

   USE Sales INDEX All_Sales VIA "DBFCDX" NEW
   USE Customer INDEX Name, Serial VIA "DBFNTX" NEW
   ? Sales->dbOrderInfo(DBOI_INDEXEXT)                  // .CDX
   ? Customer->dbOrderInfo(DBOI_INDEXEXT)               // .NTX

■  In this example, dbOrderInfo(DBOI_INDEXEXT) checks for the
   existence of the Customer index file independent of the RDD linked
   into the current work area:

   #include dbinfo.ch

   USE Customer NEW
   IF !FILE( "Customer" + dbOrderInfo(DBOI_INDEXEXT))
            Customer->dbCreateIndex("Customer", "CustName",;
                                          {||Customer->CustName} )
   ENDIF

■  This example accesses the key expression of several orders
   from the same index file:

   #include dbinfo.ch

   USE Customer INDEX All_Cust VIA "DBFMDX" NEW
   Customer->dbSetOrder("Serial")
   ? dbOrderInfo(DBOI_EXPRESSION,, "Name")
   // Result: key expression for name order
   ? dbOrderInfo(DBOI_EXPRESSION,, "Serial")
   // Result: key expression for serial order

■  This example uses dbOrderInfo() as part of a TOTAL ON key
   expression.  Since dbOrderInfo() returns the expression as a string,
   it is specified using a macro expression to force evaluation of the
   key expression:

   #include dbinfo.ch

   USE Sales INDEX Salesman NEW
   TOTAL ON &(dbOrderInfo(DBOI_EXPRESSION)) ;
      FIELDS SaleAmount TO Summary

■  In this example, All_Cust.mdx contains three orders named
   CuAcct, CuName, CuZip.  The DBOI_INDEXNAME constant is used to
   display the name of the index file using one of its orders:

   #include dbinfo.ch

   USE Customer VIA "DBFNTX" NEW
   Customer->dbSetIndex("All_Cust")
   ? dbOrderInfo(DBOI_INDEXNAME,, "CuName")
   // Returns: All_Cust

■  The following example searches for CuName in the order list:

   #include dbinfo.ch

   USE Customer VIA "DBFNTX" NEW
   Customer->dbSetIndex("CuAcct")
   Customer->dbSetIndex("CuName")
   Customer->dbSetIndex("CuZip")
   ? dbOrderInfo(DBOI_NUMBER,, "CuName")            // 2

■  This example retrieves the FOR condition from an order:

   #include dbinfo.ch

   USE Customer NEW
   INDEX ON Customer->Acct TO Customer ;
      FOR Customer->Acct > "AZZZZZ"
   ? dbOrderInfo(DBOI_CONDITION,, "Customer")
   // Returns: Customer->Acct > "AZZZZZ"
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is dbinfo.ch.
See also

dbRecall()Harbour implementation  | 

Reinstate a record marked for deletion
Syntax
dbRecall() → NIL
Returns
dbRecall() always returns NIL.
Description

dbRecall() causes the current record to be reinstated if it is marked for deletion.

dbRecall() performs the same function as the RECALL command. For more information, refer to the DELETE and RECALL commands.

Notes

■ Logical records: Reinstating a deleted record affects the

record's logical visibility if the global _SET_DELETED status is true (.T.). For more information, refer to the dbDelete() function and the DELETE and RECALL commands.

■ Network environment: For a shared database on a network,

dbRecall() requires the current record to be locked. For more information, refer to the "Network Programming" chapter in the Programming and Utilities Guide.

Examples
■  The following example recalls a record if it is deleted and
   attempts to lock the record if successful:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() )
         IF Sales( RLock() )
            Sales( dbRecall() )
            ? "Record recalled"
         ELSE
            "Unable to lock record..."
         ENDIF
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbRecordInfo()Harbour implementation  | 

Return and optionally change information about a record
Syntax
dbRecordInfo(<nInfoType>,
   [<nRecord>],
   [<expNewSetting>]) → uCurrentSetting
Arguments
nInfoType determines the type of information, as specified by the constants below. Note, however, that not all constants are supported for all RDDs. These constants are defined in the dbinfo.ch header file, which must be included (#include) in your application.
Record Information Type Constants
    Constant       Description
    DBRI_DEL       Deleted flag status of the record
    DBRI_LOCK      Locked flag status of the record
    DBRI_SIZE      Length of the record
    DBRI_RECNO     Position of the record
    DBRI_UPDAT     Updated flag status of the record
Important! DBI_USER is a constant that returns the minimum value that third-party RDD developers can use for defining new nInfoType parameters. Values less than DBI_USER are reserved for Computer Associates development.
nRecord is the record to obtain information. If omitted, the current record is used.
expNewSetting is reserved for RDDs that allow the file information to be changed, in addition to being retrieved. None of the RDDs supplied with CA-Clipper support this argument. It can be omitted or specified as NIL.
Returns
If expNewSetting is not specified, dbRecordInfo() returns the current setting. If expNewSetting is specified, the previous setting is returned.
Description

dbRecordInfo() retrieves information about the state of a record (row). The type of information is specified by the nInfoType parameter. By default, this function operates on the currently selected record.

dbRecordInfo() is designed to allow for additional nInfoType values that can be defined by third-party RDD developers.

Examples
■  The following example uses dbRecordInfo() to retrieve field
   information:

   #include "Dbinfo.ch"

   dbRecordInfo(DBRI_SIZE)               // Same as RecSize()

   dbRecordInfo(DBRI_LOCK, 200)         // Is record 200 locked?

   dbRecordInfo(DBRI_DEL, 201)         // Is record 201 locked?

   dbRecordInfo(DBRI_UPDAT)            // Is the current record
                                       // updated?

   dbRecordInfo(DBRI_RECNO, 230)         // On which position is

                                       // record 230?
                                       // If no orders are active,
                                       // the position is 230;
                                       // otherwise, the relative
                                       // position within the order
                                       // will be returned.
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is dbinfo.ch.
See also

dbReindex()  | 

Recreate all active indexes for the current work area
Syntax
dbReindex() → NIL
Returns
dbReindex() always returns NIL.
Description

dbReindex() rebuilds all active indexes associated with the current work area. After the indexes are recreated, the work area is moved to the first logical record in the controlling order.

dbReindex() performs the same function as the standard REINDEX command. For more information, refer to the REINDEX command.

Examples
■  The following example reindexes the work area:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF RLock()
         DELETE FOR Sales->LastName == "Winston"
         Sales->( dbReindex() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbRelation()Harbour implementation  | 

Return the linking expression of a specified relation
Syntax
dbRelation(<nRelation>) → cLinkExp
Arguments
nRelation is the position of the desired relation in the list of current work area relations. The relations are numbered according to the order in which they were defined with SET RELATION.
Returns
dbRelation() returns a character string containing the linking expression of the relation specified by nRelation. If there is no RELATION SET for nRelation, dbRelation() returns a null string ("").
Description

dbRelation() is a database function used with dbRSelect() to determine the linking expression and work area of an existing relation created with the SET RELATION command.

dbRelation() returns the linking expression defined by the TO clause. dbRSelect() returns the work area linked as defined by the INTO clause.

By default, dbRelation() operates on the currently selected work area. It will operate on an unselected work area if you specify it as part of an aliased expression (see example below).

Notes

■ Declared variables: A character string returned by

dbRelation() may not operate correctly when recompiled and executed using the macro operator (&) if the original expression contained references to local or static variables, or otherwise depends on compile-time declarations.

Examples
■  This example opens three database files, sets two child
   relations from the parent work area, and then displays the linking
   expression to the second child work area:

   USE Invoices INDEX Invoices NEW
   USE BackOrder INDEX BackOrder NEW
   USE Customer INDEX Customer NEW
   SET RELATION TO CustNum INTO Invoices, OrderNum ;
         INTO BackOrder
   //
   ? dbRelation(2)                  // Result: OrderNum

■  Later you can query the same linking expression from an
   unselected work area by using an aliased expression like this:

   USE Archive NEW
   ? Customer->(dbRelation(2))   // Result: OrderNum

■  This example is a user-defined function, Relation(), that
   returns the results of both dbRelation() and dbRSelect() as an array:

   FUNCTION Relation( nRelation )
      RETURN { dbRelation(nRelation), ;
            Alias(dbRSelect(nRelation)) }
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbRLock()Harbour implementation  | 

Lock the record at the current or specified identity
Syntax
dbRLock([<xIdentity>]) → lSuccess
Arguments
xIdentity is a unique value guaranteed by the structure of the data file to reference a specific item in a data source (database). In a .dbf xIdentity is the record number. In other data formats, xIdentity is the unique primary key value.
Returns
dbRLock() returns lSuccess, a logical data type that is true (.T.) if successful, false (.F.) if unsuccessful.
Description

dbRLock() is a database function that locks the record identified by the value xIdentity. In Xbase, xIdentity is the record number.

If you do not specify xIdentity, all record locks are released and the current record is locked. If you specify xIdentity, dbRLock() attempts to lock it and, if successful, adds it to the locked record list.

Examples
■  This example shows two different methods for locking multiple
   records:

FUNCTION dbRLockRange( nLo, nHi )

         LOCAL nRec
         FOR nRec := nLo TO nHi

            IF ! dbRLock( nRec )
               dbRUnlock()      // Failed - unlock everything
            ENDIF
         NEXT
      RETURN dbRLockList()      // Return array of actual locks

   FUNCTION dbRLockArray( aList )

         LOCAL nElement, nLen, lRet
         lRet := .T.
         nLen := Len( aList )
         FOR nElement := 1 TO nLen
            IF ! dbRLock( aList[ nElement ] )
               dbRUnlock()      // Failed - unlock everything
               lRet := .F.
            ENDIF
         NEXT
      RETURN dbRLockList()
Platforms
Available on MS-DOS
See also

dbRLockList()Harbour implementation  | 

Return an array of the current lock list
Syntax
dbRLockList() → aRecordLocks
Returns
dbRLockList() returns an array of the locked records in the current or aliased work area.
Description
dbRLockList() is a database function that returns a one-dimensional array that contains the identities of record locks active in the selected work area.
Examples
ROCEDURE PrintCurLocks()

OCAL aList
OCAL nSize
OCAL nCount

List := dbRLockList()
Size := Len( aList )

 "Currently locked records: "
OR nCount := 1 TO nSize
  ?? aList[ nCount ]
  ?? Space( 1 )

   NEXT
   ?

   RETURN
Platforms
Available on MS-DOS
See also

dbRSelect()Harbour implementation  | 

Return the target work area number of a relation
Syntax
dbRSelect(<nRelation>) → nWorkArea
Arguments
nRelation is the position of the desired relation in the list of current work area relations. The relations are numbered according to the order in which they were defined with SET RELATION.
Returns
dbRSelect() returns the work area number of the relation specified by nRelation as an integer numeric value. If there is no RELATION SET for nRelation, dbRSelect() returns zero.
Description

dbRSelect() is a database function used in combination with dbRelation() to determine the work area and linking expression of an existing relation created with the SET RELATION command. dbRSelect() returns the work area defined by the INTO clause. dbRelation() returns the linking expression defined by the TO clause. To determine the alias of the relation instead of the work area number, use the expression Alias(dbRSelect(nRelation)).

By default, dbRSelect() operates on the currently selected work area. It will operate on an unselected work area if you specify it as part of an aliased expression (see example below).

Examples
■  This example opens three database files, sets two child
   relations from the parent work area, and then displays the linking
   expression to the second child work area, as well as the target work
   area of the relation:

   USE Invoices INDEX Invoices NEW
   USE BackOrder INDEX BackOrder NEW
   USE Customer INDEX Customer NEW
   SET RELATION TO CustNum INTO Customer, ;
         OrderNum INTO BackOrder
   //
   ? dbRelation(2), dbRSelect(2)         // Result: OrderNum 3

   ? Alias(dbRSelect(2))               // Result: BACKORDER

■  Later, you can query the same information from an unselected
   work area by using an aliased expression:

   USE Archive NEW
   ? Customer->(dbRelation(2))      // Result: OrderNum
   ? Customer->(dbRSelect(2))         // Result: 3
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbRUnlock()Harbour implementation  | 

Release all or specified record locks
Syntax
dbRUnlock([<xIdentity>]) → NIL
Arguments
xIdentity is a unique value guaranteed by the structure of the data file to reference a specific item in a data source (database). In a .dbf xIdentity is the record number. In other data formats, xIdentity is the unique primary key value.
Returns
dbRUnlock() always returns NIL.
Description
dbRUnlock() is a database function that releases the lock on xIdentity and removes it from the Lock List. If xIdentity is not specified, all record locks are released.
Examples
PROCEDURE dbRUnlockRange( nLo, nHi )

   LOCAL nCounter

   // Unlock the records in the range from nLo to nHi
   FOR nCounter := nLo TO nHi
      dbRUnlock( nCounter )
   NEXT

   RETURN
Platforms
Available on MS-DOS
See also

dbSeek()Harbour implementation  | 

Move to the record having the specified key value
Syntax
dbSeek(<expKey>, [<lSoftSeek>], [<lLast>]) → lFound
Arguments
expKey is a value of any type that specifies the key value associated with the desired record.
lSoftSeek is an optional logical value that specifies whether a soft seek is to be performed. This determines how the work area is positioned if the specified key value is not found (see below). If lSoftSeek is omitted, the current global _SET_SOFTSEEK setting is used.
lLast is specified as true (.T.) to seek the last occurrence of the specified key value. False (.F.), the default, seeks the first occurrence.
Note: This parameter is only supported for specific RDDs. DBFNTX is NOT one of them.
Returns
dbSeek() returns true (.T.) if the specified key value was found; otherwise, it returns false (.F.).
Description

dbSeek() moves to the first logical record whose key value is equal to expKey. If such a record is found, it becomes the current record and dbSeek() returns true (.T.); otherwise, it returns false (.F.). the positioning of the work area is as follows: for a normal (not soft) seek, the work area is positioned to LastRec() + 1 and Eof() returns true (.T.); for a soft seek, the work area is positioned to the first record whose key value is greater than the specified key value. If no such record exists, the work area is positioned to LastRec() + 1 and Eof() returns true (.T.).

For a work area with no active indexes, dbSeek() has no effect.

dbSeek() performs the same function as the standard SEEK command. For more information, refer to the SEEK command.

Notes

■ Logical records: dbSeek() operates on logical records which

are considered in indexed order. If a filter is set, only records which meet the filter condition are considered.

■ Controlling order: If the work area has more than one active

index, the operation is performed using the controlling order as set by dbSetOrder() or the SET ORDER command. For more information, refer to the SET ORDER command.

■ Network environment: For a shared file on a network, moving

to a different record may cause updates to the current record to become visible to other processes. For more information, refer to the "Network Programming" chapter in the Programming and Utilities Guide. This function will not affect the locked status of any record.

Examples
■  In this example, dbSeek() moves the pointer to the record in
   the database, Employee, in which the value in FIELD "cName" matches
   the entered value of cName:

   ACCEPT "Employee name: " TO cName
   IF ( Employee->(dbSeek(cName)) )
      Employee->(VIEWRECORD())
   ELSE
      ? "Not found"
   END
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbSelectArea()Harbour implementation  | 

Change the current work area
Syntax
dbSelectArea(<nArea> | <cAlias>) → NIL
Arguments
nArea is a numeric value between zero and 250, inclusive, that specifies the work area being selected.
cAlias is a character value that specifies the alias of a currently occupied work area being selected.
Returns
dbSelectArea() always returns NIL.
Description
dbSelectArea() causes the specified work area to become the current work area. All subsequent database operations will apply to this work area unless another work area is explicitly specified for an operation. dbSelectArea() performs the same function as the standard SELECT command. For more information, refer to the SELECT command.
Notes

■ Selecting zero: Selecting work area zero causes the lowest

numbered unoccupied work area to become the current work area.

■ Aliased expressions: The alias operator (->) can temporarily

select a work area while an expression is evaluated and automatically restore the previously selected work area afterward. For more information, refer to the alias operator (->).

Examples
■  The following example selects a work area via the alias name:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() ) .AND. Sales->( RLock() )
         Sales->( dbRecall() )
         ? "Deleted record has been recalled."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbSetDriver()Harbour implementation  | 

Return the default database driver and optionally set a new driver
Syntax
dbSetDriver([<cDriver>]) → cCurrentDriver
Arguments
cDriver is an optional character value that specifies the name of the database driver that should be used to activate and manage new work areas when no driver is explicitly specified.
Returns
dbSetDriver() returns the name of the current default driver.
Description
dbSetDriver() sets the database driver to be used when activating new work areas without specifying a driver. If the specified driver is not available to the application, the call has no effect. dbSetDriver() returns the name of the current default driver, if any.
Examples
■  This example makes the "DBFNDX" driver the default driver.  If
   the driver is unavailable, a message is issued:

   dbSetDriver("DBFNDX")
   IF ( dbSetDriver() <> "DBFNDX" )
      ? "DBFNDX driver not available"
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbSetFilter()Harbour implementation  | 

Set a filter condition
Syntax
dbSetFilter(<bCondition>, [<cCondition>]) → NIL
Arguments
bCondition is a code block that expresses the filter condition in executable form.
cCondition stores the filter condition as a character string for later retrieval by the dbFilter() function. If you omit this optional parameter, the dbFilter() function will return an empty string for the work area.
Returns
dbSetFilter() always returns NIL.
Description

dbSetFilter() sets a logical filter condition for the current work area. When a filter is set, records which do not meet the filter condition are not logically visible. That is, database operations which act on logical records will not consider these records.

The filter expression supplied to dbSetFilter() evaluates to true (.T.) if the current record meets the filter condition; otherwise, it should evaluate to false (.F.).

The filter expression may be a code block (bCondition) or both a code block and equivalent text (cCondition). If both versions are supplied, they must express the same condition. If the text version is omitted, dbFilter() will return an empty string for the work area.

dbSetFilter() performs the same function as the standard SET FILTER command. For more information, refer to the SET FILTER command.

Notes

■ Logical records: dbSetFilter() affects the logical visibility

of records (see above).

■ Side effects: Setting a filter condition is only guaranteed to

restrict visibility of certain records as described above. The filter expression is not necessarily evaluated at any particular time, by any particular means, or on any particular record or series of records. If the filter expression relies on information external to the database file or work area, the effect is unpredictable. If the filter expression changes the state of the work area (e.g., by moving to a different record or changing the contents of a record), the effect is unpredictable.

■ Evaluation context: When the filter expression is evaluated,

the associated work area is automatically selected as the current work area before the evaluation; the previously selected work area is automatically restored afterward.

Examples
■  This example limits data access to records in which the Age
   field value is less than 40:

   USE Employee NEW
   dbSetFilter( {|| Age < 40}, "Age < 40" )
   dbGoTop()
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbSetIndex()  | 

Empty orders from an order bag into the order list
Syntax
dbSetIndex(<cOrderBagName>) → NIL
Arguments
cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.
Returns
dbSetIndex() always returns NIL.
Description

dbSetIndex() is a database function that adds the contents of an order bag into the order list of the current work area. Any orders already associated with the work area continue to be active. If the newly opened order bag is the only order associated with the work area, it becomes the controlling order; otherwise, the controlling order remains unchanged. If the order bag contains more than one order, and there are no other orders associated with the work area, the first order in the new order bag becomes the controlling order.

Note: dbSetIndex() does not close all currently open index files.

dbSetIndex() is a compatibility command and therefore is not recommended. It is superseded by the ordListAdd() function.

Examples
USE Customer NEW
dbSetIndex( "Cust01" )         // Open the index Cust01
                              // in the current work area
dbSetIndex( "Cust02" )         // Open the index Cust02
                              // leaving Cust01 open
Platforms
Available on MS-DOS
See also

dbSetOrder()Harbour implementation  | 

Set the controlling order
Syntax
dbSetOrder(<nOrderNum>) → NIL
Arguments
nOrderNum is a numeric value that specifies which of the active indexes is to be the controlling index.
Returns
dbSetOrder() always returns NIL.
Description

dbSetOrder() controls which of the current work area's active indexes is the controlling index. The controlling index is the index which determines the logical order of records in the work area.

Active indexes are numbered from 1 to the number of active indexes, based on the order in which the indexes were opened. nOrderNum specifies the number of the desired index.

dbSetOrder() performs the same function as the standard SET ORDER command. For more information, refer to the SET ORDER command.

Notes

■ Setting order to zero: Setting order to zero causes the work

area to be accessed in natural (record number) order. Only the logical order of the records is affected; any open indexes continue to be active and are properly maintained.

Examples
■  This example sets the second named index, Age, as the
   controlling index:

   USE Employee NEW
   SET INDEX TO Name, Age
   dbSetOrder(2)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbSetRelation()Harbour implementation  | 

Relate two work areas
Syntax
dbSetRelation(<nArea> | <cAlias>, <bExpr>, <cExpr>)
   → NIL
Arguments
nArea is a numeric value that specifies the work area number of the child work area.
cAlias is a character value that specifies the alias of the child work area.
bExpr is a code block that expresses the relational expression in executable form.
cExpr is a character value that expresses the relational expression in textual form.
Returns
dbSetRelation() always returns NIL.
Description

dbSetRelation() relates the work area specified by nArea or cAlias (the child work area) to the current work area (the parent work area). Any existing relations remain active.

Relating work areas synchronizes the child work area with the parent work area. This is achieved by automatically repositioning the child work area whenever the parent work area moves to a new record. If there is an active index in the child work area, moving the parent work area causes an automatic SEEK operation in the child work area; the seek key is based on the expression specified by bExpr and/or cExpr. If the child work area has no active index, moving the parent work area causes an automatic GOTO in the child work area; the record number for the GOTO is based on the expression specified by bExpr and/or cExpr.

The relational expression may be a code block (bExpr) or both a code block and equivalent text (cExpr). If both versions are supplied, they must be equivalent. If the text version is omitted, dbRelation() will return an empty string for the relation.

dbSetRelation() performs the same function as the standard SET RELATION command with the ADDITIVE clause. For more information, refer to the SET RELATION command.

Notes

■ Side effects: dbSetRelation() is only guaranteed to

synchronize the work areas as described above. The relational expression is not necessarily evaluated at any particular time, by any particular means, or on any particular record or series of records. If the relational expression relies on information external to the parent work area or its associated database file, the effect is unpredictable. If the expression changes the state of either work area (e.g., by moving to a different record or changing the contents of a record), the effect is unpredictable.

■ Evaluation context: When the relational expression is

evaluated, the parent work area is automatically selected as the current work area before the evaluation; the previously selected work area is automatically restored afterward.

■ Soft seeking: Seek operations that occur as part of relational

positioning are never soft seeks. If a relational movement is unsuccessful, the child work area is positioned to LastRec() + 1, its Found() status returns false (.F.), and its Eof() status returns true (.T.).

Examples
■  This example demonstrates a typical use of the dbSetRelation()
   function:

   USE Employee NEW
   USE Department NEW INDEX Dept
   SELECT Employee
   dbSetRelation("Department", {|| Employee->Dept},;
                   "Employee->Dept")
   LIST Employee->Name, Department->Name
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbSkip()Harbour implementation  | 

Move relative to the current record
Syntax
dbSkip([<nRecords>]) → NIL
Arguments
nRecords is the number of logical records to move, relative to the current record. A positive value means to skip forward, and a negative value means to skip backward. If nRecords is omitted, a value of 1 is assumed.
Returns
dbSkip() always returns NIL.
Description

dbSkip() moves either forward or backward relative to the current record. Attempting to skip forward beyond the last record positions the work area to LastRec() + 1 and Eof() returns true (.T.). Attempting to skip backward beyond the first record positions the work area to the first record and Bof() returns true (.T.).

dbSkip() performs the same function as the standard SKIP command. For more information, refer to the SKIP command.

Notes

■ Logical records: dbSkip() operates on logical records. If

there is an active index, records are considered in indexed order. If a filter is set, only records which meet the filter condition are considered.

■ Controlling order: If the work area has more than one active

index, the skip operation is performed using the controlling order as set by dbSetOrder() or the SET ORDER command. For more information, refer to the SET ORDER command.

■ Network environment: For a shared file on a network, moving to

a different record may cause updates to the current record to become visible to other processes. For more information, refer to the "Network Programming" chapter in the Programming and Utilities Guide.

Examples
■  This example demonstrates a typical use of the dbSkip()
   function:

   dbGoTop()

   DO WHILE ( !Eof() )
      ? FIELD->Name
      dbSkip()
   ENDDO
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbStruct()Harbour implementation  | 

Create an array containing the structure of a database file
Syntax
dbStruct() → aStruct
Returns
dbStruct() returns the structure of the current database file in an array whose length is equal to the number of fields in the database file. Each element of the array is a subarray containing information for one field. The subarrays have the following format:
dbStruct() Return Array
    Position     Metasymbol     Dbstruct.ch
    1            cName          DBS_NAME
    2            cType          DBS_TYPE
    3            nLength        DBS_LEN
    4            nDecimals      DBS_DEC
If there is no database file in USE in the current work area, dbStruct() returns an empty array ({}).
Description

dbStruct() is a database function that operates like COPY STRUCTURE EXTENDED by creating an array of structure information rather than a database file of structure information. There is another function, dbCreate(), that can create a database file from the structure array.

By default, dbStruct() operates on the currently selected work area. It will operate on an unselected work area if you specify it as part of an aliased expression as shown below.

Note, a header file, dbstruct.ch, located in \CLIP53\INCLUDE contains a series of manifest constants for each field attribute.

Examples
■  This example opens two database files and then creates an
   array containing the database structure using dbStruct() within an
   aliased expression.  The field names are then listed using AEval():

   #include "Dbstruct.ch"
   //
   LOCAL aStruct
   USE Customer NEW
   USE Invoices NEW
   //
   aStruct := Customer->(dbStruct())
   AEval( aStruct, {|aField| QOut(aField[DBS_NAME])} )
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is dbstruct.ch.
See also

dbUnlock()Harbour implementation  | 

Release all locks for the current work area
Syntax
dbUnlock() → NIL
Returns
dbUnlock() always returns NIL.
Description

dbUnlock() releases any record or file locks obtained by the current process for the current work area. dbUnlock() is only meaningful on a shared database in a network environment.

dbUnlock() performs the same function as the standard UNLOCK command. For more information, refer to the UNLOCK command.

Notes

■ Network environment: Releasing locks may cause updates to the

database to become visible to other processes. For more information, refer to the "Network Programming" chapter in the Programming and Utilities Guide.

Examples
■  The following example illustrates a basic use of the
   dbUnlock() function:

   cLast := "Winston"
   USE Sales SHARED NEW VIA "DBFNTX"
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( RLock() )
         Sales->( dbDelete() )

         ? "Record deleted: ", Sales( Deleted() )
         Sales->( dbUnlock() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbUnlockAll()Harbour implementation  | 

Release all locks for all work areas
Syntax
dbUnlockAll() → NIL
Returns
dbUnlockAll() always returns NIL.
Description

dbUnlockAll() releases any record or file locks obtained by the current process for any work area. dbUnlockAll() is only meaningful on a shared database in a network environment. It is equivalent to calling dbUnlock() on every occupied work area.

dbUnlockAll() performs the same function as the UNLOCK ALL command. For more information, refer to the UNLOCK ALL command.

Examples
■  The following example marks a record for deletion if an
   RLock() attempt is successful, then clears all locks in all work
   areas:

   cLast := "Winston"
   USE Sales SHARED NEW VIA "DBFNTX"
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   USE Colls SHARED NEW VIA "DBFNTX"
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //
   IF ( Colls->(dbSeek(cLast)) )
      IF Colls->( Deleted() )
         ? "Record deleted: ", Colls->( Deleted() )

         IF Colls->( RLock() )
            Colls->( dbRecall() )
            ? "Record recalled..."
         ENDIF
      ENDIF
   ELSE
      ? "Not found"
      dbUnlockAll()            // remove all locks in
   ENDIF                        // all work areas
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

dbUseArea()Harbour implementation  | 

Use a database file in a work area
Syntax
dbUseArea( [<lNewArea>], [<cDriver>], <cName>, [<xcAlias>],
  [<lShared>], [<lReadonly>]) → NIL
Arguments
lNewArea is an optional logical value. A value of true (.T.) selects the lowest numbered unoccupied work area as the current work area before the use operation. If lNewArea is false (.F.) or omitted, the current work area is used; if the work area is occupied, it is closed first.
cDriver is an optional character value. If present, it specifies the name of the database driver which will service the work area. If cDriver is omitted, the current default driver is used (see note below).
cName specifies the name of the database (.dbf) file to be opened.
xcAlias is an optional character value. If present, it specifies the alias to be associated with the work area. The alias must constitute a valid CA-Clipper identifier. A valid xcAlias may be any legal identifier (i.e., it must begin with an alphabetic character and may contain numeric or alphabetic characters and the underscore). Within a single application, CA-Clipper will not accept duplicate aliases. If xcAlias is omitted, a default alias is constructed from cName.
lShared is an optional logical value. If present, it specifies whether the database (.dbf) file should be accessible to other processes on a network. A value of true (.T.) specifies that other processes should be allowed access; a value of false (.F.) specifies that the current process is to have exclusive access. If lShared is omitted, the current global _SET_EXCLUSIVE setting determines whether shared access is allowed.
lReadonly is an optional logical value that specifies whether updates to the work area are prohibited. A value of true (.T.) prohibits updates; a value of false (.F.) permits updates. A value of true (.T.) also permits read-only access to the specified database (.dbf) file. If lReadonly is omitted, the default value is false (.F.).
Returns
dbUseArea() always returns NIL.
Description
dbUseArea() associates the specified database (.dbf) file with the current work area. It performs the same function as the standard USE command. For more information, refer to the USE command.
Notes

■ Current driver: If no driver is specified in the call to

dbUseArea() the default driver is used. If more than one driver is available to the application, the default driver is the driver specified in the most recent call to dbSetDriver(). If dbSetDriver() has not been called, the DBFNTX driver is used. If the default driver is undetermined, DBFNTX will be used.

Examples
■  This example is a typical use of the dbUseArea() function:

   dbUseArea(.T., "DBFNDX", "Employees")
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Date()Harbour implementation  | 

Return the system date as a date value
Syntax
Date() → dSystem
Returns
Date() returns the system date as a date value.
Description

Date() is a date function that provides a means of initializing memory variables to the current date, comparing other date values to the current date, and performing date arithmetic relative to the current date.

The display format for dates is controlled by the SET DATE command. The default format is mm/dd/yy.

Examples
■  These examples show the Date() function used in various ways:

   ? Date()                 // Result: 09/01/90
   ? Date() + 30            // Result: 10/01/90
   ? Date() - 30            // Result: 08/02/90
   dDate := Date()
   ? CMonth(dDate)          // Result: September
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Day()Harbour implementation  | 

Return the day of the month as a numeric value
Syntax
Day(<dDate>) → nDay
Arguments
dDate is a date value to convert.
Returns
Day() returns a number in the range of zero to 31 as an integer numeric value. If the month is February, leap years are considered. If the date argument is February 29 and the year is not a leap year, Day() returns zero. If the date argument is empty, Day() returns zero.
Description
Day() is a date conversion function used to convert a date value to the day of a month. This function is used in combination with CMonth() and Year() to format dates. In addition, it is often used in various date calculations.
Examples
■  These examples show the Day() function used several ways:

   ? Date()                             // Result: 09/01/90
   ? Day(Date())                        // Result: 1
   ? Day(Date()) + 1                    // Result: 2
   ? Day(CToD("12/01/94"))              // Result: 1

■  This example uses Day() in combination with CMonth() and
   Year() to format a date value:

   ? CMonth(Date()) + Str(Day(Date())) +;
      "," + Str(Year(Date()))      // Result: June 15, 1990
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Dbf()*Harbour implementation  | 

Return current alias name
Syntax
Dbf() → cAlias
Returns
Dbf() returns the alias of the current work area as a character string. If there is no active database file in the current work area, Dbf() returns a null string ("").
Description

Dbf() is a compatibility function that replicates the Dbf() function in dBASE III PLUS. CA-Clipper implements it by invoking the Alias() function without an argument.

Dbf() is a compatibility function and, therefore, no longer recommended. It is superseded entirely by the Alias() function.

Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/DBF.PRG
See also

Deleted()Harbour implementation  | 

Return the deleted status of the current record
Syntax
Deleted() → lDeleted
Returns
Deleted() returns true (.T.) if the current record is marked for deletion; otherwise, it returns false (.F.). If there is no database file in USE in the current work area, Deleted() returns false (.F.).
Description

Deleted() is a database function that determines if the current record in the active work area is marked for deletion. Since each work area with an open database file can have a current record, each work area has its own Deleted() value.

By default, Deleted() operates on the currently selected work area. It will operate on an unselected work area if you specify it as part of an aliased expression (see example below).

In applications, Deleted() is generally used to query the deleted status as a part of record processing conditions, or to display the deleted status as a part of screens and reports.

Examples
■  This example uses Deleted() in the current and in an
   unselected work area:

   USE Customer NEW
   USE Sales NEW
   ? Deleted()                     // Result: .F.
   DELETE
   ? Deleted()                     // Result: .T.
   ? Customer->(Deleted())         // Result: .F.

■  This example uses Deleted() to display a record's deleted
   status in screens and reports:

   @ 1, 65 SAY IF(Deleted(), "Inactive", "Active")
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Descend()Harbour implementation  | 

Create a descending index key value
Syntax
Descend(<exp>) → ValueInverted
Arguments
exp is any valid expression of character, date, logical, or numeric type. Memo type is treated in the same way as character type.
Returns
Descend() returns an inverted expression of the same data type as the exp, except for dates which return a numeric value. A Descend() of Chr(0) always returns Chr(0).
Description
Descend() is a conversion function that returns the inverted form of the specified expression to be used with INDEX to create descending order indexes. Specify that part of the index expression you want to be descending as the Descend() argument. To subsequently perform a lookup with SEEK, specify Descend() in the search expression.
Notes

■ The preferred way to create a descending index is to use the

DESCENDing clause of the INDEX command. Using DESCENDING is the same as specifying the Descend() function, but without the performance penalty during index updates. If you create a DESCENDING index, you will not need to use the Descend() function during a SEEK. DESCENDING is an attribute of the index (.ntx) file, where it is stored and used for REINDEXing purposes.

Examples
■  This example uses Descend() in an INDEX expression to create a
   descending order date index:

   USE Sales NEW
   INDEX ON Descend(OrdDate) TO SalesDate

   Later, use Descend() to SEEK on the descending index:

   SEEK Descend(dFindDate)

■  This example illustrates how to create a descending order
   index using more than one data type.  Here, the key is created using
   the concatenation of date and character fields after the appropriate
   type conversion has taken place.  This example uses Str() instead of
   DToS(), since Descend() of a date returns a numeric value:

   USE Sales NEW
   INDEX ON Str(Descend(SaleDate)) + Salesman TO LastSale
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

DevOut()Harbour implementation  | 

Write a value to the current device
Syntax
DevOut(<exp>, [<cColorString>]) → NIL
Arguments
exp is the value to display.
cColorString is an optional argument that defines the display color of exp. If the current DEVICE setting is SCREEN, the output is displayed in the specified color.
If not specified, exp is displayed as the standard color of the current system color as defined by SetColor(). cColorString is a character expression containing the standard color setting. If you want to specify a literal color setting, enclose it in quote marks.
Returns
DevOut() always returns NIL.
Description
DevOut() is a full-screen display function that writes the value of a single expression to the current device at the current cursor or printhead position. Use DevOut() with DevPos() in std.ch to implement the @...SAY command.
Examples
■  This example shows the relationship between the DevOut()
   function and the @...SAY command:

   DevPos(10, 10)
   DevOut("Hello there", "BG+/B"))
   //
   @ 10, 10 SAY "Hello there" COLOR "BG+/B"
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DevOutPict()Harbour implementation  | 

Write a value to the current device using a picture clause
Syntax
DevOutPict(<exp>, <cPicture>, [<cColorString>])
   → NIL
Arguments
exp is the value to display.
cPicture defines the formatting control for the display of exp. The picture specified here is the same as one used with @...SAY or TRANSFORM and can include both templates and functions.
cColorString is an optional argument that defines the display color of exp. If the current DEVICE is SCREEN, output displays in the specified color.
If not specified, exp displays as the standard color of the current system color as defined by SetColor(). cColorString is a character expression containing the standard color setting. If you want to specify a literal color setting, it must be enclosed in quote marks.
Returns
DevOutPict() always returns NIL.
Description
DevOutPict() is a full-screen display function that writes the value of a single expression to the current device at the current cursor or printhead position. DevOutPict() is used in combination with DevPos() in std.ch to implement the @...SAY command used with a PICTURE clause.
Examples
■  This example shows the relationship between the DevOutPict()
   function and the @...SAY command:

   DevPos(10, 10)
   DevOutPict("Hello there", "@!", "BG+/B"))
   //
   @ 10, 10 SAY "Hello there" PICTURE "@!" COLOR "BG+/B"
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DevPos()Harbour implementation  | 

Move the cursor or printhead to a new position depending on the current device
Syntax
DevPos(<nRow>, <nCol>) → NIL
Arguments
nRow and nCol are the new row and column positions of the cursor or printhead.
Returns
DevPos() always returns NIL.
Description

DevPos() is an environment function that moves the screen or printhead depending on the current DEVICE. If DEVICE is SET to SCREEN, DevPos() behaves like SetPos(), moves the cursor to the specified location, and updates Row() and Col() with the new cursor position.

If DEVICE is SET to PRINTER, DevPos() moves the printhead instead. It does this by sending the number of linefeed and/or formfeed characters to the printer, and advancing the printhead to the new position. If the current SET MARGIN value is greater than zero, it is added to nCol. The printhead is then advanced to the specified nRow and nCol position and PRow() and PCol() are updated. If either nRow or nCol are less than the current PRow() and PCol() values, the printhead is moved according to the following special rules:

■ If nRow is less than PRow(), an automatic EJECT (Chr(12)) is

sent to the printer followed by the number of linefeed characters (Chr(10)) required to position the printhead on nRow of the following page.

■ If nCol including the current SET MARGIN value is less than

PCol(), a carriage return character (Chr(13)) and the number of space characters required to position the printhead at nCol are sent to the printer.

To circumvent these rules, use SetPRC() to reset PRow() and PCol() to new values before using DevPos(). See the SetPRC() discussion for more information.

If the printer is redirected to a file using the SET PRINTER command, DevPos() updates the file instead of the printer.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DECLARE* | 

Create and initialize private memory variables and arrays
Syntax
DECLARE <identifier> [[:= <initializer>], ... ]
Arguments
identifier is the name of a private variable or array to create. If the identifier is followed by square brackets ([ ]), it is created as an array. If the identifier is an array, the syntax for specifying the number of elements for each dimension is either array[nElements, nElements2,...] or array[nElements][nElements2]... The maximum number of elements per dimension is 4096.
initializer is the optional assignment of a value to a new private variable. An initializer expression for a private variable consists of the inline assignment operator (:=) followed by any valid CA-Clipper expression, including a literal array. If no explicit initializer is specified, the variable is given an initial value of NIL. In the case of an array, each element is NIL. Array identifiers, cannot be given values with an initializer.
DECLARE can create and, optionally, initialize a list of variable arrays, if definitions are separated by commas.
Description
DECLARE is a compatibility statement that is a synonym for the PRIVATE statement. Its general use is not recommended. PRIVATE should be used in all instances.
Platforms
Available on MS-DOS
See also

DELETEHarbour implementation | 

Mark records for deletion
Syntax
DELETE [<scope>] [WHILE <lCondition>]
   [FOR <lCondition>]
Arguments
scope is the portion of the current database file to DELETE. If a scope is not specified, DELETE acts only on the current record. If a conditional clause is specified, the default becomes ALL records.
WHILE lCondition specifies the set of records meeting the condition from the current record until the condition fails.
FOR lCondition specifies the conditional set of records to DELETE within the given scope.
Description

DELETE is a database command that tags records so they can be filtered with SET DELETED ON, queried with Deleted(), or physically removed from the database file with PACK. In addition, display commands such as LIST and DISPLAY identify deleted records with an asterisk (*) character. Once records are deleted, you can reinstate them by using RECALL. If you want to remove all records from a database file, use ZAP instead of DELETE ALL and PACK.

Any deleted record can be recalled as long as the PACK or ZAP command has not been issued. Once the PACK or ZAP command has been issued, the deleted data cannot be retrieved.

In a network environment, DELETE requires the current record be locked with RLock() if you are deleting a single record. If you are deleting several records, the current database file must be locked with FLock() or USEed EXCLUSIVEly. Refer to the "Network Programming" chapter in the Programming and Utilities Guide for more information.

Notes

DELETE with SET DELETED ON: If the current record is deleted

with SET DELETED ON, it will be visible until the record pointer is moved.

Examples
■  This example demonstrates use of the FOR clause to mark a set
   of records for deletion:

   USE Sales INDEX Salesman NEW
   DELETE ALL FOR Inactive
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DELETE FILEHarbour implementation | 

Remove a file from disk
Syntax
DELETE FILE | ERASE <xcFile>
Arguments
xcFile is the name of the file to be deleted from disk and can be specified either as a literal file name or as a character expression enclosed in parentheses. You must specify the file name, including the extension, and it may optionally be preceded by a drive and/or path specification.
Description

DELETE FILE, a synonym for ERASE, is a file command that removes the specified file from disk. SET DEFAULT and SET PATH do not affect DELETE FILE. The file is deleted from disk only if found in the current DOS directory or in the directory explicitly specified as part of the file name.

Warning! Files must be CLOSEd before deleting them. Otherwise, either a sharing violation or a date corruption on the drive may occur.

Examples
■  This example removes a specified file from disk then tests to
   see if the file was in fact removed:

   ? FILE("Temp.dbf")               // Result: .T.
   DELETE FILE Temp.dbf
   ? FILE("Temp.dbf")               // Result: .F.
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DELETE TAGHarbour implementation | 

Delete a tag
Syntax
DELETE TAG <cOrderName> [IN <xcOrderBagName>]
   [, <cOrderName> [IN xcOrderBagName] list>]
Arguments
cOrderName is a character string that represents the order name.
xcOrderBagName is the name of a disk file containing one or more orders. You may specify xcOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of xcOrderBagName, CA-Clipper uses the default extension of the current RDD.
cOrderName ...list is an optional list of order and order bag name pairs, separated by commas. Any reference to cOrderName that results in either a null string ("") or spaces is ignored. You can specify each order as a literal expression or as a character expression enclosed in parentheses. If you specify no extension for the order bag name, the current database driver supplies a default extension.
Description

This command removes an order from an order bag in the current or specified work area. If you do not specify an xcOrderBagName, all orders bags are searched in the current or specified work area. The first occurrence of cOrderName is deleted. A runtime recoverable error is raised if the order is not found.

If cOrderName is the active order, the database in the current or specified work area reverts to its identity order (natural or entry) and SET FILTER scoping.

A runtime error is raised if xcOrderBagName does not exist or if it exists but does not contain cOrderName.

The active RDD determines the order capacity of an order bag. The default DBFNTX and the DBFNDX drivers only support single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBFMDX drivers).

Examples
USE Customer VIA "DBFCDX" NEW
SET INDEX TO Customer

// Delete the Orders (Tags) Cust01 and Cust02 that
// exist in the index file Customer
DELETE TAG Cust01 IN Customer
DELETE TAG Cust02 IN Customer

// or
// DELETE TAG Cust01 IN Customer, Cust02 IN Customer
Platforms
Available on MS-DOS
See also

DirChange()Harbour implementation  | 

Change the current DOS directory
Syntax
DirChange(<cDir>) → nSuccess
Arguments
cDir is the name of the directory to change to, including the drive.
Returns
DirChange() returns 0 if successful; -1 if there is an argument error. Otherwise, DirChange() returns the DOS error code.
Description
DirChange() changes the current DOS directory. This function may also be used to determine whether or not a directory exists.
Examples
■  The following example attempts to change to the "c:\dos"
   directory.  If it is unsuccessful, an error message is displayed.

   nResult :=  DirChange("c:\dos")

   IF nResult != 0
      ? "Cannot change directory. "
      DO CASE
         CASE nResult == 3
            ?? "Directory does not exist."
         CASE nResult == 5
            ?? "Access to directory denied."
      END
      BREAK
   ENDIF

  You may also use something like this:

   DirChange( "..\..\test" )
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

Directory()Harbour implementation  | 

Create an array of directory and file information
Syntax
Directory(<cDirSpec>, [<cAttributes>]) → aDirectory
Arguments
cDirSpec identifies the drive, directory and file specification for the directory search. Wildcards are allowed in the file specification. If cDirSpec is omitted, the default value is *.*.
cAttributes specifies inclusion of files with special attributes in the returned information. cAttributes is a string containing one or more of the following characters:
Directory() Attributes
    Attribute    Meaning
    H            Include hidden files
    S            Include system files
    D            Include directories
    V            Search for the DOS volume label and exclude all other files
Normal files are always included in the search, unless you specify V.
Returns
Directory() returns an array of subarrays, with each subarray containing information about each file matching cDirSpec. The subarray has the following structure:
Directory() Subarray Structure
    Position     Metasymbol     Directry.ch
    1            cName          F_NAME
    2            cSize          F_SIZE
    3            dDate          F_DATE
    4            cTime          F_TIME
    5            cAttributes    F_ATTR
If no files are found matching cDirSpec or if cDirSpec is an illegal path or file specification, Directory() returns an empty ({}) array.
Description

Directory() is an environment function that returns information about files in the current or specified directory. It is similar to ADir(), but returns a single array instead of adding values to a series of existing arrays passed by reference.

Use Directory() to perform actions on groups of files. In combination with AEval(), you can define a block that can be applied to all files matching the specified cDirSpec.

The header file, directry.ch, in the \CLIP53\INCLUDE subdirectory contains #defines for the subarray subscripts, so that the references to each file subarray are more readable.

Examples
■  This example creates an array of information about files in
   the current directory and then lists the names of the files using
   AEval() and QOut():

   #include "Directry.ch"
   //
   aDirectory := Directory("*.*", "D")
   AEval( aDirectory, {|aFile| QOut(aFile[F_NAME])} )
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is directry.ch.
See also

DirMake()  | 

Create a directory
Syntax
DirMake(<cNewDir>) → nSuccess
Arguments
cNewDir is the name of the directory to be created, including an optional drive. If you do not specify a drive, the current one is used.
Returns
DirMake() returns 0 if successful; -1 if there is an argument error. Otherwise, DirMake() returns the DOS error code.
Description
DirMake() creates a specified directory. Note that first you must have sufficient rights to create a directory. To create nested subdirectories, you must create each subdirectory separately, starting from the top-level directory that you want to create (see example below.)
Examples
■  This example assumes that C:\TEST exists and uses DirMake()
   twice to create a nested subdirectory under it:

   DirMake("c:\test\one")    // Create top-most one
   nResult := DirMake("c:\test\one\two")
   IF nResult != 0
      ? "Cannot make directory, DOS error ", nResult
      BREAK
   ENDIF

  You may also use something like this:

   DirMake( ".\test" )
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

DirRemove()→ hb_DirDelete()Harbour implementation  | 

Remove a directory
Syntax
DirRemove(<cDirName>) → nSuccess
Arguments
cDirName is the name of the directory to erase, including an optional drive. If you do not specify a drive, the current one is used.
Returns
DirRemove() returns 0 if successful; -1 if there is an argument error. Otherwise, DIRREMOVE returns the DOS error code.
Description
DirRemove() removes a specified directory. Note that you must first have sufficient rights to delete a directory. A directory must be empty in order to be deleted. Therefore, to delete a directory that contains subdirectories, you must first delete the subdirectories (see example below).
Examples
■  This example uses DirRemove() to delete a subdirectory named
   C:\TEST\ONE, which only contains an empty subdirectory named
   C:\TEST\ONE\TWO:

   DirRemove("c:\test\one\two")        // First delete lowest dir
   nResult := DirRemove("c:\test\one")  // Then delete higher dir
   IF nResult != 0
      ? "Cannot remove directory, DOS error ", siResult
      BREAK
   ENDIF
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

DiskChange()Harbour implementation  | 

Change the current DOS disk drive
Syntax
DiskChange(<cDrive>) → lSuccess
Arguments
cDrive specifies the letter of the disk drive to change to.
Returns
DiskChange() returns true (.T.) if successful; otherwise, it returns false (.F.).
Examples
■  This example uses DiskChange() to change to drive "D":

   IF DiskChange("D:")
      ? "Successfully changed"
   ELSE
      ? "Not changed"
   ENDIF


■  This example builds a string that contains all currently
   available drives on your system:

   FUNCTION AllDrives()
      LOCAL wI, cDrives := ""

      FOR wI := 1 TO 26
         IF DiskChange( Chr(wI + 64) )
            cDrives := cDrives + Chr(wI + 64)
         ENDIF
      NEXT
   RETURN cDrives
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

DiskName()Harbour implementation  | 

Return the current DOS drive
Syntax
DiskName() → cDrive
Returns
DiskName() returns the letter of the current DOS drive, without a trailing colon.
Examples
■  This example illustrates the relationship between
   DiskName()and DiskChange() and shows that DiskName() is unaffected by
   the SET DEFAULT TO command:

   ? DiskName()      // C
   SET DEFAULT TO A
   ? DiskName()      // C
   DiskChange("A")
   ? DiskName()      // A
   DiskChange("C")
   ? DiskName()      // C
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

DiskSpace()Harbour implementation  | 

Return the space available on a specified disk
Syntax
DiskSpace([<nDrive>]) → nBytes
Arguments
nDrive is the number of the drive to query, where one is drive A, two is B, three is C, etc. The default is the current DOS drive if nDrive is omitted or specified as zero.
Returns
DiskSpace() returns the number of bytes of empty space on the specified disk drive as an integer numeric value.
Description

DiskSpace() is an environment function that determines the number of available bytes remaining on the specified disk drive. It is useful when COPYing or SORTing to another drive to determine if there is enough space available before initiating the operation. You may also use DiskSpace() with RecSize() and RecCount() to create a procedure to back up database files.

DiskSpace() ignores the SET DEFAULT drive setting.

Examples
■  This example is a user-defined function that demonstrates the
   use of DiskSpace() to back up a database file to another drive:

   FUNCTION BackUp( cTargetFile, cTargetDrive )
      LOCAL nSpaceNeeded, nTargetDrive
      //
      nSpaceNeeded := INT((RecSize() * ;
         LastRec()) + Header() + 1)
      nTargetDrive := Asc(Upper(cTargetDrive)) - 64
      //
      IF DiskSpace(nTargetDrive) < nSpaceNeeded
         RETURN .F.
      ENDIF
      COPY TO (cTargetDrive + ":" + cTargetFile)
      //
      RETURN .T.
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

DispBegin()Harbour implementation  | 

Begin buffering screen output
Syntax
DispBegin() → NIL
Returns
DispBegin() always returns NIL.
Description

DispBegin() is a screen function that informs the CA-Clipper display output system that the application is about to perform a series of display operations.

Use DispBegin() with DispEnd() to allow the display output system to buffer display updates. Display output which occurs after DispBegin() but before DispEnd() is allowed to accumulate in internal buffers. When DispEnd() executes, any pending updates appear on the physical display. This is useful in applications where complex screen displays are slow and the appearance of performance is desired.

DispBegin() and DispEnd() calls are optional. They are not required for normal output.

Notes

■ Nested calls: DispBegin() calls are nested internally. If

several DispBegin() calls occur, buffering is allowed until a corresponding number of DispEnd() calls occur.

■ Guaranteed operations: Display updates performed between

DispBegin() and DispEnd() are not guaranteed to be buffered—some updates may become visible before DispEnd() is called. However, all updates are guaranteed to be visible after the closing call to DispEnd().

■ Terminal operations: Terminal input operations such as Inkey()

or READ should not be performed between DispBegin() and DispEnd(). Doing this may cause input or display output to be lost.

■ Incompatible operations: Display output by other than the

CA-Clipper display functions (e.g., by add-on libraries or by DOS via OutStd(), etc.) may not be compatible with DispBegin() and DispEnd(). Output may be lost.

Examples
■  This example buffers screen output, updates the screen, and
   then displays the buffered screen output:

   DispBegin()            // Start screen buffering
   //
   SetPos(10, 10)
   DispOut("A display update")
   SetPos(11, 10)
   DispOut("Another display update")
   //
   DispEnd()               // Display buffered screen data
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DispBox()Harbour implementation  | 

Display a box on the screen
Syntax
DispBox(<nTop>, <nLeft>, <nBottom>, <nRight>,
   [<cnBoxString>], [<cColorString>]) → NIL
Arguments
nTop, nLeft, nBottom, and nRight define the coordinates of the box. DispBox() draws a box using row values from zero to MaxRow(), and column values from zero to MaxCol(). If nBottom and nRight are larger than MaxRow() and MaxCol(), the bottom-right corner is drawn off the screen.
cnBoxString is a numeric or character expression that defines the border characters of the box. If specified as a numeric expression, a value of 1 displays a single-line box and a value of 2 displays a double-line box. All other numeric values display a single-line box.
If cnBoxString is a character expression, it specifies the characters to be used in drawing the box. This is a string of eight border characters and a fill character. If cnBoxString is specified as a single character, that character is used to draw the whole box.
If this argument is not specified, a single-line box is drawn.
cColorString defines the display color of the box that is drawn. If not specified, the box is drawn using the standard color setting of the current system color as defined by SetColor().
Returns
DispBox() always returns NIL.
Description

DispBox() is a screen function that draws a box at the specified display coordinates in the specified color. If you specify cnBoxString, DispBox() draws a box on the screen using configurable border and fill characters. DispBox() draws the box using cnBoxString starting from the upper left-hand corner, proceeding clockwise and filling the screen region with the ninth character. If the ninth character is not specified, the screen region within the box is not painted. Existing text and color remain unchanged.

In cases where cnBoxString respects CA-Clipper conventions, the behavior of DispBox() is unchanged. The behavior of this function can easily be modified to take advantage of graphic mode. For example, you can replace the standard window frames using single or double lines with new graphical frames that have an impressive 3-D look. Simply replace the cBoxString parameter using the following:

Chr(2) + Chr(nColor+1) // draws a box of thickness 16x8x16x8 Chr(3) + Chr(nColor+1) // draws a box of thickness 8x8x8x8 Chr(4) + Chr(nColor+1) // draws a box of thickness

// 16x16x16x16

Chr(5) + Chr(nColor+1) // draws a box of thickness 16x8x8x8

Note that nColor is a numeric color representation. You must add 1 to this value.

In general, Chr(2) + Chr(nColor+1) can be used instead of CA-Clipper's B_SINGLE or B_DOUBLE defines.

CA-Clipper graphics comes with two #defines LLG_BOX_GRAY_STD and LLG_BOX_GRAY_SQUARE to allow gray (nColor=7) boxes of width 16x8 or 16x16.

You can completely customize the box by passing Chr(1) + ... as the first parameter:

Chr(1) + ; // Box entirely defined Chr(nBackColor+1) + ; // Color used as background fill Chr(nLightColor+1) + ; // Color used to lighten the frame Chr(nDarkColor+1) + ; // Color used to darken the frame Chr(nWidthUp) + ; // Thickness of upper edge of box Chr(nWidthRight) + ; // Thickness of right edge of box Chr(nWidthDown) + ; // Thickness of lower edge of box Chr(nWidthLeft) // Thickness of left edge of box

After DispBox() executes, the cursor is located in the upper corner of the boxed region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.

Note that box.ch, located in \CLIP53\INCLUDE, provides constants for various border configurations.

Notes
The number of colors available depends on the current video mode setting ( SET VIDEOMODE ).
Examples
■  This code example displays a double-line box using a numeric
   value to specify the box border:

   #define B_SINGLE   1
   #define B_DOUBLE   2
   //
   DispBox(1, 1, 10, 10, B_DOUBLE, "BG+/B")

■  This example displays a single-line top and double-line side
   box by specifying border characters with a manifest constant defined
   in box.ch:

   #include "Box.ch"
   //
   DispBox(1, 1, 10, 10, B_SINGLE_DOUBLE, "BG+/B")

■  This example displays a box with a 3-D look.  It can be used
   for graphic mode:

   // Display a box with a 3D look of constant width 16x16x16x16
   DispBox( nTop, nLeft, nBottom, nRight, LLG_BOX_GRAY_SQUARE )
   // Write some transparent text in the 3D frame
   GWRITEAT(  nLeft * GMODE()[LLG_MODE_FONT_COL] ,;
   nTop  * GMODE()[LLG_MODE_FONT_ROW] ,;
   "This is some Text...",;
   4,;
   LLG_MODE_SET; )
Platforms
Available on MS-DOS
File
Library is LLIBG.LIB, header file is Llibg.ch.
See also

DispCount()Harbour implementation  | 

Return the number of pending DispEnd() requests
Syntax
DispCount() → nDispCount
Returns
DispCount() returns the number of DispEnd() calls required to restore the original display context.
Description

You can use DispCount() to determine the current display context. CA-Clipper uses display contexts to buffer and to supervise screen output operations.

Each call to DispBegin() defines a new display context. Output to the display context is suppressed until a matching DispEnd() statement executes.

Since you may nest DispBegin() calls, use DispCount() to determine whether there are pending screen refresh requests.

Examples
■  This example saves the setting of DispCount(), then releases
   all pending display contexts before writing to the screen:

   PROCEDURE ForceDisplay(cExp)
      LOCAL nSavCount

   nSavCount := DispCount()

   //  Discard pending display contexts
   DO WHILE ( DispCount() > 0)
      DispEnd()

   ENDDO

   DispOut(cExp)

   //  "Rewind" the current display context
   DO WHILE (DISPCCOUNT() < nSavCount )
      DispBegin()
   ENDDO

   RETURN
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DispEnd()Harbour implementation  | 

Display buffered screen updates
Syntax
DispEnd() → NIL
Returns
DispEnd() always returns NIL.
Description

DispEnd() is a screen function that informs the CA-Clipper display output system that the application has finished performing a series of display operations.

DispEnd() is used with DispBegin() so the display output system can buffer display updates. This can be important for applications in which complex screen displays are slow and the appearance of performance is desired.

Examples
■  This example buffers screen output, updates the screen, and
   then displays the buffered screen output:

   DispBegin()            // Start screen buffering
   //
   SetPos(10, 10)
   DispOut("A display update")
   SetPos(11, 10)
   DispOut("Another display update")
   //
   DispEnd()               // Display buffered screen data
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DispOut()Harbour implementation  | 

Write a value to the display
Syntax
DispOut(<exp>, [<cColorString>]) → NIL
Arguments
exp is the value to display.
cColorString is an optional argument that defines the display color of exp. If unspecified, exp is displayed as the standard color of the current system color as defined by SetColor(). cColorString is a character expression containing the standard color setting. You can specify a literal color setting, if you enclose it in quote marks.
Returns
DispOut() always returns NIL.
Description
DispOut() is a simple output function that writes the value of a single expression to the display at the current cursor position. This function ignores the SET DEVICE setting; output always goes to the screen. You can only use this function within a procedure or function.
Examples
■  This example performs screen output at a specified location in
   different colors.  Note how the cursor position is saved and restored
   using Row(), Col(), and SetPos():

   PROCEDURE Showit
      LOCAL nRow, nCol
      ? nCol := Col()            // save original
      ?? nRow := Row()            // cursor position

      Inkey(2)

      SetPos(nRow, nCol)
      DispOut("This is a test of DispOut()")
      ? Col()                     // display current
      ?? Row()                     // cursor position

      Inkey(2)

      SetPos(nRow, nCol)
      DispOut(Space(26))         // clear original position
      SET DEVICE TO PRINTER      // ignores SET DEVICE

      SetPos(nRow, nCol)         // display at
      DispOut("           all through")
                                 // original position

      RETURN
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DIR*Harbour implementation | 

Display a listing of files from a specified path
Syntax
DIR [<xcFileSpec>]
Arguments
xcFileSpec is a template that must be matched by displayed files and can include standard wildcard (* and ?) characters. You can specify xcFileSpec as a literal file specification string or as a character expression enclosed in parentheses.
Description

DIR is a file command that displays a listing of files from the specified path in one of two formats depending on whether you specify the xcFileSpec argument. If you do not specify a path, DIR displays a standard listing of database files from the current or specified directory. The list includes the database file name, date of last update, and number of records. Including the option xcFileSpec displays a list of all files in the specified directory. This list includes the file name, extension, number of bytes, and date of last update.

If no path is specified, DIR displays files from the current DOS drive and directory unless SET DEFAULT has been used to specify a new default directory.

DIR is a compatibility command and therefore not recommended. It is superseded by the Directory() function which returns an array of file information from a wildcard pattern. Using this array, you can display file information to screen.

Notes

■ Directory picklists: To present directory information to the

user, use ADir() to return one or more arrays of directory information, and AChoice() to present a picklist to the user.

Examples
■  These examples display DOS and database files in the current
   directory:

   cFilespec := "*.*"
   DIR (cFilespec)            // Display all files
   DIR                        // Display all (.dbf) files
   DIR *.prg                  // Display all program files
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB.
See also

DISPLAYHarbour implementation | 

Display records to the console
Syntax
DISPLAY <exp list>
   [TO PRINTER] [TO FILE <xcFile>]
   [<scope>] [WHILE <lCondition>]
   [FOR <lCondition>] [OFF]
Arguments
exp list is the list of values to display for each record processed.
TO PRINTER echoes output to the printer.
TO FILE xcFile echoes output to the indicated file which can be specified either as a literal file name or as a character expression enclosed in parentheses. If an extension is not specified, .txt is added.
scope is the portion of the current database file to DISPLAY. The default is the current record, or NEXT 1. If a condition is specified, the scope becomes ALL.
WHILE lCondition specifies the set of records meeting the condition from the current record until the condition fails.
FOR lCondition specifies the conditional set of records to DISPLAY within the given scope.
OFF suppresses the display of the record number.
Description

DISPLAY is a database command that sequentially accesses records in the current work area, sending the results of the exp list to the console in a tabular format with each column separated by a space. The command does not display column headers or pause at predetermined intervals. DISPLAY is identical to LIST with the exception that its default scope is NEXT 1 rather than ALL.

When invoked, output is sent to the screen and optionally to the printer and/or a file. To suppress output to the screen while printing or echoing output to a file, SET CONSOLE OFF before the DISPLAY command line.

Notes

■ Interrupting output: To let the user interrupt the processing

of a DISPLAY command, using the Inkey() function, add a test for the interrupt key press to the FOR condition. See the example below.

■ Printer margin: Since DISPLAY is a console command, it honors

the current SET MARGIN for output echoed to the printer.

Examples
■  This example illustrates a simple DISPLAY, and a conditional
   DISPLAY to the printer:

   USE Sales NEW
   DISPLAY Date(), Time(), Branch
   DISPLAY Branch, Salesman FOR Amount > 500 TO PRINTER

■  This example interrupts a DISPLAY using Inkey() to test
   whether the user pressed the Esc key:

   #define K_ESC  27
   USE Sales INDEX SalesMan NEW
   DISPLAY Branch, Salesman, Amount WHILE ;
      Inkey() != K_ESC
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DosError()Harbour implementation  | 

Return the last DOS error number
Syntax
DosError([<nNewOsCode>]) → nOsCode
Arguments
nNewOsCode, if specified, alters the value returned by DosError(). The value must be a numeric value that reflects a DOS error number.
Returns
DosError() returns the DOS error number as an integer numeric value.
Description

DosError() is an error function that returns the last DOS error code associated with an activation of the runtime error block. When a runtime error occurs, the DosError() function is set to the current DOS error if the operation has an associated DOS error. The function value is retained until another runtime error occurs. If the failed operation has no associated DOS error, the DosError() returns zero. With low- level file functions, FError() returns the same value as DosError().

Through use of the optional nNewOsCode, you may customize to the reporting activation the returned value for any DOS error.

For a complete list of DOS error numbers and accompanying descriptions, refer to the Error Messages and Appendices Guide.

Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DoW()Harbour implementation  | 

Convert a date value to a numeric day of the week
Syntax
DoW(<dDate>) → nDay
Arguments
dDate is a date value to convert.
Returns
DoW() returns the day of the week as a number between zero and seven. The first day of the week is one (Sunday) and the last day is seven (Saturday). If dDate is empty, DoW() returns zero.
Description
DoW() is a date conversion function that converts a date value to a number identifying the day of the week. It is useful when you want date calculations on a weekly basis. DoW() is similar to CDoW(), which returns the day of week as a character string instead of a number.
Examples
■  These examples illustrate CDoW() and its relationship to
   DoW():

   ? Date()                        // Result: 09/01/89
   ? DoW(Date())                  // Result: 3
   ? CDoW(Date())                  // Result: Tuesday
   ? DoW(Date() - 2)               // Result: 1
   ? CDoW(Date() - 2)            // Result: Sunday

■  This is a user-defined function that uses DoW() to calculate
   the date of last Monday from any other date:

   FUNCTION LastMonday(dDate)
      RETURN (dDate - DoW(dDate) + 2)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DO CASE | 

Execute one of several alternative blocks of statements
Syntax
DO CASE
CASE <lCondition1>
   <statements>...
[CASE <lCondition2>]
   <statements>...
[OTHERWISE]
   <statements>...
END[CASE]
Arguments
CASE lCondition defines a block of statements to be executed if lCondition evaluates to true (.T.).
OTHERWISE defines a block of statements to be executed if none of the specified CASE conditions evaluates to true (.T.).
Description

DO CASE...ENDCASE is a control structure that executes one of several blocks of statements depending on which of the associated conditions is true (.T.). It works by branching execution to the statements following the first CASE lCondition that evaluates to true (.T.). Execution continues until the next CASE, OTHERWISE, or ENDCASE is encountered. Control then branches to the first statement following the next ENDCASE statement.

If none of the CASE conditions evaluates to true (.T.), the statements following the OTHERWISE statement are executed up to the matching ENDCASE statement. If an OTHERWISE statement is omitted, control branches to the first statement following the matching ENDCASE statement.

You may nest any number of statements, including other control structures (i.e., DO WHILE and FOR), within a single DO CASE structure. In addition, within a single DO CASE structure, there is no fixed limit on the number of CASE statements that a DO CASE structure may contain.

DO CASE...ENDCASE is identical to IF...ELSEIF...ENDIF with neither syntax having a specific advantage over the other.

Examples
■  This example uses DO CASE in a menu structure to branch
   control based on user selection:

   @ 3, 25 PROMPT "First choice"
   @ 4, 25 PROMPT "Second choice"
   MENU TO nChoice
   //
   DO CASE
   CASE nChoice = 0
      RETURN
   CASE nChoice = 1
      ChoiceOne()
   CASE nChoice = 2
      ChoiceTwo()
   ENDCASE
Platforms
Available on MS-DOS
See also

DO WHILE | 

Execute a loop while a condition is true (.T.)
Syntax
[DO] WHILE <lCondition>
   <statements>...
   [EXIT]
   <statements>...
   [LOOP]
   <statements>...
END[DO]
Arguments
lCondition is the logical control expression for the DO WHILE loop.
EXIT unconditionally branches control from within a DO WHILE or FOR...NEXT structure to the statement immediately following the corresponding ENDDO or NEXT statement.
LOOP branches control to the most recently executed DO WHILE or FOR statement.
Description

DO WHILE...ENDDO is a control structure that executes a block of statements repetitively, as long as lCondition evaluates to true (.T.). When the condition evaluates to true (.T.), control passes into the structure and proceeds until an EXIT, LOOP, or ENDDO is encountered. ENDDO returns control to the DO WHILE statement and the process repeats itself. If an EXIT statement is encountered, control branches to the nearest ENDDO or NEXT statement. If a LOOP statement is encountered, control branches to the nearest DO WHILE or FOR statement. If the condition evaluates to false (.F.), the DO WHILE construct terminates and control passes to the statement immediately following the ENDDO.

Use EXIT to terminate a DO WHILE structure based on a condition other than the DO WHILE condition. LOOP, by contrast, prevents execution of statements within a DO WHILE based on an intermediate condition, and returns to the most recent DO WHILE statement.

DO WHILE constructs may be nested within any other control structures to any depth. The only requirement is that each control structure be properly nested.

Examples
■  This example demonstrates a typical control structure for a
   simple grouped report:

   LOCAL cOldSalesman, nTotalAmount
   USE Sales INDEX Salesman NEW
   DO WHILE .NOT. Eof()
      cOldSalesman := Sales->Salesman
      nTotalAmount := 0
      DO WHILE cOldSalesman = Sales->Salesman ;
         .AND. (.NOT. Eof())
         ? Sales->Salesman, Sales->Amount
         nTotalAmount := nTotalAmount + Sales->Amount
         SKIP
      ENDDO
      ? "Total: ", nTotalAmount, "for", cOldSalesman
   ENDDO
   CLOSE Sales

■  This code fragment demonstrates how LOOP can be used to
   provide an intermediate processing condition:

   DO WHILE <lCondition>
      <initial processing>...
      IF <intermediate condition>
         LOOP
      ENDIF
      <continued processing>...
   ENDDO

■  This example demonstrates the use of DO WHILE to emulate a
   repeat until looping construct:

   LOCAL lMore := .T.
   DO WHILE lMore
      <statements>...
      lMore := (<lCondition>)
   ENDDO

■  This example uses a DO WHILE loop to move sequentially through
   a database file:

   DO WHILE .NOT. Eof()
      <statements>...
      SKIP
   ENDDO
Platforms
Available on MS-DOS
See also

DO* | 

Call a procedure
Syntax
DO <idProcedure> [WITH <argument list>]
Arguments
idProcedure is the name of the procedure or user-defined function to be executed.
WITH argument list specifies up to 128 arguments, separated by commas, to pass to idProcedure. Each argument may be a single variable, field, array, array element, expression, or object. Arguments can be skipped or left off the end of the list.
Description

The DO statement calls a procedure or user-defined function, optionally passing arguments to the called routine. It performs the same action as a user-defined function or procedure specified on a line by itself with the exception that variables other than field variables are passed by reference as the default. In order to pass a field variable as an argument, enclose it in parentheses, unless you declare it with the FIELD statement or with an alias.

In CA-Clipper, the number of specified arguments need not match the number of specified parameters in the called procedure. If the number of arguments is less than the number of parameters, the parameter variables with no corresponding arguments are initialized with a NIL value when the procedure is called. If the number of arguments is greater than the number of parameters, they are ignored.

Also, skipping an argument within the argument list by leaving an empty spot next to the comma initializes the corresponding argument to NIL. To detect the position of the last argument passed in the argument list, use PCount(). To detect a skipped argument, compare the receiving parameter to NIL.

In addition to calling a procedure or user-defined function, DO also has an effect on compilation if you compile the current program file without the /M option. If the CA-Clipper compiler encounters a DO statement and the specified procedure has not already been compiled, the compiler searches the current directory for a .prg file with the same name and compiles it. If the file with the same name as the procedure is not found, the called procedure is assumed to be external, and a reference is added to the object (.OBJ) file. At link time, the linker will search other object files and libraries for this external reference.

In CA-Clipper, DO is a compatibility statement and therefore not recommended. Calling a procedure or function on a line by itself is the preferred method. Since this preferred calling convention normally passes parameters by value, you must preface an argument with the pass- by-reference operator (@) in order to pass by reference. If you are using DO to make a procedure call more readable, a user-defined command, specified with the #command directive, can provide greater readability without sacrificing the safety of variables passed as parameters.

For more information on passing parameters refer to the Functions and Procedures section of the "Basic Concepts" chapter in the Programming and Utilities Guide.

Examples
■  This example executes a procedure with no parameters:

   DO AcctsRpt
   AcctsRpt()                           // Preferred method

■  This example executes a procedure passing two constants:

   DO QtrRpt WITH "2nd", "Sales Division"
   QtrRpt("2nd", "Sales Division")      // Preferred method

■  In this example, a procedure is executed with the first
   argument passed by value and the second passed by reference:

   nNumber := 12
   DO YearRpt WITH nNumber + 12, nNumber
   YearRpt(nNumber + 12, @nNumber)      // Preferred method

■  Here, a procedure is invoked with skipped arguments embedded
   in the list of arguments:

   DO DisplayWindow WITH ,,,,"My Window"
   DisplayWindow(,,,,"My Window")       // Preferred method
Platforms
Available on MS-DOS
See also

DToC()Harbour implementation  | 

Convert a date value to a character string
Syntax
DToC(<dDate>) → cDate
Arguments
dDate is the date value to convert.
Returns
DToC() returns a character string representation of a date value. The return value is formatted in the current date format. The default format is mm/dd/yy. A null date returns a string of spaces equal in length to the current date format.
Description

DToC() is a date conversion function used for formatting purposes when you want to display the date in the SET DATE format and when a character expression is required (in a LABEL FORM, for example). If you need a specialized date format, you can use Transform() or a custom expression.

If you are INDEXing a date in combination with a character string, use DToS() instead of DToC() to convert the date value to a character string.

Examples
■  These examples show general uses of DToC():

   ? Date()                  // Result: 09/01/90
   ? DToC(Date())            // Result: 09/01/90
   ? "Today is " + DToC(Date())
                           // Result: Today is 09/01/90
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

DToS()Harbour implementation  | 

Convert a date value to a character string formatted as yyyymmdd
Syntax
DToS(<dDate>) → cDate
Arguments
dDate is the date value to convert.
Returns
DToS() returns a character string eight characters long in the format yyyymmdd. When dDate is a null date (CToD("")), DToS() returns a string of eight spaces. The return value is not affected by the current date format.
Description
DToS() is a date conversion function that is used when creating index expressions consisting of a date value and a character expression. DToS() converts a date value to a character string that can be concatenated to any other character expression. The return value is structured to preserve date order (year, month, and day).
Examples
■  These examples illustrate DToS() in conjunction with several
   other functions:

   ? Date()                        // Result: 09/01/90

   ? DToS(Date())                  // Result: 19900901
   ? Len(DToS(CToD("")))           // Result: 8

■  This example demonstrates how to create an index with a
   compound date and character key using DToS():

   USE Sales NEW
   INDEX ON DToS(Date) + Salesman TO DateName
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

EJECTHarbour implementation | 

Advance the printhead to top of form
Syntax
EJECT
Description
EJECT is a printing command that sends a formfeed character (Chr(12)) to the printer and sets the PCol() and PRow() values to zero. If you address a printer row less than the last row position since an EJECT or SetPRC() was executed, CA-Clipper automatically performs an EJECT. Because of this, your printing logic must proceed sequentially from left to right down the page. If you need to reset the internal printer row and column values to zero without sending a formfeed, use SetPRC().
Examples
■  This example prints a simple list report and uses EJECT to
   advance to a new page when the line counter reaches the maximum
   number of lines to print per page:

   LOCAL nLine := 99, nPage := 0
   USE Sales NEW
   SET PRINTER ON
   SET CONSOLE OFF
   DO WHILE !Eof()
      IF nLine > 55
         EJECT
         ? "Page " + LTrim(Str(++nPage, 3))
         ? "Date " + CToD(Date())
         ?
         ? "Salesman", "Amount"
         ?
         nLine := 6
      ENDIF
      ? Sales->Salesman, Sales->Amount
      nLine++
      SKIP
   ENDDO
   SET PRINTER OFF
   SET CONSOLE ON
   CLOSE
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Empty()Harbour implementation  | 

Determine if the result of an expression is empty
Syntax
Empty(<exp>) → lEmpty
Arguments
exp is an expression of any data type.
Returns
Empty() returns true (.T.) if the expression results in an empty value; otherwise, it returns false (.F.). The criteria for determining whether a value is considered empty depends on the data type of exp according to the following rules:
List of Empty Values
    Data Type    Contents
    Array        Zero-length
    Character    Spaces, tabs, CR/LF, or ("")
    Numeric      0
    Date         Null (CToD(""))
    Logical      False (.F.)
    Memo         Same as character
    NIL          NIL
Description
The Empty() function has a number of uses. You can use it to determine if a user entered a value into a Get object before committing changes to a database file. It can also determine whether a formal parameter is NIL or unsupplied. In addition, it can test an array for zero-length.
Notes

■ Space characters: The Empty() function treats carriage

returns, line feeds, and tabs as space characters and removes these as well.

Examples
■  These examples illustrate use of Empty() against several
   different data types:

   ? Empty(Space(5)), Empty("")        // Result: .T. .T.
   ? Empty(0), Empty(CToD(""))         // Result: .T. .T.
   ? Empty(.F.), Empty(NIL)            // Result: .T. .T.

■  This example uses Empty() to determine whether the user
   entered a value into the first Get object before writing the new
   value to the database file:

   LOCAL cCust := Space(15), nAmount := 0
   USE Sales NEW
   @ 10, 10 GET cCust
   @ 11, 10 GET nAmount PICTURE "999.99"
   READ
   //
   IF !Empty(cCust)
      APPEND BLANK
      REPLACE Sales->Cust WITH cCust, Sales->Amount ;
         WITH nAmount
   ENDIF

■  This example uses Empty() as part of the VALID clause to force
   the user to enter data into the current Get object:

   LOCAL cCode := Space(5)
   @ 2, 5 SAY "Enter code" GET cCode VALID !Empty(cCode)
   READ
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Eof()Harbour implementation  | 

Determine when end of file is encountered
Syntax
Eof() → lBoundary
Returns
Eof() returns true (.T.) when an attempt is made to move the record pointer beyond the last logical record in a database file; otherwise, it returns false (.F.). If there is no database file open in the current work area, Eof() returns false (.F.). If the current database file contains no records, Eof() returns true (.T.).
Description

Eof() is a database function used to test for an end of file boundary condition when the record pointer is moving forward through a database file. Any command that can move the record pointer can set Eof().

The most typical application is as a part of the lCondition argument of a DO WHILE construct that sequentially processes records in a database file. Here lCondition would include a test for .NOT. Eof(), forcing the DO WHILE loop to terminate when Eof() returns true (.T.).

Eof() and Found() are often used interchangeably to test whether a SEEK, FIND, or LOCATE command failed. With these commands, however, Found() is preferred.

When Eof() returns true (.T.), the record pointer is positioned at LastRec() + 1 regardless of whether there is an active SET FILTER or SET DELETED is ON. Further attempts to move the record pointer forward return the same result without error. Once Eof() is set to true (.T.), it retains its value until there is another attempt to move the record pointer.

By default, Eof() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression (see example below).

Examples
■  This example demonstrates Eof() by deliberately moving the
   record pointer beyond the last record:

   USE Sales
   GO BOTTOM
   ? Eof()            // Result: .F.
   SKIP
   ? Eof()            // Result: .T.

■  This example uses aliased expressions to query the value of
   Eof() in unselected work areas:

   USE Sales NEW
   USE Customer NEW
   ? Sales->(Eof())
   ? Customer->(Eof())

■  This example illustrates how Eof() can be used as part of a
   condition for sequential database file operations:

   USE Sales INDEX CustNum NEW
   DO WHILE !Eof()
      nOldCust := Sales->CustNum
      nTotalAmount := 0
      DO WHILE nOldCust = Sales->CustNum .AND. (!Eof())
         ? Sales->CustNum, Sales->Description, ;
               Sales->SaleAmount
         nTotalAmount += Sales->SaleAmount
         SKIP
      ENDDO
      ? "Total amount: ", nTotalAmount
   ENDDO
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Error class | 

Provides objects containing information about runtime errors
Description

An Error object is a simple object that contains information pertaining to a runtime error. Error objects have no methods, only exported instance variables. When a runtime error occurs, CA-Clipper creates a new Error object and passes it as an argument to the error handler block specified with the ErrorBlock() function. Within the error handler, the Error object can then be queried to determine the nature of the error condition.

Error objects can also be returned to the RECOVER statement of a BEGIN SEQUENCE construct with a BREAK statement. Here, the error object can be queried for local error handling. For more detailed information and examples refer to the "Error Handling Strategies" chapter in the Programming and Utilities Guide.

Methods link
Class Function
ErrorNew() Create a new Error object
ErrorNew() → oError
Returns
ErrorNew() returns a new Error object.
Exported Instance Variables
args An array of function or operator arguments
args (Assignable)
Contains an array of the arguments supplied to an operator or function when an argument error occurs. For other types of errors, Error:args contains a NIL value.
canDefault Indicates if default recovery is available
canDefault (Assignable)
Contains a logical value indicating whether the subsystem can perform default error recovery for the error condition. A value of true (.T.) indicates that default recovery is available. Availability of default handling and the actual default recovery strategy depends on the subsystem and the error condition. The minimum action is simply to ignore the error condition.
Default recovery is requested by returning false (.F.) from the error block invoked to handle the error. Note that Error:canDefault is never true (.T.) if Error:canSubstitute is true (.T.).
canRetry Indicates if a retry is possible after an error
canRetry (Assignable)
Contains a logical value indicating whether the subsystem can retry the operation that caused the error condition. A value of true (.T.) indicates that a retry is possible. Retry may or may not be available, depending on the subsystem and the error condition.
Retry is requested by returning true (.T.) from the error block invoked to handle the error. Note that Error:canRetry never contains true (.T.) if Error:canSubstitute contains true (.T.).
canSubstitute Indicates if a new result can be substituted after an error
canSubstitute (Assignable)
Contains a logical value indicating whether a new result can be substituted for the operation that produced the error condition. Argument errors and certain other simple errors allow the error handler to substitute a new result value for the failed operation. A value of true (.T.) means that substitution is possible.
The substitution is performed by returning the new result value from the code block invoked to handle the error. Note that Error:canSubstitute is never true (.T.) if either Error:canDefault or Error:canRetry is true (.T.).
cargo User-definable variable
cargo (Assignable)
Contains a value of any data type unused by the Error system. It is provided as a user-definable slot, allowing arbitrary information to be attached to an Error object and retrieved later.
description Character description of the error condition
description (Assignable)
Contains a character string that describes the error condition. A zero-length string indicates that the subsystem does not provide a printable description for the error. If Error:genCode is not zero, a printable description is always available.
filename Name of the file associated with the error
filename (Assignable)
Contains a character value representing the name originally used to open the file associated with the error condition. A zero-length string indicates either that the error condition is not associated with a particular file or that the subsystem does not retain file name information.
genCode CA-Clipper error code number
genCode (Assignable)
Contains an integer numeric value representing a CA-Clipper generic error code. Generic error codes allow default handling of similar errors from different subsystems. A value of zero indicates that the error condition is specific to the subsystem and does not correspond to any of the generic error codes. The header file, error.ch, provides a set of manifest constants for generic error codes.
operation Character description of the failed operation
operation (Assignable)
Contains a character string that describes the operation being attempted when the error occurred. For operators and functions, Error:operation contains the name of the operator or function. For undefined variables or functions, it contains the name of the variable or function. A zero-length string indicates that the subsystem does not provide a printable description of the operation.
osCode Operating system error code number
osCode (Assignable)
Contains an integer numeric value representing the operating system error code associated with the error condition. A value of zero indicates that the error condition was not caused by an error from the operating system. When Error:osCode is set to a value other than zero, DosError() is updated with the same value.
Error:osCode properly reflects the DOS extended error code for file errors. This allows proper distinction between errors which result from sharing violations (e.g., opening EXCLUSIVE when another process has already opened the file) and access violations (e.g., opening read/write when the file is marked read-only).
For a list of DOS error codes refer to the Error Messages and Appendices Guide.
severity Indicates error severity
severity (Assignable)
Contains a numeric value indicating the severity of the error condition. Four standard values are defined in error.ch:
Error:severity Values
       Error.ch            Meaning
       ES_WHOCARES         The condition does not represent a failure; the
                           error is informational.
       ES_WARNING          The condition does not prevent further
                           operations, but may result in a more serious
                           error later.
       ES_ERROR            The condition prevents further operations without
                           corrective action of some kind.
       ES_CATASTROPHIC     The condition requires immediate termination of
                           the application.
Note that the CA-Clipper runtime support code only generates errors with severities of ES_WARNING or ES_ERROR.
subCode Subsystem-specific error code number
subCode (Assignable)
Contains an integer numeric value representing a subsystem-specific error code. A value of zero indicates that the subsystem does not assign any particular number to the error condition.
subSystem Character description of the subsystem generating the error
subSystem (Assignable)
Contains a character string representing the name of the subsystem generating the error. For errors with basic CA-Clipper operators and functions, the subsystem name "BASE" is given. For errors generated by a database driver, Error:subSystem contains the name of the database driver.
tries Number of times the failed operation has been attempted
tries (Assignable)
Contains an integer numeric value representing the number of times the failed operation has been attempted. When Error:canRetry is true (.T.), Error:tries can be used to limit the number of retry attempts. A value of zero indicates that the subsystem does not track the number of times the operation has been tried.
Examples
■  This example demonstrates how a file open operation might be
   handled in an error handler replicating the default CA-Clipper
   behavior.  When, for example, an attempt to open a database file with
   a USE command fails, control returns to the statement following the
   offending command:

   #include "Error.ch"
   #command RETRY      => RETURN (.T.)   // Retry operation
   #command RESUME      => RETURN (.F.)   // Default recovery
   //

   FUNCTION MyError( <oError> )
      //
      // Handle file open error
      IF <oError>:genCode == EG_OPEN .AND.;
         <oError>:canDefault .AND.;
         NetErr()
         //
         RESUME
      ENDIF
      .
      . <other error statements>
      .
      RETURN NIL

■  This example retries an operation within an error handler a
   specified number of times:

   #include "Error.ch"
   #command RETRY      => RETURN (.T.)   // Retry operation
   #command RESUME      => RETURN (.F.)   // Default recovery
   //

   FUNCTION MyError( <oError> )
      //
      // Handle printer not ready error
      IF <oError>:genCode == EG_PRINT .AND.;
         <oError>:canRetry .AND.;
         <oError>:tries < 25
         //
         RETRY
      ENDIF
      .
      . <other error statements>
      .
      RETURN NIL

■  This code fragment returns an error object from an error
   handler to the RECOVER statement for further processing:

   LOCAL objLocal, bLastHandler
   //
   // Save current and set new error handler
   bLastHandler := ErrorBlock({    |oErr| ;
                     MyHandler(oErr, .T.)})
   //
   BEGIN SEQUENCE
      .
      . <operation that might fail>
      .
   RECOVER USING objLocal
      .
      . <send messages to objLocal and handle the error>
      .
   END
   //
   // Restore previous error handler
   ErrorBlock( bLastHandler )

   FUNCTION MyHandler( <oError>, lLocalHandler )
      //
      // Handle locally returning the error object
      IF lLocalHandler
         BREAK <oError>
      ENDIF
      .
      . <other statements to handle the error>
      .
      RETURN NIL
Platforms
Available on MS-DOS
File
Header file is error.ch, default error handler is in Errorsys.prg.
See also

ErrorBlock()Harbour implementation  | 

Post a code block to execute when a runtime error occurs
Syntax
ErrorBlock([<bErrorHandler>]) → bCurrentErrorHandler
Arguments
bErrorHandler is the code block to execute whenever a runtime error occurs. When evaluated, the bErrorHandler is passed an error object as an argument by the system.
Returns
ErrorBlock() returns the current error handling code block. If no error handling block has been posted since the program was invoked, ErrorBlock() returns the default error handling block.
Description

ErrorBlock() is an error function that defines an error handler to execute whenever a runtime error occurs. Specify the error handler as a code block with the following form,

{ |oError| expression list,... }

where oError is an error object containing information about the error. Within the code block, messages can be sent to the error object to obtain information about the error. Returning true (.T.) from the error handling block retries the failed operation and false (.F.) resumes processing.

The error handling code block can be specified either as a list of expressions or as a call to a user-defined function. A call to a user- defined function is more useful since you can use CA-Clipper control statements instead of expressions. This is particularly the case if there is a BEGIN SEQUENCE pending and you want to BREAK to the nearest RECOVER statement.

As this implies, error handling blocks can be used in combination with BEGIN SEQUENCE...END control structures. Within an error handling block, you handle device, low-level, and common errors that have a general recovery mechanism. If the operation needs specific error handling, define a BEGIN SEQUENCE then BREAK to the RECOVER statement, returning the error object for local processing. See the example below.

If no bErrorHandler has been specified using ErrorBlock() and a runtime error occurs, the default error handling block is evaluated. This error handler displays a descriptive message to the screen, sets the ErrorLevel() to 1, then QUITs the program.

Since ErrorBlock() returns the current error handling block, it is possible to specify an error handling block for an operation saving the current error handling block, then restore it after the operation has completed. Also, error handlers specified as code blocks, can be passed to procedures and user-defined functions, and RETURNed as values.

For more information on the structure and operations of error objects, refer to the Error class entry in this chapter and the "Error Handling Strategies" chapter in the Programming and Utilities Guide.

Examples
■  This code fragment posts, and then calls an error handling
   block when there is an error within a BEGIN SEQUENCE construct:

   LOCAL bErrorHandler, bLastHandler, objErr
   bErrorHandler := { |oError| ;
         MyErrorHandler(oError) }
   //
   // Save current handler
   bLastHandler := ErrorBlock(bErrorHandler)
   //
   BEGIN SEQUENCE
      .
      . <operation statements>
      .
   // Receive error object from BREAK
   RECOVER USING oErrorInfo
      .
      . <recovery statements>
      .
   END
   ErrorBlock(bLastHandler)      // Restore handler
   RETURN

   FUNCTION MyErrorHandler( oError )
      //
      BREAK oError      // Return error object to RECOVER
      RETURN NIL
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ErrorLevel()Harbour implementation  | 

Set the CA-Clipper return code
Syntax
ErrorLevel([<nNewReturnCode>]) → nCurrentReturnCode
Arguments
nNewReturnCode is the new return code setting. This can be a value between zero and 255. The default value at startup is zero. If not specified, ErrorLevel() reports the current setting without assigning a new value.
Returns
ErrorLevel() returns the current CA-Clipper exit code as a numeric value, if one has been set using ErrorLevel() with an argument; otherwise, it returns zero.
Description

ErrorLevel() is a dual purpose environment function. It returns the current CA-Clipper return code and optionally sets a new return code. The return code is a value set by a child process so the parent process can test the termination state of the child process. Typically, the parent process is DOS and the child process is an application program. Retrieve a return code with the DOS ERRORLEVEL command or INT 21 Function 4Dh.

When a CA-Clipper program terminates, the return code is set to 1 if the process ends with a fatal error. If the process ends normally, the return code is set to zero, or the last ErrorLevel() set in the program.

Typically, you would set a return code with ErrorLevel() to indicate an error state to the program that invoked the current CA-Clipper program. In most cases this is the application batch file. Here you would test the return code using the DOS ERRORLEVEL command. Refer to your DOS manual for more information.

Notes

ErrorLevel() is not updated after a RUN command terminates.

To obtain the return code of the invoked program, you must create an assembler or C routine that queries the child process return code using INT 21 Function 4Dh. Refer to your DOS documentation for more information.

Examples
■  This example saves the current CA-Clipper return code, then
   sets a new value:

   nOldCode := ErrorLevel()      // Get current error level
   ErrorLevel(1)                 // Set new error level

■  This example uses ErrorLevel() to set a return code that can
   be tested by the parent process:

   #define ERR_FILE_MISSING      255
   #define ERR_POST_INCOMPLETE   254
   //
   IF !FILE("Sysfile.dbf")
      @ 0, 0
      @ 1, 0
      @ 0, 0 SAY "Fatal error: System ;
                  file is missing...quitting"
      ErrorLevel(ERR_FILE_MISSING)
      QUIT
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

ERASEHarbour implementation | 

Remove a file from disk
Syntax
ERASE | DELETE FILE <xcFile>
Arguments
xcFile is the name of the file to be deleted from disk and can be specified either as a literal file name or as a character expression enclosed in parentheses. The file name must be fully specified including the extension, and it may optionally be preceded by a drive and/or path specification.
Description

ERASE is a file command that removes a specified file from disk. SET DEFAULT and SET PATH do not affect ERASE. The file is deleted from disk only if found in the current DOS directory or in the directory explicitly specified as part of the file name.

Warning! Files must be CLOSEd before being ERASEd. Otherwise, either a sharing violation or a date corruption on the drive may occur.

Examples
■  This example removes a specified file from disk and then tests
   to see if the file was in fact removed:

   ? FILE("Temp.dbf")         // Result: .T.
   ERASE Temp.dbf
   ? FILE("Temp.dbf")         // Result: .F.
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Eval()Harbour implementation  | 

Evaluate a code block
Syntax
Eval(<bBlock>, [<BlockArg list>]) → LastBlockValue
Arguments
bBlock is the code block to be evaluated.
BlockArg list is a list of arguments to send to the code block before it is evaluated.
Returns
Eval() returns the value of the last expression within the block. A code block can return a value of any type.
Description

Eval() is a code block function. It is the most basic code block evaluation facility in the CA-Clipper system. A code block is a special data value that refers to a piece of compiled program code. For more information on code blocks, refer to the "Basic Concepts" chapter in the Programming and Utilities Guide.

To execute or evaluate a code block, call Eval() with the block value and any parameters. The parameters are supplied to the block when it is executed. Code blocks may be a series of expressions separated by commas. When a code block is evaluated, the returned value is the value of the last expression in the block.

The CA-Clipper compiler usually compiles a code block at compile time. There are, however, occasions at runtime when you may need to compile a code block from a character string. You can do this by using the macro operator (&).

Eval() is often used to create iteration functions. These are functions that apply a block to each member of a data structure. AEval(), ASort(), AScan(), and dbEval() are iteration functions (e.g., AEval() applies a block to each element within an array).

Examples
■  This example creates a code block that increments a number,
   and then evaluates it:

   bBlock := { |nArg| nArg + 1 }
   ? Eval(bBlock, 1)                     // Result: 2

■  This example demonstrates compiling a code block at runtime
   using the macro operator (&):

   // Compile a string to a block
   bBlock := &("{ |nArg| nArg + 1 }")

   // Evaluate the block
   ? Eval(bBlock, 1)                     // Result: 2
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Exp()Harbour implementation  | 

Calculate e**x
Syntax
Exp(<nExponent>) → nAntilogarithm
Arguments
nExponent is the natural logarithm for which a numeric value is to be calculated.
Returns
Exp() returns a numeric value that is equivalent to the value e raised to the specified power.
Description

Exp() is a mathematical function that calculates the value, y, (the antilogarithm) of the following equation,

e**x = y

where e is the base of natural logarithms (2.71828...) and x is nExponent. The maximum value of nExponent is 45 before a numeric overflow occurs. Exp() and Log() are inverse functions.

The number of decimal places displayed is determined solely by SET DECIMALS regardless of the current SET FIXED value.

Examples
■  This example demonstrates several invocations of Exp():

   ? Exp(1)                       // Result: 2.72
   SET DECIMALS TO 10
   ? Exp(1)                       // Result: 2.7182818285
   ? Log(Exp(1))                  // Result: 1.0000000000
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

EXIT PROCEDUREHarbour implementation | 

Declare an exit procedure
Syntax
EXIT PROCEDURE <idProcedure>
   [FIELD <idField list> [IN <idAlias>]]
   [LOCAL <identifier> [[:= <initializer>]]]
   [MEMVAR <identifer list>]
   .
   . <executable statements>
   .
   [RETURN]
Arguments
EXIT PROCEDURE declares a procedure that will be executed on program termination.
idProcedure is the name of the exit procedure to declare. Exit procedure names can be any length, but only the first 10 characters are significant. Names may not begin with an underscore but can contain any combination of characters, numbers, or underscores.
FIELD declares a list of identifiers to use as field names whenever encountered. If the IN clause is specified, referring to the declared name includes an implicit reference to the specified alias.
LOCAL declares and optionally initializes a list of variables or arrays whose visibility and lifetime is the current procedure.
MEMVAR declares a list of identifiers to use as private or public memory variables or arrays whenever encountered.
RETURN passes control to the next exit procedure or to the operating system, if no other exit procedures are pending.
Description

The EXIT PROCEDURE statement declares a procedure that will be executed upon program termination. EXIT procedures are called after the last executable statement in a CA-Clipper application has completed. EXIT PROCEDUREs can be used to perform common housekeeping tasks such as saving configuration settings to a file, closing a log file, or concluding a communications session.

The visibility of exit procedures is restricted to the system; therefore, it is not possible to call an EXIT PROCEDURE from a procedure or user-defined function. Exit procedures do not receive parameters.

Once the last executable statement has completed, control passes from one EXIT PROCEDURE to the next until all procedures in the exit list have been called. Control then passes to the operating system.

The ANNOUNCE statement declares a module identifier for a source (.prg) file. Once declared, EXIT PROCEDUREs are referenced with this module identifier. An application may use any number of exit procedures by explicitly REQUESTing their module identifiers.

The EXIT PROCEDUREs requested for an application are collectively referred to as the exit list. There is no mandatory execution order of procedures in the exit list; however, if an EXIT PROCEDURE is declared in the same source (.prg) file as the application's primary routine (root), it is guaranteed to be the first exit procedure called.

Termination of a given CA-Clipper application can be attributed to any of the following:

RETURNing from the primary (root) routine

■ the QUIT command

■ issuing a BREAK without an enclosing BEGIN SEQUENCE...END

■ unrecoverable error

Execution of an EXIT PROCEDURE cannot be guaranteed when the system encounters an unrecoverable error. If an error is raised during an exit procedure, the system returns to DOS. Pending exit procedures are not called.

Examples
■  This example illustrates construction of a simple timing
   mechanism using INIT and EXIT PROCEDUREs:

   // prints the amount of time required to read,
   // sort, and display a list of file names.

   ANNOUNCE MySystem

   STATIC nStart

   PROCEDURE Main()
      AEval( ASort( Directory( "*.*" ) ),;
         { | aFileInfo | QOut( aFileInfo[ 1 ] ) } )
      RETURN

   INIT PROCEDURE MyInit()
      nStart := Seconds()
      RETURN

   EXIT PROCEDURE MyExit()
      ?
      ? "Elapsed Time: "
      ?? Seconds() - nStart
      RETURN
Platforms
Available on MS-DOS
See also

EXTERNAL* | 

Declare a list of procedure or user-defined function names to the linker
Syntax
EXTERNAL <idProcedure list>
Arguments
idProcedure list is the list of procedures, user-defined functions, or format procedures to add to the list of routines that will be linked into the current executable (.EXE) file.
Description

EXTERNAL is a declaration statement that specifies uncoded references to the linker. Like all other declaration statements, an EXTERNAL statement must be specified before any executable statements in either the program file, or a procedure or user-defined function definition.

During the compilation of CA-Clipper source code, all explicit references to procedures and user-defined functions are made to the linker. In some instances, there may be no references made to procedure or user-defined function names until runtime. EXTERNAL resolves this by forcing the named procedures or user-defined functions to be linked even if they are not explicitly referenced in the source file. This is important in several instances:

■ Procedures, user-defined functions, or formats referenced with

macro expressions or variables

■ Procedures and user-defined functions used in REPORT and LABEL

FORMs and not referenced in the source code

■ User-defined functions used in index keys and not referenced

in the source code

AChoice(), dbEdit(), or MemoEdit() user functions

To group common EXTERNAL declarations together, place them in a header file and then include (#include) the header file into each program (.prg) file that might indirectly use them.

EXTERNAL is a compatibility statement and therefore not recommended. It is superseded by the REQUEST statement that defines a list of module identifiers to the linker.

Examples
■  These examples are equivalent header files consisting of
   common EXTERNAL references for REPORT FORMs:

   // Externals.ch
   EXTERNAL HardCR
   EXTERNAL Tone
   EXTERNAL MemoTran
   EXTERNAL StrTran

   // Externals.ch
   EXTERNAL HardCR, TONE, MEMOTRAN, STRTRAN
Platforms
Available on MS-DOS
See also

FClose()Harbour implementation  | 

Close an open binary file and write DOS buffers to disk
Syntax
FClose(<nHandle>) → lError
Arguments
nHandle is the file handle obtained previously from FOpen() or FCreate().
Returns
FClose() returns false (.F.) if an error occurs while writing; otherwise, it returns true (.T.).
Description

FClose() is a low-level file function that closes binary files and forces the associated DOS buffers to be written to disk. If the operation fails, FClose() returns false (.F.). FError() can then be used to determine the reason for the failure. For example, attempting to use FClose() with an invalid handle returns false (.F.), and FError() returns DOS error 6, invalid handle. See FError() for a complete list of error numbers.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples
■  This example uses FClose() to close a newly created binary
   file and displays an error message if the close fails:

   #include "Fileio.ch"
   //
   nHandle := FCreate("Testfile", FC_NORMAL)
   IF !FClose(nHandle)
      ? "Error closing file, error number: ", FError()
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FCount()Harbour implementation  | 

Return the number of fields in the current .dbf file
Syntax
FCount() → nFields
Returns
FCount() returns the number of fields in the database file in the current work area as an integer numeric value. If there is no database file open, FCount() returns zero.
Description

FCount() is a database function. It is useful in applications containing data-independent programs that can operate on any database file. These include generalized import/export and reporting programs. Typically, you use FCount() to establish the upper limit of a FOR...NEXT or DO WHILE loop that processes a single field at a time.

By default, FCount() operates on the currently selected work area.

Examples
■  This example illustrates FCount(), returning the number of
   fields in the current and an unselected work area:

   USE Sales NEW
   USE Customer NEW
   ? FCount()                     // Result: 5
   ? Sales->(FCount())            // Result: 8

■  This example uses FCount() to DECLARE an array with field
   information:

   LOCAL aFields := Array(FCount())
   AFields(aFields)

■  This example uses FCount() as the upper boundary of a FOR loop
   that processes the list of current work area fields:

   LOCAL nField
   USE Sales NEW
   FOR nField := 1 TO FCount()
      ? Field(nField)
   NEXT
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FCreate()Harbour implementation  | 

Create and/or truncate a binary file to zero-length
Syntax
FCreate(<cFile>, [<nAttribute>]) → nHandle
Arguments
cFile is the name of the file to create. If the file already exists, its length is truncated to zero without warning.
nAttribute is one of the binary file attributes shown in the table below. If this argument is omitted, the default value is zero.
Binary File Attributes
    Value   Fileio.ch      Attribute Description
    0       FC_NORMAL      Normal    Create normal read/write file (default)
    1       FC_READONLY    Read-only Create read-only file
    2       FC_HIDDEN      Hidden    Create hidden file
    4       FC_SYSTEM      System    Create system file
Returns
FCreate() returns the DOS file handle number of the new binary file in the range of zero to 65,535. If an error occurs, FCreate() returns -1 and FError() is set to indicate an error code.
Description

FCreate() is a low-level file function that either creates a new file or opens and truncates an existing file. If cFile does not exist, it is created and opened for writing. If it does exist and can be opened for writing, it is truncated to zero-length. If it cannot be opened for writing, FCreate() returns -1 and FError() returns the appropriate error value.

When FCreate() successfully creates a new file, the file is left open in compatibility sharing mode and read/write access mode. The file attribute specified by the nAttribute argument is applied to the new file when it is closed, allowing writing to a newly created read-only file. For a list of access modes, see FOpen().

Since a file handle is required in order to identify an open file to other file functions, always assign the return value from FCreate() to a variable for later use.

Like other file functions, FCreate() does not use either the DEFAULT or PATH settings for its operation. Instead, it writes to the current DOS directory unless a path is explicitly stated.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples
■  This example creates a file called Testfile and opens it for
   reading and writing:

   #include "Fileio.ch"

   //
   IF (nHandle := FCreate("Testfile", FC_NORMAL)) == -1
      ? "File cannot be created:", FError()
      BREAK
   ELSE
      FWrite(nHandle, "Hello there")
      FClose(nHandle)
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is fileio.ch.
See also

FErase()Harbour implementation  | 

Delete a file from disk
Syntax
FErase(<cFile>) → nSuccess
Arguments
cFile is the name of the file to be deleted from disk, including extension, optionally preceded by a drive and/or path specification.
Returns
FErase() returns -1 if the operation fails and zero if it succeeds. In the case of a failure, FError() can be used to determine the nature of the error.
Description

FErase() is a file function that deletes a specified file from disk. FErase() is the same as the ERASE command but returns a value and can be specified within an expression. When FErase() is called, cFile is deleted from disk only if found in the current DOS directory or in the directory explicitly specified as part of the file name. Like the other file functions and commands, FErase() does not use either SET DEFAULT or SET PATH to locate cFile.

Warning! Files must be CLOSEd before removing them with FErase().

Examples
■  This example deletes a set of files matching a wildcard
   pattern:

   #include "Directry.ch"
   AEval(Directory("*.BAK"), { |aFile| ;
      FErase(aFile[F_NAME]) })

■  This example erases a file and displays a message if the
   operation fails:

   IF FErase("AFile.txt") == -1
      ? "File erase error:", FError()
      BREAK
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FError()Harbour implementation  | 

Test for errors after a binary file operation
Syntax
FError() → nErrorCode
Returns
FError() returns the DOS error from the last file operation as an integer numeric value. If there is no error, FError() returns zero.
FError() Return Values
    Error   Meaning
    0       Successful
    2       File not found
    3       Path not found
    4       Too many files open
    5       Access denied
    6       Invalid handle
    8       Insufficient memory
    15      Invalid drive specified
    19      Attempted to write to a write-protected disk
    21      Drive not ready
    23      Data CRC error
    29      Write fault
    30      Read fault
    32      Sharing violation
    33      Lock Violation
Description

FError() is a low-level file function that indicates a DOS error after a file function is used. These functions include FClose(), FCreate(), FErase(), FOpen(), FRead(), FReadStr(), and FRename(). FError() retains its value until the next execution of a file function.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples
■  This example tests FError() after the creation of a binary
   file and displays an error message if the create fails:

   #include "Fileio.ch"
   //
   nHandle := FCreate("Temp.txt", FC_NORMAL)
   IF FError() != 0
      ? "Cannot create file, DOS error ", FError()
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FieldBlock()Harbour implementation  | 

Return a set-get code block for a given field
Syntax
FieldBlock(<cFieldName>) → bFieldBlock
Arguments
cFieldName is the name of the field to which the set-get block will refer.
Returns
FieldBlock() returns a code block that, when evaluated, sets (assigns) or gets (retrieves) the value of the given field. If cFieldName does not exist in the specified work area, FieldBlock() returns an empty block.
Description

FieldBlock() is a database function that builds a code block. When executed with an argument, the code block created by this function assigns the value of the argument to cFieldName. When executed without an argument, the code block retrieves the value of cFieldName.

Note that the specified field variable may not exist when the code block is created, but must exist before the code block is executed.

Notes

■ Work area: The code block returned by FieldBlock() sets or

gets the value of the specified field in whatever work area is current when the block is run. For example, given work areas 1 and 2, both containing field FName:

SELECT 1

FName:= "Kate" SELECT 2

FName := "Cindy" bFName := FieldBlock("FName") SELECT 1 ? Eval(bFName) // Result: "Kate" SELECT 2 ? Eval(bFName) // Result: "Cindy"

The function FieldWBlock() provides a set-get block for a field in a specific work area.

Examples
■  This example compares FieldBlock() to a code block created
   using the macro operator.  Note that using FieldBlock() avoids the
   speed and size overhead of the macro operator:

   // Set-Get block defined using macro operator
   bSetGet := &( "{ |setVal| IF( setVal == NIL,;
                   FName, FName := setVal ) }" )
   // Set-Get block defined using FieldBlock()

   // bSetGet created here is the functional
   // equivalent of bSetGet above
   bSetGet := FieldBlock("FName")
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FieldGet()Harbour implementation  | 

Retrieve the value of a field using the ordinal position of the field in the database structure
Syntax
FieldGet(<nField>) → ValueField
Arguments
nField is the ordinal position of the field in the record structure for the current work area.
Returns
FieldGet() returns the value of the specified field. If nField does not correspond to the position of any field in the current database file, FieldGet() returns NIL.
Description
FieldGet() is a database function that retrieves the value of a field using its position within the database file structure rather than its field name. Within generic database service functions this allows, among other things the retrieval of field values without use of the macro operator.
Examples
■  This example compares FieldGet() to functionally equivalent
   code that uses the macro operator to retrieve the value of a field:

   LOCAL nField := 1, FName, FVal
   USE Customer NEW
   //
   // Using macro operator
   FName := Field( nField )           // Get field name
   FVal := &FName                     // Get field value
   // Using FieldGet()
   FVal := FieldGet( nField )         // Get field value
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FieldName()/Field()  | 

Return a field name from the current database (.dbf) file
Syntax
FIELDNAME/Field(<nPosition>) → cFieldName
Arguments
nPosition is the position of a field in the database file structure.
Returns
FieldName() returns the name of the specified field as a character string. If nPosition does not correspond to an existing field in the current database file or if no database file is open in the current work area, FieldName() returns a null string ("").
Description

FieldName() is a database function that returns a field name using an index to the position of the field name in the database structure. Use it in data-independent applications where the field name is unknown. If information for more than one field is required, use AFields() to create an array of field information or COPY STRUCTURE EXTENDED to create a database of field information.

If you need additional database file structure information, use Type() and Len(). To obtain the number of decimal places for a numeric field, use the following expression:

Len(SubStr(Str(idField), RAt(".", ;

Str(idField)) + 1))

By default, FieldName() operates on the currently selected work area as shown in the example below.

Examples
■  These examples illustrate FieldName() used with several other
   functions:

   USE Sales
   ? FieldName(1)              // Result: BRANCH
   ? FCount()                  // Result: 5
   ? Len(FieldName(0))         // Result: 0
   ? Len(FieldName(40))        // Result: 0

■  This example uses FieldName() to list the name and type of
   each field in Customer.dbf:

   USE Customer NEW
   FOR nField := 1 TO FCount()
      ? PadR(FieldName(nField), 10),;
             ValType(&(FieldName(nField)))
   NEXT

■  This example accesses fields in unselected work areas using
   aliased expressions:

   USE Sales NEW
   USE Customer NEW
   USE Invoices NEW
   //
   ? Sales->(FieldName(1))            // Result: SALENUM
   ? Customer->(FieldName(1))         // Result: CUSTNUM
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FieldPos()Harbour implementation  | 

Return the position of a field in a work area
Syntax
FieldPos(<cFieldName>) → nFieldPos
Arguments
cFieldName is the name of a field in the current or specified work area.
Returns
FieldPos() returns the position of the specified field within the list of fields associated with the current or specified work area. If the current work area has no field with the specified name, FieldPos() returns zero.
Description

FieldPos() is a database function that is the inverse of the FieldName() function. FieldPos() is most often used with the FieldPut() and FieldGet() functions.

FieldPos() return the names of fields in any unselected work area by referring to the function using an aliased expression. See the example below.

Examples
■  This example demonstrates a typical specification of the
   FieldPos() function:

   USE Customer NEW
   ? FieldPos("Name")                     // Result: 1
   ? FieldGet(FieldPos("Name"))           // Result: Kate

■  This example uses FieldPos() to return the position of a
   specified field in a unselected work area:

   USE Customer NEW
   USE Invoices NEW
   ? Customer->(FieldPos("Name"))         // Result: 1
   ? Customer->(FieldGet(FieldPos("Name")))
                                          // Result: Kate
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FieldPut()Harbour implementation  | 

Set the value of a field variable using the ordinal position of the field in the database structure
Syntax
FieldPut(<nField>, <expAssign>) → ValueAssigned
Arguments
nField is the ordinal position of the field in the current database file.
expAssign is the value to assign to the given field. The data type of this expression must match the data type of the designated field variable.
Returns
FieldPut() returns the value assigned to the designated field. If nField does not correspond to the position of any field in the current database file, FieldPut() returns NIL.
Description
FieldPut() is a database function that assigns expAssign to the field at ordinal position nField in the current work area. This function allows you to set the value of a field using its position within the database file structure rather than its field name. Within generic database service functions this allows, among other things, the setting of field values without use of the macro operator.
Examples
■  This example compares FieldPut() to functionally equivalent
   code that uses the macro operator to set the value of a field:

   // Using macro operator
   FName := Field(nField)           // Get field name
   FIELD->&FName := FVal            // Set field value
   // Using FieldPut()
   FieldPut(nField, FVal)           // Set field value
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FieldWBlock()Harbour implementation  | 

Return a set-get code block for a field in a given work area
Syntax
FieldWBlock(<cFieldName>, <nWorkArea>)
   → bFieldWBlock
Arguments
cFieldName is the name of the field specified as a character string.
nWorkArea is the work area number where the field resides specified as a numeric value.
Returns
FieldWBlock() returns a code block that, when evaluated, sets (assigns) or gets (retrieves) the value of cFieldName in the work area designated by nWorkArea. If cFieldName does not exist in the specified work area, FieldWBlock() returns an empty block.
Description

FieldWBlock() is a database function that builds a code block. When evaluated with the Eval() function, the code block first selects the designated nWorkArea. If an argument was passed, the code block then assigns the value of the argument to cFieldName. If no argument was passed, the code block retrieves the value of cFieldName. The original work area is then reselected before the code block returns control.

Note that the specified field variable may not exist when the code block is created but must exist before the code block is executed.

Notes

FieldWBlock() is similar to FieldBlock(), except that

FieldBlock() incorporates a fixed work area into the set-get block.

Examples
■  This example compares FieldWBlock() to a code block created
   using the macro operator.  Note that using FieldWBlock() avoids the
   speed and size overhead of the macro operator:

   // Set-Get block for work area 1 defined with
   // macro operator
   bSetGet := &( "{ |setVal| IF( setVal == NIL, ;
      1->FName, 1->FName := setVal ) }" )
   // Set-Get block defined using FieldWBlock()

   // bSetGet created here is the functional
   // equivalent of bSetGet above
   bSetGet := FieldWBlock("FName", 1)
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FIELD | 

Declare database field names
Syntax
FIELD <idField list> [IN <idAlias>]
Arguments
idField list is a list of names to declare as fields to the compiler.
IN idAlias specifies an alias to assume when there are unaliased references to the names specified in the idField list. Unaliased references to variables in idField list are treated as if they are preceded by the special field alias (FIELD->).
Description

The FIELD statement declares the names of database fields to the compiler, and optionally supplies an implicit alias for each name. This allows the compiler to resolve references to variables with no explicit alias—by implicitly assuming the specified idAlias. Only explicit, unaliased references to the specified fields in the idField list are affected. The FIELD statement, like all declarations, has no effect on references made within macro expressions or variables.

The FIELD statement neither opens a database file nor verifies the existence of the specified fields. It is useful primarily to ensure correct references to fields whose accessibility is known at runtime. Attempting to access the fields when the associated database is not in USE will cause an error.

The scope of the FIELD declaration is the procedure or function in which it occurs, or the entire program (.prg) file if the declaration precedes all PROCEDURE or FUNCTION declarations and the /N compiler option is specified.

FIELD statements, like other declarations, must precede any executable statements in the procedure or function definition or the program (.prg) file if the declaration has filewide scope.

FIELD used with the /W compiler option performs compile-time checking for undeclared variables.

For more information on variable declarations and scoping, refer to the Variables section in the "Basic Concepts" chapter of the Programming and Utilities Guide.

Examples
■  This user-defined function includes statements to declare
   database field names in both the current and Employee work areas:

   FUNCTION DisplayRecord
      FIELD CustNo, OrderNo, Salesman
      FIELD EmpName, EmpCode IN Employee
      USE Employee NEW
      USE Orders NEW
      //
      ? CustNo               // Refers to Orders->CustNo
      ? EmpName              // Refers to Employee->EmpName
      //
      CLOSE Orders
      CLOSE Employee
      RETURN NIL
Platforms
Available on MS-DOS
See also

FILE()Harbour implementation  | 

Determine if files exist in the CA-Clipper default directory or path
Syntax
FILE(<cFilespec>) → lExists
Arguments
cFilespec is in the current CA-Clipper default directory and path. It is a standard file specification that can include the wildcard characters * and ? as well as a drive and path reference. Explicit references to a file must also include an extension.
Returns
File() returns true (.T.) if there is a match for any file matching the cFilespec pattern; otherwise, it returns false (.F.).
Description

File() is an environment function that determines whether any file matching a file specification pattern is found. File() searches the specified directory if a path is explicitly specified.

If a path is not specified, File() searches the current CA-Clipper default directory and then the CA-Clipper path. In no case is the DOS path searched. Note also that File() does not recognize hidden or system files in its search.

Examples
■  In this example FILE() attempts to find Sales.dbf in other
   than the current CA-Clipper default:

   ? FILE("Sales.dbf")               // Result: .F.
   ? FILE("\APPS\DBF\Sales.dbf")     // Result: .T.
   //
   SET PATH TO \APPS\DBF
   ? FILE("Sales.dbf")               // Result: .T.
   //
   SET PATH TO
   SET DEFAULT TO \APPS\DBF\
   ? FILE("Sales.dbf")               // Result: .T.
   ? FILE("*.dbf")                   // Result: .T.
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FIND*Harbour implementation | 

Search an index for a specified key value
Syntax
FIND <xcSearchString>
Arguments
xcSearchString is part or all of the index key of a record to search for, and can be specified either as a literal string or as a character expression enclosed in parentheses. If an expression is specified instead of a literal string, FIND operates the same as SEEK.
Description

FIND is a database command that searches an index for the first key matching the specified character string and positions the record pointer to the corresponding record.

If SOFTSEEK is OFF and FIND does not find a record, the record pointer is positioned to LastRec() + 1, Eof() returns true (.T.), and Found() returns false (.F.).

If SOFTSEEK is ON, the record pointer is positioned to the record with the first key value greater than the search argument and Found() returns false (.F.). In this case, Eof() returns true (.T.) only if there are no keys in the index greater than the search argument.

FIND is a compatibility command and therefore not recommended. Its usage is superseded entirely by the SEEK command.

Examples
■  These examples show simple FIND results:

   USE Sales INDEX Branch NEW
   FIND ("500")
   ? Found(), Eof(), RecNo()         // Result: .F. .T. 85
   FIND "200"
   ? Found(), Eof(), RecNo()         // Result: .T. .F. 5
   FIND "100"
   ? Found(), Eof(), RecNo()         // Result: .T. .F. 1
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FKLabel()*Harbour implementation  | 

Return function key name
Syntax
FKLabel(<nFunctionKey>) → cKeyLabel
Returns
FKLabel() returns a character string representing the name of the function key specified by the numeric argument, nFunctionKey. If this argument is less than one or greater than 40, the function returns a null ("") string.
Description
FKLabel() is a compatibility function used to replicate the FKLabel() function in dBASE III PLUS. As a general principle, the use of this function is not recommended and not needed in CA-Clipper. The function keys are labeled Fn, where n ranges from one to 40 and corresponds directly to the FKLabel() argument.
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/FKLABEL.PRG.
See also

FKMax()*Harbour implementation  | 

Return number of function keys as a constant
Syntax
FKMax() → nFunctionKeys
Description
FKMax() is a compatibility function used to replicate the FKMax() function in dBASE III PLUS. As a general principle, the use of this function is not recommended and not needed in CA-Clipper. It simply returns a constant value of 40.
Platforms
Available on MS-DOS
File
Library is EXTEND.LIB, source file is SOURCE/SAMPLE/FKMAX.PRG.
See also

FLock()Harbour implementation  | 

Lock an open and shared database file
Syntax
FLock() → lSuccess
Returns
FLock() returns true (.T.) if an attempt to lock a database file in USE in the current work area succeeds; otherwise, it returns false (.F.). For more information on file locking, refer to the "Network Programming" chapter in the Programming and Utilities Guide.
Description

FLock() is a database function used in network environments to lock an open and shared database file, preventing other users from updating the file until the lock is released. Records in the locked file are accessible for read-only operations.

FLock() is related to USE...EXCLUSIVE and RLock(). USE...EXCLUSIVE opens a database file so that no other user can open the same file at the same time and is the most restrictive locking mechanism in CA-Clipper. RLock() is the least restrictive and attempts to place an update lock on a shared record, precluding other users from updating the current record. FLock() falls in the middle.

FLock() is used for operations that access the entire database file. Typically, these are commands that update the file with a scope or a condition such as DELETE or REPLACE ALL. The following is a list of such commands:

Commands that require an FLock()

    Command                       Mode
    APPEND FROM                   FLock() or USE...EXCLUSIVE
    DELETE (multiple records)     FLock() or USE...EXCLUSIVE
    RECALL (multiple records)     FLock() or USE...EXCLUSIVE
    REPLACE (multiple records)    FLock() or USE...EXCLUSIVE
    UPDATE ON                     FLock() or USE...EXCLUSIVE

For each invocation of FLock(), there is one attempt to lock the database file, and the result is returned as a logical value. A file lock fails if another user currently has a file or record lock for the same database file or EXCLUSIVE USE of the database file. If FLock() is successful, the file lock remains in place until you UNLOCK, CLOSE the DATABASE, or RLock().

By default, FLock() operates on the currently selected work area as shown in the example below.

Notes

SET RELATION: CA-Clipper does not automatically lock all work

areas in the relation chain when you lock the current work area, and an UNLOCK has no effect on related work areas.

Examples
■  This example uses FLock() for a batch update of prices in
   Inventory.dbf:

   USE Inventory NEW
   IF FLock()
      REPLACE ALL Inventory->Price WITH ;
            Inventory->Price * 1.1
   ELSE
      ? "File not available"
   ENDIF

■  This example uses an aliased expression to attempt a file lock
   in an unselected work area:

   USE Sales NEW
   USE Customer NEW
   //
   IF !Sales->(FLock())
      ? "Sales is in use by another"
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

Found()Harbour implementation  | 

Determine if the previous search operation succeeded
Syntax
Found() → lSuccess
Returns
Found() returns true (.T.) if the last search command was successful; otherwise, it returns false (.F.).
Description

Found() is a database function that determines whether a search operation (i.e., FIND, LOCATE, CONTINUE, SEEK, or SET RELATION) succeeded. When any of these commands are executed, Found() is set to true (.T.) if there is a match; otherwise, it is set to false (.F.).

If the search command is LOCATE or CONTINUE, a match is the next record meeting the scope and condition. If the search command is FIND, SEEK or SET RELATION, a match is the first key in the controlling index that equals the search argument. If the key value equals the search argument, Found() is true (.T.); otherwise, it is false (.F.).

The value of Found() is retained until another record movement command is executed. Unless the command is another search command, Found() is automatically set to false (.F.).

Each work area has a Found() value. This means that if one work area has a RELATION set to a child work area, querying Found() in the child returns true (.T.) if there is a match.

By default, Found() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression (see example below).

Found() will return false (.F.) if there is no database open in the current work area.

Examples
■  This example illustrates the behavior of Found() after a
   record movement command:

   USE Sales INDEX Sales
   ? IndexKey(0)              // Result: SALESMAN
   SEEK "1000"
   ? Found()                  // Result: .F.
   SEEK "100"
   ? Found()                  // Result: .T.
   SKIP
   ? Found()                  // Result: .F.

■  This example tests a Found() value in an unselected work area
   using an aliased expression:

   USE Sales INDEX Sales NEW
   USE Customer INDEX Customer NEW
   SET RELATION TO CustNum INTO Sales
   //
   SEEK "Smith"
   ? Found(), Sales->(Found())

■  This code fragment processes all Customer records with the key
   value "Smith" using Found() to determine when the key value changes:

   USE Customer INDEX Customer NEW
   SEEK "Smith"
   DO WHILE Found()
      .

      . <statements>
      .
      SKIP
      LOCATE REST WHILE Name == "Smith"
   ENDDO
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FOpen()Harbour implementation  | 

Open a binary file
Syntax
FOpen(<cFile>, [<nMode>]) → nHandle
Arguments
cFile is the name of the file to open, including the path if there is one.
nMode is the requested DOS open mode indicating how the opened file is to be accessed. The open mode is composed of elements from the two types of modes described in the tables below. If just the Access Mode is used, the file is opened non-sharable. The default open mode is zero, which indicates non-sharable and read-only.
FOpen() Access Modes
    Mode    Fileio.ch      Operation
    0       FO_READ        Open for reading (default)
    1       FO_WRITE       Open for writing
    2       FO_READWRITE   Open for reading or writing
The Sharing Modes determine how other processes may access the file.
FOpen() Sharing Modes
    Mode    Fileio.ch      Operation
    0       FO_COMPAT      Compatibility mode (default)
    16      FO_EXCLUSIVE   Exclusive use
    32      FO_DENYWRITE   Prevent others from writing
    48      FO_DENYREAD    Prevent others from reading
    64      FO_DENYNONE    Allow others to read or write
    64      FO_SHARED      Same as FO_DENYNONE
The Access Modes in combination (+) with the Sharing modes determine the accessibility of the file in a network environment.
Returns
FOpen() returns the file handle of the opened file in the range of zero to 65,535. If an error occurs, FOpen() returns -1.
Description

FOpen() is a low-level file function that opens an existing binary file for reading and writing, depending on the nMode argument. Whenever there is an open error, use FError() to return the DOS error number. For example, if the file does not exist, FOpen() returns -1 and FError() returns 2 to indicate that the file was not found. See FError() for a complete list of error numbers.

If the specified file is opened successfully, the value returned is the DOS handle for the file. This value is similar to an alias in the database system and is required to identify the open file to other file functions. It is, therefore, important to assign the return value to a variable for later use as in the example below.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Notes

■ Accessing files in other directories: FOpen() does not obey

either SET DEFAULT or SET PATH. Instead, it searches the current DOS directory and path setting unless a path is explicitly stated as part of the cFile argument.

Examples
■  This example uses FOpen() to open a file with  sharable
   read/write status and displays an error message if the open fails:

   #include "Fileio.ch"
   //
   nHandle := FOpen("Temp.txt", FO_READWRITE + FO_SHARED)
   IF FError() != 0
      ? "Cannot open file, DOS error ", FError()
      BREAK
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is fileio.ch.
See also

FOR | 

Execute a block of statements a specified number of times
Syntax
FOR <idCounter> := <nStart> TO <nEnd>
   [STEP <nIncrement>]
   <statements>...
   [EXIT]
   <statements>...
   [LOOP]
NEXT
Arguments
idCounter is the name of the loop control or counter variable. If the specified idCounter is not visible or does not exist, a private variable is created.
nStart is the initial value assigned to idCounter. If nIncrement is negative, nStart must be less than nEnd.
TO nEnd defines the final value of idCounter. If nIncrement is negative, nStart must be greater than nEnd; otherwise, nStart must be less than nEnd.
STEP nIncrement defines the amount idCounter is changed for each iteration of the loop. nIncrement can be either positive or negative. If the STEP clause is not specified, idCounter is incremented by one for each iteration of the loop.
EXIT unconditionally branches control from within a FOR...NEXT construct to the statement immediately following the nearest NEXT statement.
LOOP branches control to the most recently executed FOR or DO WHILE statement.
Description

FOR...NEXT is a control structure that executes a block of statements a specified number of times. The control structure loops from the initial value of idCounter to the boundary specified by nEnd, moving through the range of values of the control variable for an increment specified by nIncrement. All expressions in the FOR statement are reevaluated for each iteration of the loop. The nStart and nEnd expressions, therefore, can be changed as the control structure operates.

A FOR loop operates until idCounter is greater than nEnd or an EXIT statement is encountered. Control then branches to the statement following the corresponding NEXT statement. If a LOOP statement is encountered, control branches back to the current FOR statement.

If nIncrement is a negative value, idCounter is decremented rather than incremented. The FOR loop, however, continues until idCounter is less than nEnd. This means that nEnd must be less than nStart when the FOR loop begins.

FOR loops are useful for traversing arrays where idCounter is used as the array subscript. See the example below.

FOR...NEXT constructs may be nested within any other control structures to any depth. The only requirement is that each control structure is properly nested.

Examples
■  This example traverses an array in ascending order:

   nLenArray := Len(aArray)
   FOR i := 1 TO nLenArray
      <statements>...
   NEXT

■  To traverse an array in descending order:

   nLenArray := Len(aArray)
   FOR i := nLenArray TO 1 STEP -1
      <statements>...
   NEXT
Platforms
Available on MS-DOS
See also

FRead()Harbour implementation  | 

Read characters from a binary file into a buffer variable
Syntax
FRead(<nHandle>, @<cBufferVar>, <nBytes>) → nBytes
Arguments
nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.
cBufferVar is the name of an existing and initialized character variable used to store data read from the specified file. The length of this variable must be greater than or equal to nBytes. cBufferVar must be passed by reference and, therefore, must be prefaced by the pass- by-reference operator (@).
nBytes is the number of bytes to read into the buffer.
Returns
FRead() returns the number of bytes successfully read as an integer numeric value. A return value less than nBytes or zero indicates end of file or some other read error.
Description

FRead() is a low-level file function that reads characters from a binary file into an existing character variable. It reads from the file starting at the current DOS file pointer position, advancing the file pointer by the number of bytes read. All characters are read including control, null, and high-order (above Chr(127)) characters.

FRead() is similar in some respects to both FReadStr() and FSeek(). FReadStr() reads a specified number of bytes from a file up to the next null (Chr(0)) character. FSeek() moves the file pointer without reading.

If there is an error during the file read, FError() returns the DOS error number. See FError() for the list of error numbers.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples
■  This example uses FRead() after successfully opening a file to
   read 128 bytes into a buffer area:

   #define F_BLOCK      128
   //
   cBuffer := Space(F_BLOCK)
   nHandle := FOpen("Temp.txt")
   //
   IF FError() != 0
      ? "File open error:", FError()
   ELSE
      IF FRead(nHandle, @cBuffer, F_BLOCK) <> F_BLOCK
         ? "Error reading Temp.txt"
      ENDIF
      FClose(nHandle)
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FReadStr()Harbour implementation  | 

Read characters from a binary file
Syntax
FReadStr(<nHandle>, <nBytes>) → cString
Arguments
nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.
nBytes is the number of bytes to read, beginning at the current DOS file pointer position.
Returns
FReadStr() returns a character string up to 65,535 (64K) bytes. A null return value ("") indicates an error or end of file.
Description

FReadStr() is a low-level file function that reads characters from an open binary file beginning with the current DOS file pointer position. Characters are read up to nBytes or until a null character (Chr(0)) is encountered. All characters are read including control characters except for Chr(0). The file pointer is then moved forward nBytes. If nBytes is greater than the number of bytes from the pointer position to the end of the file, the file pointer is positioned to the last byte in the file.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples
■  This example displays the ASCII values of the first 16 bytes
   of a text file:

   #include "Fileio.ch"
   //
   nHandle := FOpen("New.txt", FC_NORMAL)
   IF FError() != 0
      ? "File open error:", FError()
   ELSE
      cString := FReadStr(nHandle, 16)
      ? cString
      FClose(nHandle)
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FRename()Harbour implementation  | 

Change the name of a file
Syntax
FRename(<cOldFile>, <cNewFile>) → nSuccess
Arguments
cOldFile is the name of the file to be renamed, including the file extension. A drive letter and/or path name may also be included as part of the file name.
cNewFile is the new name of the file, including the file extension. A drive letter and/or path name may also be included as part of the name.
Returns
FRename() returns -1 if the operation fails and zero if it succeeds. In the case of a failure, FError() can be used to determine the nature of the error.
Description

FRename() is a file function that changes the name of a specified file to a new name and is identical to the RENAME command.

When FRename() is called, cOldFile is renamed only if it is located in the current DOS directory or in the specified path. FRename() does not use SET DEFAULT or SET PATH to locate cOldFile.

If the source directory is different from the target directory, the file moves to the target directory. In the instance that either cNewFile exists or is currently open, FRename() fails and returns -1, indicating that it did not perform its designated action. The nature of the error can be determined with FError().

Warning! Files must be CLOSEd before renaming. Attempting to rename an open file will produce unpredictable results. When a database file is renamed, the associated memo (.dbt) file must also be renamed. Failure to do so may compromise the integrity of your databases.

Examples
■  This example demonstrates a file rename:

   IF FRename("OldFile.txt", "NewFile.txt") == -1
      ? "File error:", FError()
   ENDIF
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB.
See also

FSeek()Harbour implementation  | 

Set a binary file pointer to a new position
Syntax
FSeek(<nHandle>, <nOffset>, [<nOrigin>]) → nPosition
Arguments
nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.
nOffset is the number of bytes to move the file pointer from the position defined by nOrigin. It can be a positive or negative number. A positive number moves the pointer forward, and a negative number moves the pointer backward in the file.
nOrigin defines the starting location of the file pointer before FSeek() is executed. The default value is zero, representing the beginning of file. If nOrigin is the end of file, nOffset must be zero or negative.
Methods of Moving the File Pointer
    Origin  Fileio.ch      Description
    0       FS_SET         Seek from beginning of file
    1       FS_RELATIVE    Seek from the current pointer position
    2       FS_END         Seek from end of file
Returns
FSeek() returns the new position of the file pointer relative to the beginning of file (position 0) as an integer numeric value. This value is without regard to the original position of the file pointer.
Description

FSeek() is a low-level file function that moves the file pointer forward or backward in an open binary file without actually reading the contents of the specified file. The beginning position and offset are specified as function arguments, and the new file position is returned. Regardless of the function arguments specified, the file pointer cannot be moved beyond the beginning or end of file boundaries.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples
■  This example uses FSeek() to determine the length of a file by
   seeking from the end of file.  Then, the file pointer is reset to the
   beginning of file:

   #include "Fileio.ch"
   //
   // Open the file read-only
   IF (nHandle := FOpen("Temp.txt")) >= 0
      //
      // Get length of the file
      nLength := FSeek(nHandle, 0, FS_END)
      //
      // Reset file position to beginning of file
      FSeek(nHandle, 0)
      FClose(nHandle)
   ELSE
      ? "File open error:", FError()
   ENDIF

■  This pseudofunction positions the file pointer at the last
   byte in a binary file:

   #define FileBottom(nHandle);
         (FSeek(nHandle, 0, FS_END))

■  This pseudofunction positions the file pointer at the first
   byte in a binary file:

   #define FileTop(nHandle);
         (FSeek(nHandle, 0))

■  This pseudofunction reports the current position of the file
   pointer in a specified binary file:

   #define FilePos(nHandle);
         (FSeek(nHandle, 0, FS_RELATIVE))
Platforms
Available on MS-DOS
File
Library is CLIPPER.LIB, header file is fileio.ch.
See also

FUNCTION | 

Declare a user-defined function name and formal parameters
Syntax
[STATIC] FUNCTION <idFunction>[(<idParam list>)]
   [LOCAL <identifier> [[:= <initializer>], ... ]]
   [STATIC <identifier> [[:= <initializer>], ... ]]
   [FIELD <identifier list> [IN <idAlias>]]
   [MEMVAR <identifier list>]
   .
   . <executable statements>
   .
   RETURN <exp>
Arguments
idFunction is the name of the user-defined function to be declared. User-defined function names can be any length, but only the first 10 characters are significant. Names can contain any combination of characters, numbers, or underscores, but must begin with a character or an underscore. Leading underscores are not recommended since they are reserved for internal functions.
idParam list is the declaration of one or more parameter variables. Variables specified in this list are declared local.
STATIC FUNCTION declares a user-defined function that can be invoked only by procedures and user-defined functions declared in the same program (.prg) file.
LOCAL declares and optionally initializes a list of variables or arrays whose visibility and lifetime is the current function.
STATIC declares and optionally initializes a list of variables or arrays whose visibility is the current user-defined function and lifetime is the duration of the program.
FIELD declares a list of identifiers to use as field names whenever encountered. If the IN clause is specified, referring to the declared name includes an implicit reference to the specified alias.
MEMVAR declares a list of identifiers to use as private or public memory variables or arrays whenever encountered.
identifier and identifier list are labels to be used as variable or array names.
initializer is a value to which an array or variable is originally set in an inline expression.
RETURN exp passes control back to the calling procedure or user-defined function, returning the result of exp as the value of the function. Each function must have at least one RETURN statement that returns a value. RETURN statements can occur anywhere in the body of a function.
Description

The FUNCTION statement declares a user-defined function and an optional list of local variables to receive parameters often referred to as formal parameters. A user-defined function is a subprogram comprised of a set of declarations and statements executed whenever you refer to idFunction followed by an open and closed parentheses pair. A function definition begins with a FUNCTION statement which is the FUNCTION declaration and ends with the next FUNCTION statement, PROCEDURE statement, or end of file.

Functions encapsulate a computational block of code and then later create expressions using the value returned. Functions and procedures increase both readability and modularity, isolate change, and help manage complexity.

A function in CA-Clipper is the same as a procedure, except that it must return a value. The returned value can be any data type including an array, a code block, or NIL. Each function must begin with a FUNCTION statement and contain at least one RETURN statement with an argument. Function declarations cannot be nested within other function definitions. A user-defined function can be used wherever standard functions are supported, including expressions.

The visibility of function names falls into two classes. Functions that are visible anywhere in a program are referred to as public functions and declared with a FUNCTION statement. Functions that are visible only within the current program (.prg) file are referred to as static functions and declared with a STATIC FUNCTION statement. Static functions have filewide scope.

Static functions limit visibility of a function name, thereby restricting access to the function. Because of this, subsystems defined within a single program (.prg) file can provide an access protocol with a series of public functions and conceal the implementation details of the subsystem within static functions and procedures. Since the static function references are resolved at compile time, they preempt references to public functions which are resolved at link time. This ensures that within a program file, a reference to a static function executes that function if there is a name conflict with a public function.

For more information on user-defined functions, variable declarations, and parameter passing, refer to the "Basic Concepts" chapter in the Programming and Utilities Guide.

Notes

■ Calling a user-defined function: Use the same notation to call

a user-defined function as when calling a standard CA-Clipper function:

idFunction([argument list])

You can call a user-defined function within an expression or on a line by itself. If called on a line by itself, the return value is ignored.

You can also call a user-defined function as an aliased expression by prefacing it with an alias and enclosing it in parentheses:

idAlias->(idFunction(argument list))

When you call a user-defined function as an aliased expression, the work area associated with idAlias is selected, the expression is executed, and the original work area is then reselected. You can specify an aliased expression on a line by itself, as you would any other expression.

A user-defined function in CA-Clipper may call itself recursively. This means you can make a reference to a user-defined function in statements or expressions of the same user-defined function definition.

■ Parameters: User-defined functions, like procedures, can

receive parameters passed from a calling procedure, user-defined function, or DOS command line. A parameter is a place holder for a value or reference. In CA-Clipper, there are two ways to express parameters: you can declare a list of local variable names as a part of the FUNCTION declaration (referred to as formal parameters), or you can specify a list of private variables in a separate PARAMETERS statement. Note that you cannot mix a declaration of formal parameters with a PARAMETERS statement. Attempting this will result in a fatal compiler error.

Functions receive parameters in the order passed. In CA-Clipper, the number of parameters does not have to match the number of arguments passed. You can skip arguments or omit them from the end of the argument list. A parameter not receiving a value or reference is initialized to NIL. You can skip a parameter by passing NIL. If arguments are specified, PCount() returns the position of the last argument passed. (If more arguments are passed than are parameters, they are ignored.)

Parameters specified in a user-defined function can receive arguments passed by value or reference. The default method for expressions and variables is by value. This includes variables that contain references to arrays and objects. All variables except field variables, when prefaced with the pass-by-reference operator (@), are passed by reference. Field variables cannot be passed by reference and are always passed by value.

Examples
■  This example demonstrates a user-defined function that formats
   numeric values as currency:

   ? Currency( 1000 )               // Result: $1,000.00

   FUNCTION Currency( nNumber )
      LOCAL cNumber
      IF nNumber < 0
         cNumber := Transform(-1 * nNumber, ;
               "999,999,999,999.99")
         cNumber := PadL("($" + LTrim(cNumber) + ")", ;
               Len(cNumber))
      ELSE
         cNumber := Transform(nNumber, ;
               "999,999,999,999.99")
         cNumber := PadL("$" + LTrim(cNumber), ;
               Len(cNumber))
      ENDIF
      RETURN cNumber

■  This example demonstrates a user-defined function that takes a
   character string formatted as a comma-separated list and returns an
   array with one element per item:

   aList := ListAsArray("One, Two")
   // Result: {"One", "Two"}

   FUNCTION ListAsArray( cList )
      LOCAL nPos
      // Define an empty array
      LOCAL aList := {}
      //
      DO WHILE (nPos := At(",", cList)) != 0
         // Add a new element
         AAdd(aList, SubStr(cList, 1, nPos - 1))
         cList := SubStr(cList, nPos + 1)
      ENDDO
      AAdd(aList, cList)
      //
      // Return the array
      RETURN aList

■  This example checks for a skipped argument by comparing the
   parameter to NIL:

   FUNCTION MyFunc( param1, param2, param3 )
      IF param2 == NIL
         param2 := "default value"
      ENDIF
      .
      . <statements>
      .
      RETURN NIL

■  This example uses the user-defined function, Currency()
   (defined above), as an aliased expression:

   USE Invoices NEW
   USE Customer NEW
   ? Invoices->(Currency(Amount))
Platforms
Available on MS-DOS
See also

FWrite()Harbour implementation  | 

Write to an open binary file
Syntax
FWrite(<nHandle>, <cBuffer>, [<nBytes>])
   → nBytesWritten
Arguments
nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.
cBuffer is the character string to write to the specified file.
nBytes indicates the number of bytes to write beginning at the current file pointer position. If omitted, the entire content of cBuffer is written.
Returns
FWrite() returns the number of bytes written as an integer numeric value. If the value returned is equal to nBytes, the operation was successful. If the return value is less than nBytes or zero, either the disk is full or another error has occurred.
Description

FWrite() is a low-level file function that writes data to an open binary file from a character string buffer. You can either write all or a portion of the buffer contents. Writing begins at the current file position, and the function returns the actual number of bytes written.

If FWrite() results in an error condition, FError() can be used to determine the specific error.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system

Examples
■  This example copies the contents of one file to another:

   #incl