[home] [step1][step2][step3] [step4][step5][step6] [step7][links]
A different way to program using Clipper 5.2 without commands, that is, without the file STD.CH.
All trade names referenced herein are either trademarks or registered trademarks of their respective companies. In particular, Clipper (CA-Clipper) is a registered trademark of Computer Associates International.
Written by Daniele Giacomini (forgive my bad english :-). Any comment and/or correction is appreciated.
Clipper 5.2 as others xBASEs is not an ordered, clear, simple programming language. I understood that duriing my little personal experience with it because I ever tryed to find the right way to do everything. If you are not looking to make a xBase program, but a Clipper program, maybe you should find that it is better to use Clipper without commands.
Suppose that you compile the file "test.prg" this way:
CLIPPER test.prg /P
It generates a preprocessed output file (test.PPO), that is a source file without comments, where commands are translated into real Clipper instructions. That is, all the #COMMAND substitution are executed and the translation is sent to the .PPO file.
It may be difficult to read this file the first time, but that only because we have ever used commands.
The code block is a small piece of executable program code that can be stored inside a variable or use as a literal constant. The good of it is that, peaces of code may be sent to functions.
A code block is something like a little user defined function where only a sequence of expressions (functions and/or assignments) may appear: no loops, no IF ELSE END.
A code block may receive arguments and retun a value after execution, just like a function. The syntax is:
{ | [<argument list>] | <exp list> }
That is: the <argument list> is optional; the <exp list> may contain one or more expressions separated with a comma.
For example, calling the following code block will give the string "hello world" as reslut.
{ || "hello world" }
The following code block require a numeric argument an returns the number passed as argument incremented:
{ | n | n+1 }
The following code block requires two numeric arguments and returns the sum of the two square radix:
{ | nFirst, nSecond | SQRT(nFirst) + SQRT(nSecond) }
But code blocks may contains more expressions and the result of the
execution of the code block is the result of the last expression.
The following code block executes in sequence some functions and gives
"hello world" as a result.
{ | a, b | functionOne(a), functionTwo(b), "hello world" }
To start the execution of a code block a function is used: EVAL()
For example, a code block is assigned to a variable and then executed.
B := { || "hello world" } EVAL( B ) == "hello world"
Another example with one parameter.
B := { | n | n+1 } EVAL( B, 1 ) == 2
Another example with two parameters.
B := { | nFirst, nSecond | SQRT(nFirst) + SQRT(nSecond) } EVAL( B, 2, 4 ) == 20
And so on.
Clipper 5.2 do not permit to create objects, but it gives you some good objects to use: GET and TBROWSE. Before you go to clean you programming from commands, you need to understand how to use well the Clipper objects.
A class defines the structure of a "blak box", that is a data container; a method is an action to make on a peace of data contained inside the "black box". There is no way to reach the data contained inside the black box without a method.
The "black box" can be called object.
The methods may be seen as they where special functions whitch interacts with a specific peace of data contained inside the object.
Let us suppose that Clipper permits us to define classes (unluckyly we can only use predefined classes). The hypotetical syntax could be:
CLASS <ClassName> [FROM <ParentClass>] VAR <Var1> [,<Var2>[,...<VarN>]] METHOD {Method Definition1} [ , ...{Method DefinitionN} ] ENDCLASS
This way, the class defines a group of variables and a group of method to use with these wariables.
The presence of classes permits to create objects: our black boxes.
<Variable name> := <ClassName>
This way, a variable contains (is) an object. Please note that inside Clipper, an object may be generated also from a function, that is, a function can return an object. This way the example can be:
<Variable name> := classfunction( ... )
The next problem is to handle this object.
As it was said before, to handle data contained inside and object we need methods. Doing that we say that we are instantiating an object. Clipper permits also to handle directly (apparentrly without methods) some variables conatined inside objects. These are called "Exported Instance Variables". So we can instatiate a object this way:
<object>:<exported instance variable> := <new value> <object>:<method()>
An Exported Instance Variable may be read and/or modifyed depending on the allowed access to it; a method, inside Clipper, is something like a function with or without parameters (if parameters are present, these are usually used to modify data inside the object), that normally returns a value.
To instantiate an object or simply to access an exported instance variable, the "send" symbol (colon) is used.
If this is not enough to understand objects inside Clipper I suggest you to read and test:
o:Clip - An Object Oriented Extension to Clipper 5.01 - (c) 1991 Peter M. Freese, CyberSoft
http://www.coast.net/SimTel/SimTel/msdos/clipper/oclip.zip (15k)
Do you ever asked yoursef what happend with a command like the following:
@ <nTop>, <nLeft> GET <Var>
A get object is created containing all the necessary information for editing the variable <Var> at the screen position <nTop>, <nLeft>. After that, this get object is added to a get objects array (usually called GetList). The get objects array will contain all the get objects used during a READ.
So, what happends when a READ command is encoutered. The get objects array (GetList) is read and the editing of all get objects is executed. After that, the get objects array is cleared.
This method hides what Clipper really makes. I suggest to create a GET() function that will substitute the @...GET command and to use the READMODAL() function to read the get objects array. Here is an example of it:
function GET( aoGet, nRow, nCol, bVar, cGetPicture, cColorString, bPreValid, bPostValid ) // declare a local get object local oGet // create the get object using the function GETENV() oGet := GETENV( nRow, nCol, bVar, NIL, cGetPicture, cGetColor ) // send to the get object the prevalidation condition code block (WHEN) oGet:preBlock := bPreValid // send to the get object the postvalidation condition code block (VALID) oGet:postBlock := bPostValid // display the get on the screen using the display() method oGet:display() // add the get object to the get objects array AADD( aoGet, oGet ) return NIL
If we have a get function like the above one, screen I/O may be performed like the following example:
function do_some_editing() // define a variable to use as a get objects array // and initialise it to the empty array local aoGet := {} ... ... // add a new get object to the get objects array get(; aoGet,; 10, 10,; { |x| iif( pcount() > 0, myVariable := x, myVariable },; "@s30@",; "gb+/b, n/w, n, n, w/n",; { || .T. },; { || .T. }; ) ... // read the get objects array readmodal( aoGet ) // clear the get objects array aoGet := {} ... return ...
If you don't like the GET() function, the above I/O may be done as it follows:
function do_some_editing() // define a variable to use as a get object local aoGet // define a variable to use as a get objects array // and initialise it to the empty array local aoGet := {} ... ... // add a new get object to the get objects array oGet :=; GETENV(; 10, 10,; { |x| iif( pcount() > 0, myVariable := x, myVariable },; NIL,; "@s30@",; "gb+/b, n/w, n, n, w/n",; ) AADD( aoGet, oGet ) ... // read the get objects array readmodal( aoGet ) // clear the get objects array aoGet := {} ... return ...
If you have understood that you are ready to forget the @...GET command.
To stop using commands, you need to know how commands are or may be translated into functions. Take note that sometimes Clipper uses some undocumented functions: these are functions that start with a underline.
? [<exp list>]
qout([<exp list>])
?? [<exp list>]
qqout([<exp list>])
@ <nTop>, <nLeft>, <nBottom>, <nRight> BOX <cnBoxString> [COLOR <cColorString>]
dispbox(<nTop>, <nLeft>, <nBottom>, <nRight>, [<cnBoxString>], [<cColorString>])
@ <nTop>, <nLeft> GET <Var> [PICTURE <cGetPicture>] [COLOR <cColorString>] [WHEN <lPreExpression>] [VALID <lPostExpression>]
setpos(<nTop>, <nLeft>)
aadd( GetList, _GET_( <Var>, "<Var>", <cGetPicture>, [{|| <lPostExpression>}], [{|| <lPreExpression>}] ):display() ) atail(GetList):colorDisp(<cColorString>)
This is the command substitution made automatically, but I wouldn't use it. I suggest to create a get function described before at the Step 4 and use it instead.
@ <nTop>, <nLeft> SAY <exp> [COLOR <cColorString>]
devpos(<nTop>, <nLeft>)
devout(<exp> [, <cColorString>])
@ <nTop>, <nLeft> SAY <exp> PICTURE <cSayPicture> [COLOR <cColorString>]
devpos(<nTop>, <nLeft>)
devoutpic(<exp>, <cSayPicture>, [<cColorString>])
@ <nTop>, <nLeft> TO <nBottom>, <nRight> DOUBLE [COLOR <cColorString>]
dispbox(<nTop>, <nLeft>, <nBottom>, <nRight>, 2 [,<cColorString>])
@ <nTop>, <nLeft> TO <nBottom>, <nRight> [COLOR <cColorString>]
dispbox(<nTop>, <nLeft>, <nBottom>, <nRight>, 1 [,<cColorString>])
@ <nTop>, <nLeft> CLEAR [TO <nBottom>, <nRight>]
scroll([<nTop>], [<nLeft>], [<nBottom>, <nRight>])
setpos(<nRow>, <nCol>)
APPEND BLANK
dbappend()
APPEND FROM <xcFile> [FIELDS <idField list> [<scope>] [WHILE <lCondition>] [FOR <lCondition>] [VIA <xcDriver>]
__dbApp( <cFileName>, [<acFields>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>], [<cDriver>] )
APPEND FROM <xcFile> [FIELDS <idField list> [<scope>] [WHILE <lCondition>] [FOR <lCondition>] DELIMITED <xcDelimiter>
__dbDelim( .f., <cFileName>, [<cDelimiter>], [<acFields>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>] )
APPEND FROM <xcFile> [FIELDS <idField list> [<scope>] [WHILE <lCondition>] [FOR <lCondition>] SDF
__dbSDF( .f., <cFileName>, [<acFields>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>] )
CLEAR
Scroll()
SetPos(0,0)
ReadKill(.T.)
GetList := {}
CLEAR GETS
ReadKill(.T.)
GetList := {}
CLEAR SCREEN | CLS
Scroll()
SetPos(0,0)
CLOSE
dbCloseArea()
CLOSE <idAlias>
<idAlias>->( dbCloseArea() )
CLOSE ALTERNATE
Set(19, "")
CLOSE DATABASES
dbCloseAll()
CLOSE INDEXES
dbClearIndex()
COMMIT
dbCommitAll()
CONTINUE
__dbContinue()
COPY FILE <xcSourceFile> TO <xcTargetFile>|<xcDevice>
__CopyFile( <cSourceFile>, <cTargetFile>|<cDevice> )
COPY STRUCTURE [FIELDS <idField list>] TO <xcDatabase>
__dbCopyStruct( <cDatabase>, [<acFields>] )
COPY STRUCTURE EXTENDED TO <xcExtendedDatabase>
__dbCopyXStruct( <cExtendedDatabase> )
COPY TO <xcFile> [FIELDS <idField list> [<scope>] [WHILE <lCondition>] [FOR <lCondition>] [VIA <xcDriver>]
__dbCopy( <cFileName>, [<acFields>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>], [<cDriver>] )
COPY TO <xcFile> [FIELDS <idField list> [<scope>] [WHILE <lCondition>] [FOR <lCondition>] DELIMITED <xcDelimiter>
__dbDelim( .t., <cFileName>, [<cDelimiter>], [<acFields>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>] )
COPY TO <xcFile> [FIELDS <idField list> [<scope>] [WHILE <lCondition>] [FOR <lCondition>] SDF
__dbSDF( .t., <cFileName>, [<acFields>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>] )
COUNT TO <idVar> [FOR <lForCondition>] [WHILE <lWhileCondition>] [NEXT <nNextRecords>] [RECORD <nRecord>] [REST] [ALL]
dbeval( {||<idVar>:=<idVar>+1}, {||<lForCondition>}, {||<lWhileCondition>}, <nNextRecords>, <nRecord>, <lRest> )
CREATE <xcDatabase> FROM <xcExtendedDatabase> [NEW] [ALIAS <cAlias>] [VIA <cDriver>]
__dbCreate( <cDatabase>, <cExtendedDatabase>, [<cDriver>], [<lNew>], [<cAlias>] )
DEFAULT <xVar> TO <xDefaultValue>
if <xVar> == NIL
<xVar> := <xDefaultValue>
end
DELETE
dbDelete()
DELETE [FOR <lForCondition>] [WHILE <lWhileCondition>] [NEXT <nNextRecords>] [RECORD <nRecord>] [REST] [ALL]
dbeval( {||dbDelete()}, {||<lForCondition>}, {||<lWhileCondition>}, <nNextRecords>, <nRecord>, <lRest> )
DELETE FILE <xcFile>
ferase( <cFile> )
EJECT
qqout( chr(13) )
ERASE <xcFile>
ferase( <cFile> )
FIND <xcSearchString>
dbSeek( <cSearchString> )
GO[TO] <nRecord>
dbgoto(nRecord)
GO[TO] BOTTOM
dbGoBottom()
GO[TO] TOP
dbgotop()
INDEX ON <expKey> TO <xcIndexName> [UNIQUE] [FOR <lForCondition>] [WHILE <lWhileCondition>] [[EVAL <lEvalCondition>] [EVERY <nRecords>]] [ASCENDING|DESCENDING]
ordCondSet( [<cForCondition>], [<bForCondition>],, [<bWhileCondition>], [<bEvalCondition>], [<nRecords>], RECNO(),,,, <lDescending> )
ordCreate( <cIndexName>,, <cExpKey>, <bExpKey>, <lUnique> )
JOIN WITH <xcAlias> TO <xcDatabase> [FOR <lCondition>] [FIELDS <idField list>]
__dbJoin( <cAlias>, <cDatabase>, [<acFields>], [<bForCondition>] )
KEYBOARD <cString>
__Keyboard( [<cString>] ) --> NIL
LABEL FORM <xcLabel> [TO PRINTER] [TO FILE <xcFile>] [NOCONSOLE] [<scope>] [WHILE <lCondition>] [FOR <lCondition>] [SAMPLE]
__LabelForm( <cLabel>, [<lToPrinter>], [<cFile>], [<lNoConsole>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>], [<lSample>] )
LIST <exp list> [TO PRINTER] [TO FILE <xcFile>] [<scope>] [WHILE <lCondition>] [FOR <lCondition>] [OFF]
__dbList( [<lToDisplay>], <abListColumns>, [<lAll>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>], [<lToPrinter>], [<cFileName>] )
LOCATE [<scope>] FOR <lCondition> [WHILE <lCondition>
__dbLocate( [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>] )
PACK
__dbPack()
QUIT
__Quit()
READ
ReadModal(GetList)
GetList := {}
READ SAVE
ReadModal(GetList)
RECALL
dbRecall()
RECALL [FOR <lForCondition>] [WHILE <lWhileCondition>] [NEXT <nNextRecords>] [RECORD <nRecord>] [REST] [ALL]
dbeval( {||dbRecall()}, {||<lForCondition>}, {||<lWhileCondition>}, <nNextRecords>, <nRecord>, <lRest> )
REINDEX [EVAL <lEvalCondition>] [EVERY <nRecords>]
ordCondSet(,,,, [<bEvalCondition>], [<nRecords>],,,,,,,)
ordListRebuild()
RELEASE <idMemvar>
__MXRelease( "<idMemvar>" )
RELEASE ALL
__MRelease("*", .t.)
RELEASE ALL LIKE <skeleton>
__MRelease( "<skeleton>", .t. )
RELEASE ALL EXCEPT <skeleton>
__MRelease( "<skeleton>", .F. )
RENAME <xcOldFile> TO <xcNewFile>
frename( <cOldFile>, <cNewFile> )
REPLACE <idField1> WITH <exp1> [, <idField2> WITH <exp2>...] [FOR <lForCondition>] [WHILE <lWhileCondition>] [NEXT <nNextRecords>] [RECORD <nRecord>] [REST] [ALL]
dbeval( {|| <idField1> := <exp1> [, <idField2> := <exp2>...]}, {||<lForCondition>}, {||<lWhileCondition>}, <nNextRecords>, <nRecord>, <lRest> )
REPLACE <idField1> WITH <exp1>
<idField1> := <exp1>
REPORT FORM <xcReport> [TO PRINTER] [TO FILE <xcFile>] [NOCONSOLE] [<scope>] [WHILE <lCondition>] [FOR <lCondition>] [PLAIN | HEADING <cHeading>] [NOEJECT] [SUMMARY]
__ReportForm( <cForm>, [<lToPrinter>], [<cToFile>], [<lNoConsole>], [<bForCondition>], [<bWhileCondition>], [<nNext>], [<nRecord>], [<lRest>], [<lPlain>], [<cbHeading>], [<lBeforeEject>], [<lSummary>] )
RESTORE SCREEN FROM <cScreen>
restscreen( 0, 0, Maxrow(), Maxcol(), <cScreen> )
RESTORE FROM <xcMemFile> [ADDITIVE]
__MRestore( <cMemFileName>, [<lAdditive>] )
RUN <xcCommandLine>
__Run( <cCommand> )
SAVE SCREEN TO <cScreen>
<cScreen> := savescreen( 0, 0, maxrow(), maxcol() )
SAVE TO <xcMemFile> [ALL [LIKE|EXCEPT <skeleton>]]
_MSave( <cMemFileName>, [<cSkeleton>], [<lLike>] )
SEEK <expSearch> [SOFTSEEK]
dbSeek( <expSearch> [, <lSoftSeek>] )
SELECT <xnWorkArea> | <idAlias>
dbSelectArea( <nWorkArea> | <cIdAlias> )
Most of the SET... commands are translated into the SET() function that distinguishes different modes depending on a number. As this number is difficult to handle duriing programming (essentially because it is difficult to remember the meaning of it), Clipper gives you the SET.CH include file that helps with manifest constants.
#define _SET_EXACT 1 #define _SET_FIXED 2 #define _SET_DECIMALS 3 #define _SET_DATEFORMAT 4 #define _SET_EPOCH 5 #define _SET_PATH 6 #define _SET_DEFAULT 7 #define _SET_EXCLUSIVE 8 #define _SET_SOFTSEEK 9 #define _SET_UNIQUE 10 #define _SET_DELETED 11 #define _SET_CANCEL 12 #define _SET_DEBUG 13 #define _SET_TYPEAHEAD 14 #define _SET_COLOR 15 #define _SET_CURSOR 16 #define _SET_CONSOLE 17 #define _SET_ALTERNATE 18 #define _SET_ALTFILE 19 #define _SET_DEVICE 20 #define _SET_EXTRA 21 #define _SET_EXTRAFILE 22 #define _SET_PRINTER 23 #define _SET_PRINTFILE 24 #define _SET_MARGIN 25 #define _SET_BELL 26 #define _SET_CONFIRM 27 #define _SET_ESCAPE 28 #define _SET_INSERT 29 #define _SET_EXIT 30 #define _SET_INTENSITY 31 #define _SET_SCOREBOARD 32 #define _SET_DELIMITERS 33 #define _SET_DELIMCHARS 34 #define _SET_WRAP 35 #define _SET_MESSAGE 36 #define _SET_MCENTER 37 #define _SET_SCROLLBREAK 38
SET ALTERNATE TO <xcFile> [ADDITIVE]
Set( _SET_ALTFILE, <cFile>, lAdditive )
SET ALTERNATE ON | OFF | <xlToggle>
Set( _SET_ALTERNATE, "ON" | "OFF" | <lToggle> )
SET BELL ON | OFF | <xlToggle>
Set( _SET_BELL, "ON" | "OFF" | <lToggle> )
SET COLOR | COLOUR TO (cColorString)
SetColor( cColorString )
SET CONFIRM ON | OFF | <xlToggle>
Set( _SET_CONFIRM, "ON" | "OFF" | <lToggle> )
SET CONSOLE ON | OFF | <xlToggle>
Set( _SET_CONSOLE, "ON" | "OFF" | <lToggle> )
SET CURSOR ON | OFF | <xlToggle>
SetCursor( 1 | 0 | iif( <lToggle>, 1, 0 ) )
SET DATE FORMAT [TO] <cDateFormat>
Set( _SET_DATEFORMAT, <cDateFormat> )
SET DECIMALS TO
Set( _SET_DECIMALS, 0 )
SET DECIMALS TO <nDecimals>
Set( _SET_DECIMALS, <nDecimals> )
SET DEFAULT TO
Set( _SET_DEFAULT, "" )
SET DEFAULT TO <xcPathspec>
Set( _SET_DEFAULT, <cPathspec> )
SET DELETED ON | OFF | <xlToggle>
Set( _SET_DELETED, "ON" | "OFF" | <lToggle> )
SET DELIMITERS ON | OFF | <xlToggle>
Set( _SET_DELIMITERS, "ON" | "OFF" | <lToggle> )
SET DELIMITERS TO [DEFAULT]
Set( _SET_DELIMCHARS, "::" )
SET DELIMITERS TO <cDelimiters>
Set( _SET_DELIMCHARS, <cDelimiters> )
SET DEVICE TO SCREEN | PRINTER
Set( _SET_DEVICE, "SCREEN" | "PRINTER" )
SET EPOCH TO <nYear>
Set( _SET_EPOCH, <nYear> )
SET ESCAPE ON | OFF | <xlToggle>
Set( _SET_ESCAPE, "ON" | "OFF" | <lToggle> )
SET EXACT ON | OFF | <xlToggle>
Set( _SET_EXACT, "ON" | "OFF" | <lToggle> )
SET EXCLUSIVE ON | OFF | <xlToggle>
Set( _SET_EXCLUSIVE, "ON" | "OFF" | <lToggle> )
SET FILTER TO
dbclearfilter()
SET FILTER TO <lCondition>
dbsetfilter( <bCondition>, <cCondition> )
SET FIXED ON | OFF | <xlToggle>
Set( _SET_FIXED, "ON" | "OFF" | <lToggle> )
SET FUNCTION <nFunctionKey> TO <cString>
__SetFunction( <nFunctionKey>, <cString> )
SET INDEX TO [<xcIndex> [, <xcIndex1>... ] ]
ordListClear()
ordListAdd( <cIndex> )
ordListAdd( <cIndex1> )
...
SET INTENSITY ON | OFF | <xlToggle>
Set( _SET_INTENSITY, "ON" | "OFF" | <lToggle> )
SET KEY <nInkeyCode> [TO]
SetKey( <nInkeyCode>, NIL )
SET KEY <nInkeyCode> TO [<idProcedure>]
SetKey( <nInkeyCode>, { |p, l, v| idProcedure(p, l, v)} )
SET MARGIN TO
Set( _SET_MARGIN, 0 )
SET MARGIN TO [<nPageOffset>]
Set( _SET_MARGIN, <nPageOffset> )
SET MESSAGE TO
Set( _SET_MESSAGE, 0 )
Set( _SET_MCENTER, .F. )
SET MESSAGE TO [<nRow> [CENTER | CENTRE]]
Set( _SET_MESSAGE, nRow )
Set( _SET_MCENTER, lCenter )
SET ORDER TO [<nIndex>]
ordSetFocus( <nIndex> )
SET PATH TO
Set( _SET_PATH, "" )
SET PATH TO [<xcPathspec> [, <cPathspec1>... ] ]
Set( _SET_PATH, <cPathspec> [, <cPathspec1>... ] )
SET PRINTER ON | OFF | xlToggle
Set( _SET_PRINTER, "ON" | "OFF" | lToggle )
SET PRINTER TO
Set( _SET_PRINTFILE, "" )
SET PRINTER TO [<xcDevice>|<xcFile> [ADDITIVE]]
Set( _SET_PRINTFILE, <cDevice>|<cFile>, lAdditive )
SET RELATION TO
dbclearrelation()
SET RELATION TO [<expKey1> INTO <xcAlias1>] [, [TO] <expKey2> INTO <xcAlias2>...]
dbClearRel()
dbSetRelation( <cAlias1>, {||<expKey1>}, ["<expKey1>"] )
dbSetRelation( <cAlias2>, <{||<expKey2>}, ["<expKey1>"] )
SET RELATION TO [<expKey1> INTO <xcAlias1>] [, [TO] <expKey2> INTO <xcAlias2>...] ADDITIVE
dbSetRelation( <cAlias1>, {||<expKey1>}, ["<expKey1>"] )
dbSetRelation( <cAlias2>, <{||<expKey2>}, ["<expKey1>"] )
SET SCOREBOARD ON | OFF | xlToggle
Set( _SET_SCOREBOARD, "ON" | "OFF" | lToggle )
SET SOFTSEEK ON | OFF | xlToggle
Set( _SET_SOFTSEEK, "ON" | "OFF" | lToggle )
SET TYPEAHEAD TO <nKeyboardSise>
Set( _SET_TYPEAHEAD, <nKeyboardSise> )
SET UNIQUE ON | OFF | xlToggle
Set( _SET_UNIQUE, "ON" | "OFF" | lToggle )
SET WRAP ON | OFF | xlToggle
Set( _SET_WRAP, "ON" | "OFF" | lToggle )
SKIP [<nRecords> [ALIAS <idAlias>|<nWorkArea>]
[<idAlias>|<nWorkArea> -> ]( dbSkip([<nRecords>]) )
SORT TO <xcDatabase> ON <idField1> [/[A|D][C]] [, <idField2> [/[A|D][C]] ...] [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
__dbSort( <cDatabase>, [<acFields>], [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>] )
STORE <value> TO <variable>
<variable> := <value>
SUM <nExp1> [, <nExp2>...] TO <idVar1> [, <idVar2>...] [FOR <lForCondition>] [WHILE <lWhileCondition>] [NEXT <nNextRecords>] [RECORD <nRecord>] [REST] [ALL]
dbeval( {||<idVar1>:=<idVar1>+<nExp1> [, <idVar2>:=<idVar2>+<nExp2>...] }, {||<lForCondition>}, {||<lWhileCondition>}, <nNextRecords>, <nRecord>, <lRest> )
TOTAL ON <expKey> [FIELDS <idField list>] TO <xcDatabase> [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
__dbTotal( <cDatabase>, <bKey>, [<acFields>, [<bForCondition>], [<bWhileCondition>], [<nNextRecords>], [<nRecord>], [<lRest>] )
UNLOCK
dbUnlock()
UNLOCK ALL
dbUnlockAll()
UPDATE FROM <xcAlias> ON <expKey> [RANDOM] REPLACE <idField1> WITH <exp> [, <idField2> WITH <exp> ...]
dbUpdate( <cAlias>, <bKey>, [<lRandom>], [<bReplacement>] )
Example:
__dbUpdate( "INVOICE", {|| LAST}, .T.,; {|| FIELD->TOTAL1 := INVOICE->SUM1,; FIELD->TOTAL2 := INVOICE->SUM2 } )
USE
dbclosearea()
USE [<xcDatabase> [INDEX <xcIndex1> [, <xcIndex2>...] [ALIAS <xcAlias>] [EXCLUSIVE|SHARED] [NEW] [READONLY] [VIA <cDriver>]]
dbUseArea( [<lNewArea>], [<cDriver>], <cDatabase>, [<cAlias>], [<lShared>], [<lReadOnly>] )
[dbSetIndex( <cIndex1> )]
[dbSetIndex( <cIndex2> )]
...
ZAP
dbZap()
Now that you don't use commands, you can free yourself from STD.CH the standard include file. Clipper uses STD.CH automatically, unless that you tell it not to do it. You have to compile this way:
CLIPPER test.prg /U
Clipper comes with so many include files (*.CH). Haven't you ever had troubles with that? I suggest you to create your own STANDARD.CH file containing all what you need for your application. I suggest at least the following.
*================================================================= * DISPBOX() *================================================================= * Single-line box #define BOX_SINGLE; (; CHR(218) +; CHR(196) +; CHR(191) +; CHR(179) +; CHR(217) +; CHR(196) +; CHR(192) +; CHR(179); ) * Double-line box #define BOX_DOUBLE; (; CHR(201) +; CHR(205) +; CHR(187) +; CHR(186) +; CHR(188) +; CHR(205) +; CHR(200) +; CHR(186); ) * Single-line top, double-line sides #define BOX_SINGLE_DOUBLE; (; CHR(214) +; CHR(196) +; CHR(183) +; CHR(186) +; CHR(189) +; CHR(196) +; CHR(211) +; CHR(186); ) * Double-line top, single-line sides #define BOX_DOUBLE_SINGLE; (; CHR(213) +; CHR(205) +; CHR(184) +; CHR(179) +; CHR(190) +; CHR(205) +; CHR(212) +; CHR(179); ) *================================================================= * ERRORS *================================================================= * Severity levels (e:severity) #define ERROR_SEVERITY_WHOCARES 0 #define ERROR_SEVERITY_WARNING 1 #define ERROR_SEVERITY_ERROR 2 #define ERROR_SEVERITY_CATASTROPHIC 3 * Generic error codes (e:genCode) #define ERROR_GENERIC_ARG 1 #define ERROR_GENERIC_BOUND 2 #define ERROR_GENERIC_STROVERFLOW 3 #define ERROR_GENERIC_NUMOVERFLOW 4 #define ERROR_GENERIC_ZERODIV 5 #define ERROR_GENERIC_NUMERR 6 #define ERROR_GENERIC_SYNTAX 7 #define ERROR_GENERIC_COMPLEXITY 8 #define ERROR_GENERIC_MEM 11 #define ERROR_GENERIC_NOFUNC 12 #define ERROR_GENERIC_NOMETHOD 13 #define ERROR_GENERIC_NOVAR 14 #define ERROR_GENERIC_NOALIAS 15 #define ERROR_GENERIC_NOVARMETHOD 16 #define ERROR_GENERIC_BADALIAS 17 #define ERROR_GENERIC_DUPALIAS 18 #define ERROR_GENERIC_CREATE 20 #define ERROR_GENERIC_OPEN 21 #define ERROR_GENERIC_CLOSE 22 #define ERROR_GENERIC_READ 23 #define ERROR_GENERIC_WRITE 24 #define ERROR_GENERIC_PRINT 25 #define ERROR_GENERIC_UNSUPPORTED 30 #define ERROR_GENERIC_LIMIT 31 #define ERROR_GENERIC_CORRUPTION 32 #define ERROR_GENERIC_DATATYPE 33 #define ERROR_GENERIC_DATAWIDTH 34 #define ERROR_GENERIC_NOTABLE 35 #define ERROR_GENERIC_NOORDER 36 #define ERROR_GENERIC_SHARED 37 #define ERROR_GENERIC_UNLOCKED 38 #define ERROR_GENERIC_READONLY 39 #define ERROR_GENERIC_APPENDLOCK 40 #define ERROR_GENERIC_LOCK 41 *================================================================= * INKEY() *================================================================= #define K_UP 5 // Up arrow, Ctrl-E #define K_DOWN 24 // Down arrow, Ctrl-X #define K_LEFT 19 // Left arrow, Ctrl-S #define K_RIGHT 4 // Right arrow, Ctrl-D #define K_HOME 1 // Home, Ctrl-A #define K_END 6 // End, Ctrl-F #define K_PGUP 18 // PgUp, Ctrl-R #define K_PGDN 3 // PgDn, Ctrl-C #define K_CTRL_UP 397 // * Ctrl-Up arrow #define K_CTRL_DOWN 401 // * Ctrl-Down arrow #define K_CTRL_LEFT 26 // Ctrl-Left arrow, Ctrl-Z #define K_CTRL_RIGHT 2 // Ctrl-Right arrow, Ctrl-B #define K_CTRL_HOME 29 // Ctrl-Home, Ctrl-] #define K_CTRL_END 23 // Ctrl-End, Ctrl-W #define K_CTRL_PGUP 31 // Ctrl-PgUp, Ctrl-Hyphen #define K_CTRL_PGDN 30 // Ctrl-PgDn, Ctrl-^ #define K_ALT_UP 408 // * Alt-Up arrow #define K_ALT_DOWN 416 // * Alt-Down arrow #define K_ALT_LEFT 411 // * Alt-Left arrow #define K_ALT_RIGHT 413 // * Alt-Right arrow #define K_ALT_HOME 407 // * Alt-Home #define K_ALT_END 415 // * Alt-End #define K_ALT_PGUP 409 // * Alt-PgUp #define K_ALT_PGDN 417 // * Alt-PgDn #define K_ENTER 13 // Enter, Ctrl-M #define K_RETURN 13 // Return, Ctrl-M #define K_SPACE 32 // Space bar #define K_ESC 27 // Esc, Ctrl-[ #define K_CTRL_ENTER 10 // Ctrl-Enter #define K_CTRL_RETURN 10 // Ctrl-Return #define K_CTRL_RET 10 // Ctrl-Return (Compat.) #define K_CTRL_PRTSCR 379 // * Ctrl-Print Screen #define K_CTRL_QUESTION 309 // Ctrl-? #define K_ALT_ENTER 284 // * Alt-Enter #define K_ALT_RETURN 284 // * Alt-Return #define K_ALT_EQUALS 387 // * Alt-Equals #define K_ALT_ESC 257 // * Alt-Esc #define KP_ALT_ENTER 422 // * Keypad Alt-Enter #define KP_CTRL_5 399 // * Keypad Ctrl-5 #define KP_CTRL_SLASH 405 // * Keypad Ctrl-/ #define KP_CTRL_ASTERISK 406 // * Keypad Ctrl-* #define KP_CTRL_MINUS 398 // * Keypad Ctrl-- #define KP_CTRL_PLUS 400 // * Keypad Ctrl-+ #define KP_ALT_5 5 // * Keypad Alt-5 #define KP_ALT_SLASH 420 // * Keypad Alt-/ #define KP_ALT_ASTERISK 311 // * Keypad Alt-* #define KP_ALT_MINUS 330 // * Keypad Alt-- #define KP_ALT_PLUS 334 // * Keypad Alt-+ #define K_INS 22 // Ins, Ctrl-V #define K_DEL 7 // Del, Ctrl-G #define K_BS 8 // Backspace, Ctrl-H #define K_TAB 9 // Tab, Ctrl-I #define K_SH_TAB 271 // Shift-Tab #define K_CTRL_INS 402 // * Ctrl-Ins #define K_CTRL_DEL 403 // * Ctrl-Del #define K_CTRL_BS 127 // Ctrl-Backspace #define K_CTRL_TAB 404 // * Ctrl-Tab #define K_ALT_INS 418 // * Alt-Ins #define K_ALT_DEL 419 // * Alt-Del #define K_ALT_BS 270 // * Alt-Backspace #define K_ALT_TAB 421 // * Alt-Tab #define K_CTRL_A 1 // Ctrl-A, Home #define K_CTRL_B 2 // Ctrl-B, Ctrl-Right arrow #define K_CTRL_C 3 // Ctrl-C, PgDn, Ctrl-ScrollLock #define K_CTRL_D 4 // Ctrl-D, Right arrow #define K_CTRL_E 5 // Ctrl-E, Up arrow #define K_CTRL_F 6 // Ctrl-F, End #define K_CTRL_G 7 // Ctrl-G, Del #define K_CTRL_H 8 // Ctrl-H, Backspace #define K_CTRL_I 9 // Ctrl-I, Tab #define K_CTRL_J 10 // Ctrl-J #define K_CTRL_K 11 // Ctrl-K #define K_CTRL_L 12 // Ctrl-L #define K_CTRL_M 13 // Ctrl-M, Return #define K_CTRL_N 14 // Ctrl-N #define K_CTRL_O 15 // Ctrl-O #define K_CTRL_P 16 // Ctrl-P #define K_CTRL_Q 17 // Ctrl-Q #define K_CTRL_R 18 // Ctrl-R, PgUp #define K_CTRL_S 19 // Ctrl-S, Left arrow #define K_CTRL_T 20 // Ctrl-T #define K_CTRL_U 21 // Ctrl-U #define K_CTRL_V 22 // Ctrl-V, Ins #define K_CTRL_W 23 // Ctrl-W, Ctrl-End #define K_CTRL_X 24 // Ctrl-X, Down arrow #define K_CTRL_Y 25 // Ctrl-Y #define K_CTRL_Z 26 // Ctrl-Z, Ctrl-Left arrow #define K_ALT_A 286 // Alt-A #define K_ALT_B 304 // Alt-B #define K_ALT_C 302 // Alt-C #define K_ALT_D 288 // Alt-D #define K_ALT_E 274 // Alt-E #define K_ALT_F 289 // Alt-F #define K_ALT_G 290 // Alt-G #define K_ALT_H 291 // Alt-H #define K_ALT_I 279 // Alt-I #define K_ALT_J 292 // Alt-J #define K_ALT_K 293 // Alt-K #define K_ALT_L 294 // Alt-L #define K_ALT_M 306 // Alt-M #define K_ALT_N 305 // Alt-N #define K_ALT_O 280 // Alt-O #define K_ALT_P 281 // Alt-P #define K_ALT_Q 272 // Alt-Q #define K_ALT_R 275 // Alt-R #define K_ALT_S 287 // Alt-S #define K_ALT_T 276 // Alt-T #define K_ALT_U 278 // Alt-U #define K_ALT_V 303 // Alt-V #define K_ALT_W 273 // Alt-W #define K_ALT_X 301 // Alt-X #define K_ALT_Y 277 // Alt-Y #define K_ALT_Z 300 // Alt-Z #define K_ALT_1 376 // Alt-1 #define K_ALT_2 377 // Alt-2 #define K_ALT_3 378 // Alt-3 #define K_ALT_4 379 // Alt-4 #define K_ALT_5 380 // Alt-5 #define K_ALT_6 381 // Alt-6 #define K_ALT_7 382 // Alt-7 #define K_ALT_8 383 // Alt-8 #define K_ALT_9 384 // Alt-9 #define K_ALT_0 385 // Alt-0 #define K_F1 28 // F1, Ctrl-Backslash #define K_F2 -1 // F2 #define K_F3 -2 // F3 #define K_F4 -3 // F4 #define K_F5 -4 // F5 #define K_F6 -5 // F6 #define K_F7 -6 // F7 #define K_F8 -7 // F8 #define K_F9 -8 // F9 #define K_F10 -9 // F10 #define K_F11 -40 // * F11 #define K_F12 -41 // * F12 #define K_CTRL_F1 -20 // Ctrl-F1 #define K_CTRL_F2 -21 // Ctrl-F2 #define K_CTRL_F3 -22 // Ctrl-F4 #define K_CTRL_F4 -23 // Ctrl-F3 #define K_CTRL_F5 -24 // Ctrl-F5 #define K_CTRL_F6 -25 // Ctrl-F6 #define K_CTRL_F7 -26 // Ctrl-F7 #define K_CTRL_F8 -27 // Ctrl-F8 #define K_CTRL_F9 -28 // Ctrl-F9 #define K_CTRL_F10 -29 // Ctrl-F10 #define K_CTRL_F11 -44 // * Ctrl-F11 #define K_CTRL_F12 -45 // * Ctrl-F12 #define K_ALT_F1 -30 // Alt-F1 #define K_ALT_F2 -31 // Alt-F2 #define K_ALT_F3 -32 // Alt-F3 #define K_ALT_F4 -33 // Alt-F4 #define K_ALT_F5 -34 // Alt-F5 #define K_ALT_F6 -35 // Alt-F6 #define K_ALT_F7 -36 // Alt-F7 #define K_ALT_F8 -37 // Alt-F8 #define K_ALT_F9 -38 // Alt-F9 #define K_ALT_F10 -39 // Alt-F10 #define K_ALT_F11 -46 // * Alt-F11 #define K_ALT_F12 -47 // * Alt-F12 #define K_SH_F1 -10 // Shift-F1 #define K_SH_F2 -11 // Shift-F2 #define K_SH_F3 -12 // Shift-F3 #define K_SH_F4 -13 // Shift-F4 #define K_SH_F5 -14 // Shift-F5 #define K_SH_F6 -15 // Shift-F6 #define K_SH_F7 -16 // Shift-F7 #define K_SH_F8 -17 // Shift-F8 #define K_SH_F9 -18 // Shift-F9 #define K_SH_F10 -19 // Shift-F10 #define K_SH_F11 -42 // * Shift-F11 #define K_SH_F12 -43 // * Shift-F12 *================================================================= * MEMOEDIT() *================================================================= * User function entry modes #define MEMOEDIT_IDLE 0 // idle, all keys processed #define MEMOEDIT_UNKEY 1 // unknown key, memo unaltered #define MEMOEDIT_UNKEYX 2 // unknown key, memo altered #define MEMOEDIT_INIT 3 // initialization mode * User function return codes #define MEMOEDIT_DEFAULT 0 // perform default action #define MEMOEDIT_IGNORE 32 // ignore unknown key #define MEMOEDIT_DATA 33 // treat unknown key as data #define MEMOEDIT_TOGGLEWRAP 34 // toggle word-wrap mode #define MEMOEDIT_TOGGLESCROLL 35 // toggle scrolling mode #define MEMOEDIT_WORDRIGHT 100 // perform word-right operation #define MEMOEDIT_BOTTOMRIGHT 101 // perform bottom-right operation *================================================================= * SET() *================================================================= #define _SET_EXACT 1 #define _SET_FIXED 2 #define _SET_DECIMALS 3 #define _SET_DATEFORMAT 4 #define _SET_EPOCH 5 #define _SET_PATH 6 #define _SET_DEFAULT 7 #define _SET_EXCLUSIVE 8 #define _SET_SOFTSEEK 9 #define _SET_UNIQUE 10 #define _SET_DELETED 11 #define _SET_CANCEL 12 #define _SET_DEBUG 13 #define _SET_TYPEAHEAD 14 #define _SET_COLOR 15 #define _SET_CURSOR 16 #define _SET_CONSOLE 17 #define _SET_ALTERNATE 18 #define _SET_ALTFILE 19 #define _SET_DEVICE 20 #define _SET_EXTRA 21 #define _SET_EXTRAFILE 22 #define _SET_PRINTER 23 #define _SET_PRINTFILE 24 #define _SET_MARGIN 25 #define _SET_BELL 26 #define _SET_CONFIRM 27 #define _SET_ESCAPE 28 #define _SET_INSERT 29 #define _SET_EXIT 30 #define _SET_INTENSITY 31 #define _SET_SCOREBOARD 32 #define _SET_DELIMITERS 33 #define _SET_DELIMCHARS 34 #define _SET_WRAP 35 #define _SET_MESSAGE 36 #define _SET_MCENTER 37 #define _SET_SCROLLBREAK 38 *================================================================= * SETCURSOR() *================================================================= #define SETCURSOR_NONE 0 // No cursor #define SETCURSOR_NORMAL 1 // Normal cursor (underline) #define SETCURSOR_INSERT 2 // Insert cursor (lower half block) #define SETCURSOR_SPECIAL1 3 // Special cursor (full block) #define SETCURSOR_SPECIAL2 4 // Special cursor (upper half block) *================================================================= * RDD REQUESTs *================================================================= external dbfndx external dbfntx // default
I had this idea of writing Clipper code this way when I wrote nanoBase. So, the nanoBase's source code is made following the philosofy of this page: http://www.geocities.com/SiliconValley/7737/nanobase.html
Copyright © 1996-1997 Daniele Giacomini daniele@tv.shineline.it
Copy of this page is allowed provided that it remains unchanged.