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

Harbour All Functions – D

Date()
Day()
Days()

DaysInMonth()
DaysToMonth()

dbAppend()
dbClearFilter()
dbCloseAll()
dbCloseArea()
dbCommit()
dbCommitAll()
dbCreate()
dbDelete()
dbEval()
dbF()
dbFilter()
dbGoBottom()
dbGoTo()
dbGoTop()
dbReCall()
dbRLock()
dbRLockList()
dbRUnlock()
dbSeek()
dbSelectArea()
dbSetDriver()
dbSetFilter()
dbSkip()
dbSkipper()
dbStruct()
dbUnlock()
dbUnlockAll()
dbUseArea()

DecToBin()
DecToHexa()
DecToOctal()

Deleted()
Descend()
DevOutPict()
DirChange()
DirRemove()
DiskSpace()

DMY()
Do()
DoW()

DOY
DToC()

DToR
DToS()

Harbour Database Functions

Database Functions

AFields Fills referenced arrays with database field information
Alias Returns the alias name of a work area
BOF Test for the beggining-of-file condition
dbAppend Appends a new record to a database file
dbClearFilter Clears the current filter condiction in a work area
dbCloseAll Close all open files in all work areas.
dbCloseArea Close a database file in a work area
dbCommit Updates all index and database buffers for a given workarea
dbCommitAll Flushes the memory buffer and performs a hard-disk write
dbCreate Creates an empty database from a array
dbDelete Mark a record for deletion in a database
dbEval Performs a code block operation on the current Database
DBF Alias name of a work area
dbFilter Return the filter expression in a work area
dbGoBottom Moves the record pointer to the bottom of the database
dbGoto Position the record pointer to a specific location
dbGoTop Moves the record pointer to the top of the database
dbRecall Recalls a record previousy marked for deletion
dbSeek Searches for a value based on an active index
dbSelectArea Change to another work area
dbSetDriver Establishes the RDD name for the selected work area
dbSetFilter Establishes a filter condition for a work area
dbSkip Moves the record pointer in the selected work area
dbSkipper Helper function to skip a database
dbStruct Builds a multidimensional array of a database structure
dbUseArea Opens a work area and uses a database file
Deleted Tests the record’s deletion flag
EOF Test for end-of-file condition
FCount Counts the number of fields in an active database
FieldDeci Determines the number of decimal places of a given numeric field
FieldGet Obtains the value of a specified field
FieldName Return the name of a field at a numeric field location
FieldPos Return the ordinal position of a field
FieldPut Set the value of a field variable
FieldSize Determines the size of a given field
FieldType Determines the type of a given field
Found Determine the success of a previous search operation
Header Return the length of a database file header
LastRec Returns the number of records in an active work area or database
LUpdate Yields the date the database was last updated
RecCount Counts the number of records in a database
RecNo Returns the current record number or identity
RecSize Returns the size of a single record in an active database
Select Returns the work area number for a specified alias
Used Checks whether a database is in use in a work area

dbSeek()

DBSEEK()

Searches for a value based on an active index.

Syntax

      DBSEEK(<expKey>, [<lSoftSeek>],[<lFindLast>]) --> lFound

Arguments

<expKey> Any expression

<lSoftSeek> Toggle SOFTSEEK condition

<lFindLast> is an optional logical value that set the current record position to the last record if successful

Returns

DBSEEK() returns logical true (.T.) if found, otherwise false

Description

This function searches for the first record in a database file whose index key matches <expKey>. If the item is found, the function will return a logical true (.T.), the value of FOUND() wilI be a logical true (.T.), and the value of EOF() wilI be a logical false (.F.). If no item is found. then the function will return a logical false, the value of FOUND( ) will be a logical false (.F.), and the value of EOF( ) will be a logical true (.T.).

This function always “rewinds” the database pointer and starts the search from the top of the file.

If the SOFTSEEK flag is on or if <lSoftSeek> is set to a logical true (.T.) the value of FOUND() will be a logical false and EOF() will be false if there is an item in the index key with a greater value than the key expression <expKey>; at this point the record pointer will position itself on that record. However, if there is no greater key in the index, EOF() will return a logical true (.T.) value. If <lSoftSeek> is not passed, the function will look to the internal status of SOFTSEEK before performing the operation. The default of <lSoftSeek> is a logical false (.F.)

Examples

      PROCEDURE Main()
         USE tests NEW INDEX tests
         DBGOTO( 10 )
         nId := tests->nId
         IF tests->( DBSEEK( nId ) )
            IF RLOCK()
               ? tests->Name
               DBRUNLOCK()
            ENDIF
         ENDIF
         USE
         RETURN

      ACCEPT "Employee name: " TO cName
      IF Employee->( DBSEEK( cName ) )
         Employee->( ViewRecord() )
      ELSE
         ? "Not found"
      ENDIF

Compliance

DBSEEK() is Compatible with CA-Cl*pper 5.3

Files

Library is rdd

Seealso

DBGOBOTTOM(), DBGOTOP(), DBSKIP(), EOF(), BOF(), FOUND()

dbGoTop()

DBGOTOP()

Moves the record pointer to the top of the database.

Syntax

      DBGOTOP()

Description

This function moves the record pointer in the selected or aliased work area to the top of the file. The position of the record pointer is affected by the values in the index key or by an active FILTER condition. Otherwise, if no index is active or if no filter condition is present, the value of RECNO() will be 1.

Examples

      USE tests
      DBGOTOP()
      ? RECNO()
      DBGOBOTTOM()
      ? RECNO()
      USE

Compliance

Clipper

Files

Library is rdd

Seealso

BOF(), EOF(), DBSKIP(), DBSEEK(), DBGOBOTTOM()

dbGoto()

DBGOTO()

Position the record pointer to a specific location.

Syntax

      DBGOTO(<xRecordNumber>)

Arguments

<xRecordNumber> Record number or unique identity

Description

This function places the record pointer, if working with a .dbf file, in selected or aliased work area at the record number specified by <xRecordNumber>. The position is not affected by an active index or by any enviromental SET condiction.

The parameter <xRecordNumber> may be something other than a record number. In some data formats, for example, the value of <xRecordNumber> is a unique primary key while in other formats, <xRecordNumber> could be an array offset if the data set was an array.

Issuing a DBGOTO(RECNO()) call in a network enviroment will refresh the database and index buffers. This is the same as a DBSKIP(0) call.

Examples

      The following example uses DBGOTO() to iteratively process
      every fourth record:

      DBUSEAREA( .T., "DBFNTX", "sales", "sales", .T. )
      //
      // toggle every fourth record
      DO WHILE ! EOF()
         DBGOTO( RECNO() + 4 )
         sales->Group := "Bear"
      ENDDO

Compliance

Clipper

Files

Library is rdd

Seealso

BOF(), EOF(), DBGOTOP(), DBGOBOTTOM(), DBSEEK(), DBSKIP()

dbGoBottom()

DBGOBOTTOM()

Moves the record pointer to the bottom of the database.

Syntax

      DBGOBOTTOM()

Description

This function moves the record pointer in the selected or aliased work area to the end of the file. The position of the record pointer is affected by the values in the index key or by an active FILTER condition. Otherwise, if no index is active or if no filter condition is present, the value of the record pointer will be LASTREC().

Examples

      USE tests
      DBGOTOP()
      ? RECNO()
      DBGOBOTTOM()
      ? RECNO()
      USE

Compliance

Clipper

Files

Library is rdd

Seealso

BOF(), EOF(), DBSKIP(), DBSEEK(), DBGOTOP()

dbSkipper()

dbSkipper()

Helper function to skip a database

Syntax

      dbSkipper( <nRecs> ) --> nSkipped

Arguments

<nRecs> is the number of records to skip relative to current record. Positive number would try to move the record pointer forward, while a negative number would try to move the record pointer back <nRecs> records.

Returns

dbSkipper() return the number of actual record skipped.

Description

dbSkipper() is a helper function used in browse mechanism to skip a number of records while giving the caller indication about the actual records skipped.

Examples

      // open a file and find if we've got enough records in it
      USE MonthSales
      IF dbSkipper( 100 ) == 100
         ? "Good work! You can party now"
      ELSE
         ? "Too bad, you should really work harder"
      ENDIF
      CLOSE

Compliance

XPP

Files

Library is rtl

Seealso

DBSKIP(), SKIP

C5_DBSKIP

 DBSKIP()
 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

 Files   Library is CLIPPER.LIB.

See Also: BOF() DBGOBOTTOM() DBGOTOP() DBSEEK() EOF() SKIP



Hash vs Table

Consider a table for customers records with two character fields : Customer ID and customer name:

Cust_ID Cust_Name
CC001 Pierce Firth
CC002 Stellan Taylor
CC003 Chris Cherry
CC004 Amanda Baranski

 It’s known all possible and necessary operations on a table: APPEND, DELETE, SEEK and so on; by the way, for SEEK we need an index file also.

Listing this table is quite simple:

USE CUSTOMER
WHILE .NOT. EOF()
   ? CUST_ID, CUST_NAME
   DBSKIP()
ENDDO

 If our table is sufficiently small, we can find a customer record without index and SEEK :

LOCATE FOR CUST_ID = “CC003”
? CUST_ID, CUST_NAME

If we want all our data will stand in memory and we could manage it more simple and quick way, we would use an array ( with some considerations about size of table; if it is too big, this method will be problematic ) :

aCustomer := {}    // Declare / define an empty array
USE CUSTOMER
WHILE .NOT. EOF()
   AADD(aCustomer, { CUST_ID, CUST_NAME } )
   DBSKIP()
ENDDO
Traversing this array is quite simple :

FOR nRecord := 1 TO LEN( aCustomer )

    ? aCustomer[ nRecord, 1 ], aCustomer[ nRecord, 2 ]
NEXT
or :

a1Record := {}

FOR EACH a1Record IN aCustomer
   ? a1Record[ 1 ], a1Record[ 2 ]
NEXT

And locating a specific record too:

nRecord := ASCAN( aCustomer, { | a1Record | a1Record[ 1 ] == “CC003” } )

? aCustomer[ nRecord, 1 ], aCustomer[ nRecord, 2 ]

A lot of array functions are ready to use for maintain this array : ADEL(), AADD(), AINS() etc …

Now, let’s see how we could use a hash for achieve this job :

hCustomer := { => } // Declare / define an empty hash

USE CUSTOMER
WHILE .NOT. EOF()
   hCustomer[ CUST_ID ] := CUST_NAME
   DBSKIP()
ENDDO
Let’s traversing :

h1Record := NIL

FOR EACH h1Record IN hCustomer
   ? h1Record: __ENUMKEY(),h1Record:__ENUMVALUE()
NEXT

Now, we have a bit complicate our job; a few field addition to the table :

No: Field Name Type Width  Dec Decription

1

 CUST_ID

C

 5

0

Id ( Code )

2

 CUST_NAME

C

10

0

Name

3

 CUST_SNAM

C

10

0

Surname

4

 CUST_FDAT

D

 8

0

First date

5

 CUST_ACTV

L

 1

0

Is active ?

6

 CUST_BLNCE

N

11

2

Balance

 While <key> part of an element of a hash may be C / D / N / L type; <xValue> part of hash too may be ANY type of data, exactly same as arrays.

So, we can make fields values other than first ( ID) elements of an array:

hCustomer := { => } // Declare / define an empty hash
USE CUSTOMER
WHILE .NOT. EOF()
   a1Data:= { CUST_NAME, CUST_SNAM, CUST_FDAT, CUST_ACTV, CUST_BLNCE }
   hCustomer[ CUST_ID ] := a1Data
   DBSKIP()
ENDDO
Let’s traversing :

h1Record := NIL

FOR EACH h1Record IN hCustomer
   a1Key  := h1Record:__ENUMKEY()
   a1Data := h1Record:__ENUMVALUE()
   ? a1Key
   AEVAL( a1Data, { | x1 | QQOUT( x1 ) } )
NEXT
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
/*
Hash vs Tables
 
*/
#define NTrim( n ) LTRIM( STR( n ) )
#define cLMarj SPACE( 3 )
PROCEDURE Main()

  SET DATE GERM
  SET CENT ON
  SET COLO TO "W/B"
  SetMode( 40, 120 )
 
  CLS
 
  hCustomers := { => } // Declare / define an empty PRIVATE hash
 
  IF MakUseTable() 
 
     Table2Hash()
 
     * Here the hash hCustomers may be altered in any way
 
     ZAP
 
     Hash2Table()
 
  ELSE
      ? "Couldn't make / USE table"
  ENDIF
 
  ?
  @ MAXROW(), 0
  WAIT "EOF HashVsTable.prg"
 
RETURN // HashVsTable.Main()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROCEDURE Table2Hash()
   hCustomers := { => } 
   WHILE .NOT. EOF()
     hCustomers[ CUST_ID ] := CUST_SNAM
     DBSKIP()
   ENDDO
 
   ListHash( hCustomers, "A hash transferred from a table (single value)" )
 
   hCustomers := { => } // Declare / define an empty hash
   DBGOTOP()
   WHILE .NOT. EOF()
      hCustomers[ CUST_ID ] := { CUST_NAME, CUST_SNAM, CUST_FDAT, CUST_ACTV, CUST_BLNCE }
      DBSKIP()
   ENDDO
 
   ListHash( hCustomers, "A hash transferred from a table (multiple values)" )
 
RETURN // Table2Hash()

*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.

PROCEDURE Hash2Table()
   LOCAL h1Record,;
         c1Key,;
         a1Record,;
         n1Field
 
   FOR EACH h1Record IN hCustomers
      c1Key := h1Record:__ENUMKEY()
      a1Record := h1Record:__ENUMVALUE()
      DBAPPEND()
      FIELDPUT( 1, c1Key )
      AEVAL( a1Record, { | x1, n1 | FIELDPUT( n1 + 1 , x1 ) } )
   NEXT h1Record
   DBGOTOP()
 
   ?
   ? "Data trasferred from hash to table :"
   ?
   WHILE ! EOF()
      ? STR( RECN(), 5), ''
      FOR n1Field := 1 TO FCOUNT()
         ?? FIELDGET( n1Field ), ''
      NEXT n1Field
      DBSKIP()
   ENDDO 
 
RETURN // Hash2Table()

*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.

PROCEDURE ListHash( hHash, cComment )
 
  LOCAL x1Pair
 
  cComment := IF( HB_ISNIL( cComment ), '', cComment )
 
  ? 
  ? cComment // , "-- Type :", VALTYPE( hHash ), "size:", LEN( hHash )
  ?
  IF HB_ISHASH( hHash ) 
     FOR EACH x1Pair IN hHash
        nIndex := x1Pair:__ENUMINDEX()
        x1Key := x1Pair:__ENUMKEY()
        x1Value := x1Pair:__ENUMVALUE()
        ? cLMarj, NTrim( nIndex ) 
*       ?? '', VALTYPE( x1Pair )
        ?? '', x1Key, "=>"
*       ?? '', VALTYPE( x1Key ) 
*       ?? VALTYPE( x1Value ) 
        IF HB_ISARRAY( x1Value ) 
           AEVAL( x1Value, { | x1 | QQOUT( '', x1 ) } )
        ELSE 
           ?? '', x1Value
        ENDIF 
     NEXT
  ELSE
    ? "Data type error; Expected hash, came", VALTYPE( hHash ) 
  ENDIF HB_ISHASH( hHash )
RETURN // ListHash()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.

FUNCTION MakUseTable() // Make / USE table
 
 LOCAL cTablName := "CUSTOMER.DBF"
 LOCAL lRetval, aStru, aData, a1Record 
 
 IF FILE( cTablName ) 
    USE (cTablName)
 ELSE
    aStru := { { "CUST_ID", "C", 5, 0 },;
               { "CUST_NAME", "C", 10, 0 },;
               { "CUST_SNAM", "C", 10, 0 },;
               { "CUST_FDAT", "D", 8, 0 },;
               { "CUST_ACTV", "L", 1, 0 },;
               { "CUST_BLNCE", "N", 11, 2 } }
    * 
    * 5-th parameter of DBCREATE() is alias - 
    * if not given then WA is open without alias 
    *                              ^^^^^^^^^^^^^ 
    DBCREATE( cTablName, aStru, , .F., "CUSTOMER" ) 
 
    aData := { { "CC001", "Pierce", "Firth", 0d20120131, .T., 150.00 },; 
               { "CC002", "Stellan", "Taylor", 0d20050505, .T., 0.15 },;
               { "CC003", "Chris", "Cherry", 0d19950302, .F., 0 },;
               { "CC004", "Amanda", "Baranski", 0d20011112, .T., 12345.00 } }
 
    FOR EACH a1Record IN aData
        CUSTOMER->(DBAPPEND())
        AEVAL( a1Record, { | x1, nI1 | FIELDPUT( nI1, X1 ) } )
    NEXT a1Record 
    DBGOTOP()
 
 ENDIF 
 
 lRetval := ( ALIAS() == "CUSTOMER" )
 
RETURN lRetval // MakUseTable()

*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
 
HashVsTable