SKIP

SKIP

Move the record pointer to a new position

Syntax

      SKIP [<nRecords>] [ALIAS <idAlias> | <nWorkArea>]

Arguments

<nRecords> is a numeric expression specifying the number of records to move the record pointer from the current position. A positive value moves the record pointer forward and a negative value moves the record pointer backward.

ALIAS <idAlias>|<nWorkArea> specifies the alias name as a literal identifier or the work area as a numeric expression.

SKIP specified with no arguments moves the record pointer forward one record.

Description

SKIP moves the record pointer to a new position relative to the current position in the current work area and within the current filter, if there is one. SKIP is generally used for operations, such as reporting, that need to go to the next record in a database file.

If the alias clause is specified, the pointer can be moved in another work area without SELECTing that work area. SKIP can move either forward or backward. If there is no active index, SKIP moves the record pointer relative to the current position in the target database file. If there is an active index, SKIP moves the pointer relative to the current position in the index instead of the database file.

Attempting to SKIP forward beyond the end of file positions the record pointer at LASTREC() + 1, and EOF() returns true (.T.). Attempting to SKIP backward beyond the beginning of file moves the pointer to the first record, and BOF() returns true (.T.).

In a network environment, any record movement command, including SKIP, makes changes to the current work area visible to other applications if the current file is shared and the changes were made during an RLOCK(). To force an update to become visible without changing the current record position, use SKIP 0. If, however, the changes were made during an FLOCK(), visibility is not guaranteed until the lock is released, a COMMIT is performed, or the file is closed. Refer to the “Network Programming” chapter for more information.

Examples

      .  This example uses SKIP with various arguments and shows their
         results:

      USE Customers NEW
      SKIP
      ? RECNO()                  // Result: 2
      SKIP 10
      ? RECNO()                  // Result: 12
      SKIP -5
      ? RECNO()                  // Result: 7

      .  This example moves the record pointer in a remote work area:

      USE Customers NEW
      USE Invoices NEW
      SKIP ALIAS Customers

      .  This example prints a report using SKIP to move the record
         pointer sequentially through the Customer database file:

      LOCAL nLine := 99
      USE Customers NEW
      SET PRINTER ON
      DO WHILE !EOF()
         IF nLine > 55
            EJECT
            nLine := 1
         ENDIF
            ? Customer, Address, City, State, Zip
            nLine++
            SKIP
         ENDDO
      SET PRINTER OFF
      CLOSE Customers

Seealso

BOF(), COMMIT, DBSKIP(), EOF(), GO, LOCATE, RECNO(), SEEK

SET ORDER

SET ORDER

Select the controlling order

Syntax

      SET ORDER TO [<nOrder> | [TAG <cOrderName>]
            [IN <xcOrderBagName>]]

Arguments

TAG is an optional clause that provides compatibility with RDDs that access multiple-order order bags. You must use this keyword anytime you specify <cOrderName>.

<cOrderName> is the name of an order, a logical arrangement of a database according to a keyed pair. This order will become the controlling order in the order list. If you specify <cOrderName>, you must use the keyword TAG.

Note: This differs from dBASE and FoxPro where TAG is totally optional.

<nOrder> is the number of the target order in the order list. You may represent the order as an integer or as a character string enclosed in quotes.

IN <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>, Harbour uses the default extension of the current RDD.

Description

When you SET ORDER TO a new controlling order (index), all orders are properly updated when you either append or edit records. This is true even if you SET ORDER TO 0. After a change of controlling order, the record pointer still points to the same record.

SET ORDER TO 0 restores the database access to natural order, but leaves all orders open. SET ORDER TO with no arguments closes all orders and empties the order list

Though you may use <cOrderName> or <nOrder> to specify the target order, <nOrder> is only provided for compatibility with earlier versions of Harbour. Using <cOrderName> is a surer way of accessing the correct order in the order list.

If you supply <xcOrderBagName>, only the orders belonging to <xcOrderBagName> in the order list are searched. Usually you need not specify <xcOrderBagName> if you use unique order names throughout an application.

To determine which order is the controlling order use the ORDSETFOCUS() function.

In RDDs that support production or structural indices (e.g., DBFCDX), if you specify a tag but do not specify an order bag, the tag is created and added to the index. If no production or structural index exists, it will be created and the tag will be added to it. When using RDDs that support multiple order bags, you must explicitly SET ORDER (or ORDSETFOCUS()) to the desired controlling order. If you do not specify a controlling order, the data file will be viewed in natural order.

SET ORDER can open orders in a network environment instead of the INDEX clause of the USE command. Generally, specify USE, and then test to determine whether the USE succeeded. If it did succeed, open the associated orders with SET ORDER. See the example below.

Examples

      USE Customer NEW
      IF (! NETERR())
         SET ORDER TO Customer
      ENDIF

      SET ORDER TO "CuAcct"         // CuAcct is an Order in Customer

Seealso

INDEX, INDEXORD(), SEEK, SET INDEX, USE

SET EXACT

SET EXACT*

Toggle exact matches for character strings

Syntax

      SET EXACT on | OFF | <xlToggle>

Arguments

ON enforces exact comparison of character strings including length.

OFF resumes normal character string comparison.

<xlToggle> is a logical expression that must be enclosed in parentheses. A value of true (.T.) is the same as ON, and a value of false (.F.) is the same as OFF.

Description

SET EXACT determines how two character strings are compared using the relational operators (=, >, <, =>, =<). When EXACT is OFF, 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 a null string (“”), return true (.T.).

. If LEN(cRight) is greater than LEN(cLeft), return false (.F.).

. Otherwise, compare all characters in cRight with cLeft. If all characters in cRight equal cLeft, return true (.T.); otherwise, return false (.F.).

With EXACT ON, all relational operators except the double equal operator (==) treat two strings as equal, if they match exactly, excluding trailing spaces. With the double equal operator (==), all characters in the string are significant, including trailing spaces.

SET EXACT is a compatibility command and not recommended.

Notes

. Compatibility: In Harbour, unlike other dialects, SET EXACT has no affect on operations other than relational operators. This includes the SEEK and FIND commands. If you need to seek exact matches of character keys, use the example user-defined function SeekExact() in the SEEK command reference.

Examples

      .  These examples show various results of the equal operator (=)
         with SET EXACT:

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

Seealso

SEEK, Operators

SET UNIQUE

SET UNIQUE*

Toggle inclusion of non-unique keys into an index

Syntax

      SET UNIQUE on | OFF | <xlToggle>

Arguments

ON causes index files to be created with a uniqueness attribute.

OFF causes index files to be created without a uniqueness attribute.

<xlToggle> is a logical expression that must be enclosed in parentheses. A value of true (.T.) is the same as ON, and a value of false (.F.) is the same as OFF.

Description

SET UNIQUE is a database command that controls whether indexes are created with uniqueness as an attribute. With UNIQUE ON, new indexes are created including only unique keys. This is the same as creating an index with the INDEX…UNIQUE command.

If, during the creation or update of an unique index, two or more records are encountered with the same key value, only the first record is included in the index. When the unique index is updated, REINDEXed, or PACKed, only unique records are maintained, without regard to the current SET UNIQUE value.

Changing key values in a unique index has important implications. First, if a unique key is changed to the value of a key already in the index, the changed record is lost from the index. Second, if there is more than one instance of a key value in a database file, changing the visible key value does not bring forward another record with the same key until the index is rebuilt with REINDEX, PACK, or INDEX…UNIQUE.

With UNIQUE OFF, indexes are created with all records in the index. Subsequent updates to the database files add all key values to the index independent of the current UNIQUE SETting.

SET UNIQUE is a compatibility command not recommended. It is superseded by the UNIQUE clause of the INDEX command.

Seealso

DBCREATEIND(), INDEX, PACK, REINDEX, SEEK

SET SOFTSEEK

SET SOFTSEEK

Toggle relative seeking

Syntax

      SET SOFTSEEK on | OFF | <xlToggle>

Arguments

ON causes the record pointer to be moved to the next record with a higher key after a failed index search.

OFF causes the record pointer to be moved to EOF() after a failed index search.

<xlToggle> is a logical expression that must be enclosed in parentheses. A value of true (.T.) is the same as ON, and a value of false (.F.) is the same as OFF.

Description

SET SOFTSEEK enables relative seeking, a method of searching an index and returning a record even if there is no match for a specified key.

When SOFTSEEK is ON and a match for a SEEK is not found, the record pointer is set to the next record in the index with a higher key value than the SEEK argument. Records are not visible because SET FILTER and/or SET DELETED are skipped when searching for the next higher key value. If there is no record with a higher key value, the record pointer is positioned at LASTREC() + 1, EOF() returns true (.T.), and FOUND() returns false (.F.). FOUND() returns true (.T.) only if the record is actually found. It never returns true (.T.) for a relative find.

When SOFTSEEK is OFF and a SEEK is unsuccessful, the record pointer is positioned at LASTREC() + 1, EOF() returns true (.T.), and FOUND() returns false (.F.).

Notes

. SET RELATION: SET RELATION ignores SOFTSEEK updating the record pointer in all linked child work areas as if SOFTSEEK is OFF.

Examples

      .  This example illustrates the possible results of a SEEK with
         SET SOFTSEEK ON:

      SET SOFTSEEK ON
      USE Salesman INDEX Salesman NEW
      ACCEPT "Enter Salesman: " TO cSearch
      SEEK cSearch
      DO CASE
      CASE FIELD->Salesman = cSearch
         ? "Match found:", FOUND(), EOF(), FIELD->Salesman
      CASE !EOF()
         ? "Soft match found:", FOUND(), EOF(), ;
                  FIELD->Salesman
      OTHERWISE
         ? "No key matches:", FOUND(), EOF(), FIELD->Salesman
      ENDCASE

Seealso

FOUND(), SEEK, SET INDEX, SET ORDER, SET RELATION

LOCATE

LOCATE

Search sequentially for a record matching a condition

Syntax

      LOCATE [<scope>] FOR <lCondition>
             [WHILE <lCondition>]

Arguments

<scope> is the portion of the current database file in which to perform the LOCATE. The default scope is ALL records.

FOR <lCondition> specifies the next record to LOCATE within the given scope.

WHILE <lCondition> specifies the set of records meeting the condition from the current record until the condition fails.

Description

LOCATE is a database command that searches for the first record in the current work area that matches the specified conditions and scope. When you first execute a LOCATE, it searches from the beginning record of the scope for the first matching record in the current work area. It terminates when a match is found or the end of the LOCATE scope is reached. If it is successful, the matching record becomes the current record and FOUND() returns true (.T.). If it is unsuccessful, FOUND() returns false (.F.) and the positioning of the record pointer depends on the controlling scope of the LOCATE.

Each work area can have its own LOCATE condition. The condition remains active until you execute another LOCATE command in that work area or the application terminates.

LOCATE works with CONTINUE. Once a LOCATE has been issued, you can resume the search from the current record pointer position with CONTINUE. There are, however, some exceptions. See note below.

Notes

. CONTINUE: Both the <scope> and the WHILE condition apply only to the initial LOCATE and are not operational for any subsequent CONTINUE commands. To continue a pending LOCATE with a scope or WHILE condition, use SKIP then LOCATE REST WHILE <lCondition> instead of CONTINUE.

Examples

      .  These examples show typical LOCATEs:
      USE Sales INDEX Salesman
      LOCATE FOR Branch = "200"
      ? FOUND(), EOF(), RECNO()         // Result: .T. .F. 5
      LOCATE FOR Branch = "5000"
      ? FOUND(), EOF(), RECNO()         // Result: .F. .T. 85
      .  This example shows a LOCATE with a WHILE condition that is
         continued by using LOCATE REST:
      SEEK "Bill"
      LOCATE FOR Branch = "200" WHILE Salesman = "Bill"
      DO WHILE FOUND()
         ? Branch, Salesman
         SKIP
         LOCATE REST FOR Branch = "200" WHILE ;
                  Salesman = "Bill"
      ENDDO

Seealso

CONTINUE, EOF(), FOUND(), SEEK, SET FILTER

FIND

FIND*

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

Seealso

EOF(), FOUND(), RECNO(), SEEK, SET INDEX, SET ORDER