Contributed works of Danny A. del Pilar
How to build menu like old ACHOICE function?
KPI (Key Performance Indicator) Dashboard
How to build menu like old ACHOICE function?
KPI (Key Performance Indicator) Dashboard
PROGINDEX() Short: ------ PROGINDEX() Perform an index with a progress box Returns: -------- Nil Syntax: ------- PROGINDEX(cName,cKey,[lUnique],[lShowCount],[lPause]) Description: ------------ Pops up a progress bar box with PROGON(). Performs an index using <cName> as the index name, and <cKey> as the index key. [lUnique] for index UNIQUE (default False) [lShowCount] to show an index count as well as the progress bar - default False [lPause] if True will pause before removing the box with PROGOFF()- default is False. Examples: --------- use customer ProgIndex("Eraseme","LNAME",.f.,.t.,.t.) Source: ------- S_PROG.PRG See also : PROGCOUNT(), PROGDISP(), PROGEVAL(), PROGOFF(), PROGON()
NKEY() Short: ------ NKEY() Gets key of an index file Returns: -------- <cKey> => index key expression Syntax: ------- NKEY(cIndex) Description: ------------ Gets key expression of index <cIndex>. <cIndex> is the name of the index including extension. The function operates differently from .ntx to .ndx. Examples: --------- for i = 1 to nIndexes ?"Key for index: "+aInd[i]+" is "+NKEY(aInd[i]) next Warnings: ---------- Uses up a file handle temporarily. Opens up the index with low level file functions. Notes: ------- NKEY() expects the full path of the index file and if no path is passed, will use SET DEFAULT setting Source: ------- S_NKEY.PRG
Ext. | File Type | Introduced or used by |
.$$$ | temporary file | dBASE III |
.$db | temporary file | dBASE IV |
.act | FoxDoc Action Diagrams | FoxPro |
.app | application object file | dBASE Appl. Generator |
.app | generated application | FoxPro |
.bak | Backup file | dBASE |
.bar | horizontal bar menu object file | dBASE Appl. Generator |
.bin | Binary files | dBASE |
.bch | batch process object file | dBASE Appl. Generator |
.cac | executable when caching on/off | dBASE IV |
.cat | catalog | dBASE III, IV |
.cdx | compound index | FoxPro |
.ch | header file | Clipper |
.cht | interface file for ChartMaster | dBASE |
.clp | compiler script file (clip list) | Clipper |
.cmd | command | dBASE – Waffle |
.cod | template source file | dBASE Appl. Generator |
.cpt | encrypted memo file | dBASE |
.crp | encrypted database | dBASE IV |
.ctl | control file | dBASE IV – Aldus Setup |
.cvt | backup file for CONVERTed database file | dBASE IV |
.db | configuration | dBASE |
.db$ | temporary file | dBASE |
.db2 | database | dBASE II |
.db3 | database | dBASE III |
.dbf | database file | dBASE – FoxPro |
.dbk | database backup | dBASE IV |
.dbo | compiled program | dBASE IV |
.dbt | FoxBASE+ style memo | FoxPro |
.dbt | memo file for database w/same name | dBASE – Clipper |
.def | Definitions list | dBASE |
.dif | Data Interchange Format. For APPEND FROM, COPY | dBASE – VisiCal |
.doc | Documentation text file | dBASE Appl. Generator |
.fil | files list object file | dBASE Appl. Generator |
.fky | macro file | FoxPro |
.fmo | compiled format file | dBASE IV |
.fmt | format file | dBASE – FoxPro – Clipper |
.fp | configuration file | FoxPro |
.fpc | catalog | FoxPro |
.fpt | memo | FoxPro |
.fr3 | renamed dBASE III+ form file | dBASE IV |
.frg | uncompiled report file, code fragment file | dBASE IV |
.frm | report file | dBASE – Clipper |
.fro | compiled report file | dBASE IV |
.frt | report memo | FoxPro |
.frx | report | FoxPro |
.fw2 | Framework spreadsheet or database file | Framework – dBASE |
.fxp | compiled format | FoxPro |
.gen | compiled template | dBASE Appl. Generator |
.idx | index (many) | FoxPro |
.ind | include index | dBASE IV |
.inx | index | FoxBase |
.key | Key macro library | dBASE |
.lbg | label generator data | dBASE IV |
.lbl | label | dBASE – Clipper |
.lbo | compiled label | dBASE IV |
.lbt | label memo | FoxPro |
.lbx | label | FoxPro |
.ld1 | overlay file | dBASE |
.log | Transaction log file | dBASE |
.mbk | multiple index file backup | dBASE IV |
.mdx | multiple index file | dBASE IV |
.mem | memory variable save file | dBASE – FoxPro |
.mnt | menu memo | FoxPro |
.mnx | menu | FoxPro |
.mpr | generated program | FoxPro |
.mpx | compiled menu program | FoxPro |
.ndx | index file | dBASE |
.npi | source for DGEN.EXE interpreter | dBASE Appl. Generator |
.ntx | index file | Clipper |
.pjt | project memo | FoxPro |
.pjx | project | FoxPro |
.plb | library | FoxPro |
.pll | pre-linked library | Clipper |
.plt | pre-linked transfer file | Clipper |
.pop | pop-up menu object | dBASE Appl. Generator |
.ppo | pre-processor output | Clipper |
.pr2 | printer driver | dBASE IV |
.pr3 | PostScript printer driver | dBASE IV |
.prf | printer driver | dBASE IV |
.prg | program source file | dBASE – FoxPro – Clipper |
.prs | procedure | dBASE IV |
.prt | Print dump | dBASE |
.prx | compiled program | FoxPro |
.qbe | saved query (Query By Example) | dBASE IV – Quattro Pro |
.qbo | compiled query | dBASE IV |
.qpr | generated query program | FoxPro |
.qpx | compiled query program | FoxPro |
.qry | query | dBASE IV |
.res | dBASE resources | dBASE IV |
.rpd | Rapid file. For IMPORT/EXPORT,APPEND FROM, COPY | dBASE |
.sc3 | renamed dBASE III screen mask file | dBASE IV |
.scr | screen – screen snapshot | dBASE IV |
.sct | screen memo | FoxPro |
.scx | screen | FoxPro |
.spr | generated screen program | FoxPro |
.spx | compiled screen program | FoxPro |
.str | structure list object file | dBASE Appl. Generator |
.t44 | Temporary file for Sort or Index | dBASE IV |
.tbk | memo backup | dBASE IV – FoxPro |
.tvf | table view settings | dBASE |
.upd | update data | dBASE |
.upo | compiled update data | dBASE |
.val | values list object file | dBASE Appl. Generator |
.vew | view file | Clipper, Lotus Approach |
.vue | view | dBASE IV – FoxPro |
.w44 | temporary file for Sort or Index | dBASE |
.wfm | form object | dBASE Form Designer |
.win | window file | FoxPro – dBASE |
Source : http://www.clicketyclick.dk/databases/xbase/format/index.html
Notes:
– Such a list can’t be perfect. Some item may be obsolete / forgotten and something may not exist when this list compiled.
– “Clipper” may not include all versions of Clipper.
– Most of Clipper files are supported by Harbour.
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() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._