__dbStructFilter()

Template

Function

Name

__dbStructFilter()

Category

API

Subcategory

Database

Oneliner

Filter a database structure array

Syntax

      __dbStructFilter( <aStruct>,  [<aFieldList>] ) --> aStructFiltered

Arguments

<aStruct> is a multidimensional array with database fields structure, which is usually the output from dbStruct(), where each array element has the following structure:

       Position   Description    dbstruct.ch
       --------   -----------    -----------
       1          cFieldName     DBS_NAME
       2          cFieldType     DBS_TYPE
       3          nFieldLength   DBS_LEN
       4          nDecimals      DBS_DEC

<aFieldList> is an array where each element is a field name. Names could be specified as uppercase or lowercase.

Returns

__dbStructFilter() return a new multidimensional array where each element is in the same structure as the original <aStruct>, but the array is built according to the list of fields in <aFieldList>. If <aFieldList> is empty, __dbStructFilter() return reference to the original <aStruct> array.

Description

__dbStructFilter() can be use to create a sub-set of a database structure, based on a given field list.

Note that field names in <aStruct> MUST be specified in uppercase or else no match would be found.

SET EXACT has no effect on the return value.

Examples

      LOCAL aStruct,  aList,  aRet
      aStruct := { ;
         { "CODE",   "N",   4,  0 },  ;
         { "NAME",   "C",  10,  0 },  ;
         { "PHONE",  "C",  13,  0 },  ;
         { "IQ",     "N",   3,  0 } }
      aList := { "IQ",  "NAME" }
      aRet := __dbStructFilter( aStruct,  aList )
                        // { { "IQ",  "N",  3,  0 },  { "NAME",  "C",  10,  0 } }

      aRet := __dbStructFilter( aStruct,  {} )
      ? aRet == aStruct // .T.

      aList := { "iq",  "NOTEXIST" }
      aRet := __dbStructFilter( aStruct,  aList )
                        // { { "IQ",  "N",  3,  0 } }

      aList := { "NOTEXIST" }
      aRet := __dbStructFilter( aStruct,  aList )   // {}

      // Create a new file that contain part of the original structure
      LOCAL aStruct,  aList,  aRet
      USE TEST
      aStruct := dbStruct()
      aList := { "NAME" }
      dbCreate( "onlyname.dbf",  __dbStructFilter( aStruct,  aList ) )

Compliance

__dbStructFilter() is a Harbour extension. CA-Cl*pper has an internal undocumented function named __FLedit() that does exactly the same thing. The new name gives a better description of what this  function does.

Platforms

All

Files

Header file is dbstruct.ch
Library is rdd

Seealso

dbCreate(), dbStruct(), __dbCopyStruct(), __FLedit()*

__dbCreate()

Template

Function

Name

__dbCreate()

Category

API

Subcategory

Database

Oneliner

Create structure extended file or use one to create new file

Syntax

      __dbCreate( <cFileName>,  [<cFileFrom>],  [<cRDDName>],  ;
                  [<lNew>],  [<cAlias>] ) --> lUsed

Arguments

<cFileName> is the target file name to create and then open. (.dbf) is the default extension if none is given.

<cFileFrom> is an optional structure extended file name from which the target file <cFileName> is going to be built. If omitted, a new empty structure extended file with the name <cFileName> is created and opened in the current work-area.

<cRDDName> is RDD name to create target with. If omitted, the default RDD is used.

<lNew> is an optional logical expression, (.T.) opens the target file name <cFileName> in the next available unused work-area and makes it the current work-area. (.F.) opens the target file in the current
work-area. Default value is (.F.). The value of <lNew> is ignored if <cFileFrom> is not specified.

<cAlias> is an optional alias to USE the target file with. If not specified, alias is based on the root name of <cFileName>.

Returns

__dbCreate() returns (.T.) if there is database USED in the current work-area (this might be the newly selected work-area), or (.F.) if there is no database USED. Note that on success a (.T.) would be returned, but on failure you probably end up with a run-time error and not a (.F.) value.

Description

__dbCreate() works in two modes depending on the value of <cFileFrom>:

1) If <cFileFrom> is empty or not specified a new empty structure extended file with the name <cFileName> is created and then opened in the current work-area (<lNew> is ignored). The new
file has the following structure:

       Field name   Type   Length   Decimals
       ----------   ----   ------   --------
       FIELD_NAME   C      10        0
       FIELD_TYPE   C       1        0
       FIELD_LEN    N       3        0
       FIELD_DEC    N       3        0

The CREATE command is preprocessed into the __dbCopyStruct() function during compile time and uses this mode.

2) If <cFileFrom> is specified, it is opened and assumed to be a structure extended file where each record contains at least the following fields (in no particular order): FIELD_NAME, FIELD_TYPE,
FIELD_LEN and FIELD_DEC. Any other field is ignored. From this information the file <cFileName> is then created and opened in the current or new work-area (according to <lNew>), if this is a new work-area it becomes the current.

For prehistoric compatibility reasons, structure extended file Character fields which are longer than 255 characters should be treated in a special way by writing part of the length in the FIELD_DEC according to the following formula:

      FIELD->FIELD_DEC := Int( nLength / 256 )
      FIELD->FIELD_LEN := ( nLength % 256 )

CREATE FROM command is preprocessed into __dbCopyStruct() function during compile time and use this mode.

Examples

      // CREATE a new structure extended file,  append some records and
      // then CREATE FROM this file a new database file

      __dbCreate( "template" )
      dbAppend()
      FIELD->FIELD_NAME := "CHANNEL"
      FIELD->FIELD_TYPE := "N"
      FIELD->FIELD_LEN  := 2
      FIELD->FIELD_DEC  := 0
      dbAppend()
      FIELD->FIELD_NAME := "PROGRAM"
      FIELD->FIELD_TYPE := "C"
      FIELD->FIELD_LEN  := 20
      FIELD->FIELD_DEC  := 0
      dbAppend()
      FIELD->FIELD_NAME := "REVIEW"
      FIELD->FIELD_TYPE := "C"      // this field is 1000 char long
      FIELD->FIELD_LEN  := 232      // 1000 % 256 = 232
      FIELD->FIELD_DEC  := 3        // 1000 / 256 = 3
      dbCloseArea()
      __dbCreate( "TV_Guide",  "template" )

Compliance

Clipper

Platforms

All

Files

Library is rdd

Seealso

COPY STRUCTURE, COPY STRUCTURE EXTENDED, CREATE, CREATE FROM, dbCreate(), dbStruct(), __dbCopyStruct(), __dbCopyXStruct()

__dbCopyXStruct()

Template

Function

Name

__dbCopyXStruct()

Category

API

Subcategory

Database

Oneliner

Copy current database structure into a definition file

Syntax

      __dbCopyXStruct( <cFileName> ) --> lSuccess

Arguments

<cFileName> is the name of target definition file to create. (.dbf) is the default extension if none is given.

Returns

__dbCopyXStruct() returns .F. if no database is USED in the current work-area, .T. on success, or a run-time error if the file create operation had failed.

Description

__dbCopyXStruct() create a new database named <cFileName> with a pre-defined structure (also called “structure extended file”):

       Field name   Type   Length   Decimals
       ----------   ----   ------   --------
       FIELD_NAME     C      10        0
       FIELD_TYPE     C       1        0
       FIELD_LEN      N       3        0
       FIELD_DEC      N       3        0

Each record in the new file contains information about one field in the original file. CREATE FROM could be used to create a database from the structure extended file.

For prehistoric compatibility reasons, Character fields which are longer than 255 characters are treated in a special way by writing part of the length in the FIELD_DEC according to the following formula (this is done internally):

      FIELD->FIELD_DEC := Int( nLength / 256 )
      FIELD->FIELD_LEN := ( nLength % 256 )

Later if you want to calculate the length of a field you can use the following formula:

      nLength := iif( FIELD->FIELD_TYPE == "C",  ;
                      FIELD->FIELD_DEC * 256 + FIELD->FIELD_LEN,  ;
                      FIELD->FIELD_LEN )

COPY STRUCTURE EXTENDED command is preprocessed into __dbCopyXStruct() function during compile time.

Examples

      // Open a database,  then copy its structure to a new file, 
      // Open the new file and list all its records
      USE Test
      __dbCopyXStruct( "TestStru" )
      USE TestStru
      LIST

Compliance

Clipper

Platforms

All

Files

Library is rdd

Seealso

COPY STRUCTURE, COPY STRUCTURE EXTENDED, CREATE, CREATE FROM, dbCreate(), dbStruct(), __dbCopyStruct(), __dbCreate()

__dbCopyStruct()

Template

Procedure

Name

__dbCopyStruct()

Category

API

Subcategory

Database

Oneliner

Create a new database based on current database structure

Syntax

      __dbCopyStruct( <cFileName>,  [<aFieldList>] )

Arguments

<cFileName> is the name of the new database file to create. (.dbf) is the default extension if none is given.

<aFieldList> is an array where each element is a field name. Names could be specified as uppercase or lowercase.

Description

__dbCopyStruct() create a new empty database file with a structure that is based on the currently open database in this work-area. If <aFieldList> is empty, the newly created file would have the same structure as the currently open database. Else, the new file would contain only fields that exactly match <aFieldList>.

__dbCopyStruct() can be use to create a sub-set of the currently open database, based on a given field list.

COPY STRUCTURE command is preprocessed into __dbCopyStruct() function during compile time.

Examples

      // Create a new file that contain the same structure
      USE TEST
      __dbCopyStruct( "mycopy.dbf" )

      // Create a new file that contain part of the original structure
      LOCAL aList
      USE TEST
      aList := { "NAME" }
      __dbCopyStruct( "onlyname.dbf",  aList )

Compliance

Clipper

Platforms

All

Files

Library is rdd

Seealso

COPY STRUCTURE, COPY STRUCTURE EXTENDED, dbCreate(), dbStruct(), __dbCopyXStruct(), __dbCreate(), __dbStructFilter()

AFill()

 

AFILL()

Fill an array with a specified value

Syntax

      AFILL( <aArray>, <xValue>, [<nStart>], [<nCount>] ) --> aTarget

Arguments

<aArray> Name of array to be filled.

<xValue> Expression to be globally filled in <aArray>

<nStart> Subscript starting position

<nCount> Number of subscript to be filled

Returns

<aTarget> an array pointer.

Description

This function will fill each element of an array named <aArray> with the value <xValue>. If specified, <nStart> denotes the beginning element to be filled and the array elements will continue to be filled for <nCount> positions. If Not specified, the value of <nStart> will be 1, and the value of <nCount> will be the value of LEN(<aArray>); thus, all subscript positions in the array <aArray> will be filled with the value of <xValue>.

This function will work on only a single dimension of <aArray>. If there are array pointer references within a subscript <aArray>, those values will be lost, since this function will overwrite those values with new values.

Examples

      LOCAL aTest := { NIL, 0, 1, 2 }
      AFill( aTest, 5 )

Compliance

Clipper

Files

Library is vm

Seealso

AADD(), AEVAL(), DBSTRUCT(), DIRECTORY()

SP_BROWSE2D

BROWSE2D()

  Short:
  ------
  BROWSE2D() Popup  tbrowse of 2 dimension array (array of arrays)

  Returns:
  --------
  <nSelection> => selected item, 0 if none

  Syntax:
  -------
  BROWSE2D(nTop,nLeft,nBottom,nRight,aArr,[aHead],[cColor],;
        [cTitle],[bExcept])

  Description:
  ------------
  Pops up a box at <nTop,nLeft,nBottom,nRight> and
  tbrowses array contained in <aArr>.

  <aArr> must be a 2 dimensioned array, like the ones
  returned from DIRECTORY() or DBSTRUCT().

  i.e. { array(n),array(n),array(n) } where <n> is the
  same length for each subarray.

  [aHead] an array of column headers matching the
  number of elements in a single subarray of <aArr>. Default is
  none.

  [cColor] popup box color. Default is sls_popcol()

  [cTitle] title string for the box. Default is none.

  [bExcept] is a codeblock that will be evaluated for
  any exception keys - any keys other than up/ down/ right/ left/
  pgup/ pgdn/ home/ end/ enter/ esc. [bExcept] will be passed the
  parameters: key value, tbrowse object, element

  Examples:
  ---------

   proc test

   local a := directory()
   browse2d(5,5,20,40,a, ;
           {"File","Size","Date","Time","Attribute"},,"Choose a File")

   use customer
   a := dbstruct()
   browse2d(5,5,20,40,a,nil,nil,nil,;
    {|k|msg(str(k)+" is not a valid key")})
   // note the exception block

  Source:
  -------
  S_2DBRZ.PRG

 

SP_AMSUM

AMSUM()

  Short:
  ------
  AMSUM() Sum on a given element of multi-dim array

  Returns:
  --------
  <nSum> => sum of array element

  Syntax:
  -------
  AMSUM(aMult,nElem,[bCondition])

  Description:
  ------------
  Returns sum of array <aMult> element <nElem>.

  [bCondition] is an optional codeblock used to select
  a subset of the  array. This could be used to filter out 0's or
  non-numeric elements.  The block must accept a subarray as a
  parameter, and return  true or false <expL> to determine if this
  element is part of the desired subset. Please note that the
  codeblock accepts the whole subarray, not  just subarray element
  <nElem>

  Examples:
  ---------

   ?"Total file size here is "
   ??AMSUM(DIRECTORY(),2)

   ?"Total .EXE file size here is "
   ??AMSUM(DIRECTORY(),2,{|e|".EXE"$e[1]}  )

   use customer
   ?"Total field size "
   ??AMSUM(DBSTRUCT(),3)

   use customer
   ?"Total CHARACTER field size "
   ??AMSUM(DBSTRUCT(),3,{|e|e[2]=="C"} )

  Notes:
  -------
  Coded by Matthew Maier.

  Presumes all sub-arrays are of equal length

  Source:
  -------
  S_AMSTAT.PRG

 

SP_AASKIP

AASKIP()

  Short:
  ------
  AASKIP() Use for skipblock for arrays in Tbrowse

  Returns:
  --------
  <nSkipcount> => number skipped, forward or backward

  Syntax:
  -------
  AASKIP(nSkip,@nElement,nMaxRows)

  Description:
  ------------
  Use this to create the SKIPBLOCK for a tbrowse that browses
  an array, as in :

    aTbrowseObject:SKIPBLOCK := {|n|aaskip(n,@nElement,len(aArray)}

  <nSkip>      is passed in by Tbrowse as a +- value, or
               as zero.

  <nElement>   is the current array element number.
               PASSED IN BY REFERENCE!

  <nMaxrows>   refers to the length of the array being
               browsed

  Examples:
  ---------
  // this example browses the fields in a database

   local nLastKey,  nElement    := 1
   local aArray := dbstruct()
   local oTb        := tBrowseNew(2,2,20,78)
   oTb:addcolumn(tbcolumnew("Name",{||aArray[nElement,1]}))
   oTb:addcolumn(tbcolumnew("Type", {||aArray[nElement,2]}))
   oTb:addcolumn(tbcolumnew("Len " , {||aArray[nElement,3]}))
   oTb:addcolumn(tbcolumnew("Deci",  {||aArray[nElement,4]}))
   oTb:Skipblock        := {|n|aaskip(n,@nElement,len(aArray)}
   oTb:goTopBlock       := {||nElement := 1}
   oTb:goBottomBlock    := {||nElement := len(aArray)}

   while .t.
     while !oTb:stabilize()
     end
     nLastKey := inkey(0)
     do case
        /// various actions.....
     endcase
   end

  Notes:
  -------
  Aaskip() is used by a lot of SuperLib functions, but
  is very useful by itself for creating array tbrowses.

  Source:
  -------
  S_AASKIP.PRG

 

 

C5_DBSTRUCT

 DBSTRUCT()
 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])} )

 Files   Library is CLIPPER.LIB, header file is Dbstruct.ch.

See Also: AFIELDS()* COPY STRU EXTE

 

Uniform Arrays

 

If a multi-dimension array

–          have a fixed number elements in each dimension and

–          each column contains the same type of information for each row in array

called “uniform”.

This structure is similar to a table structure.

Built-in functions DBSTRUCT() and DIRECTORY() produces uniform arrays.

Array produced by DBSTRUCT() will have field count  in size and the structure of an array is:

Field Name  C
Field Type  C
Field Width N
Field Dec   N

And DIRECTORY() function produces an array with elements as file count and with this structure:

File Name        C
File Size        N
File Date        D
File Time        C
File Attributes  C

Building, maintaining and using those arrays is simple as possible.

Let’s look at a sample .prg:

-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
#include "directry.ch"
#include "dbstruct.ch"
PROCEDURE Main()
  SET DATE GERM
  SET CENT ON
 
  ?
  ? "Uniform arrays :" 
  ?
 
  ?
  ? " Directory file list :"
  ?
 
  FileList()
 
  ?
  ? " Table structure list :"
  ?
  IF MakUseTable()
     DispStru() 
  ELSE
     ? "Couldn't USE or Make th table." 
  ENDIF
 
  ?
  @ MAXROW(), 0
  WAIT "EOF UF_Arrays.prg"
 
RETURN // UF_Arrays.Main
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._

PROCEDURE FileList()
  LOCAL aFList := DIRECTORY( "C:\Harbour\*.*" )
  LOCAL a1File
 
  FOR EACH a1File IN aFList 
     ? SPACE( 4 ),;
       PAD( a1File[ F_NAME ], 13 ),; /* File name */ 
       TRAN( a1File[ F_SIZE ], "999,999,999" ),; /* File size */
       a1File[ F_DATE ],; /* File date */
       a1File[ F_TIME ],; /* File time */
       a1File[ F_ATTR ] /* File attribute */
 NEXT
 
RETURN // FileList()
 
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
FUNCTION MakUseTable() 
 
  LOCAL cTablName := "CUSTOMER.DBF"
  LOCAL lRetval, aStru 
 
  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" ) 
 ENDIF 
 
 lRetval := ( ALIAS() == "CUSTOMER" )
 
RETURN lRetval // MakUseTable()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
PROCEDURE DispStru()
   LOCAL nTotal := 1
 
   IF SELECT() > 0
      aStructur := DBSTRUCT()
      ? SPACE( 4 ), "No: Field Name Type Width Dec"
      ? SPACE( 4 ), "--- ---------- ---- ----- ---"
      AEVAL( aStructur, { | aF1, nFNo | ;
             QOUT( SPACE( 4 ),; // Left Marj 
                   PADL( nFNo, 3 ),; // Field No
                   PADR( aF1[ DBS_NAME ], 11 ),; // Field Name
                   PADC( aF1[ DBS_TYPE ], 4 ),; // Field Type
                   PADL( aF1[ DBS_LEN ], 4 ),; // Field Len
                   PADL( aF1[ DBS_DEC ], 3 )),; // Field Dec 
             nTotal += aF1[ 3 ] } )
 
      ? SPACE( 4 ), "--- ---------- ---- ----- ---"
      ? SPACE( 4 ), "** Total ** ", TRAN( nTotal, "9,999" )
   ELSE
      ? "Current work area is empty"
   ENDIF 
 
RETURN // DispStru()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
 
UF_Arrays