-->

Руководство по программированию на clipper

xBase/Clipper Tutorial[edit | edit source]

Please note: if anybody will contribute, the Clipper tutorial should contain only ‘standard’ code that would work on every Clipper compatible compiler. Compiler-specific code should be placed somewhere else, or clearly indicated in a box.

The code here should be of simple console-mode applications using only the simplest forms of input/output and focused only on algorithms, since the methods for creating and managing user interfaces will be described in Chapter 5, Making Up a User Interface.

The helloworld application line by line[edit | edit source]

Let’s try to highlight the parts of helloworld:

 function MAIN
 * This is an example
 clear
 ?"Hello, the weather is fine today"
 return nil

(in GeoCities this and all other sources were highlighted by the on-line service CodeColorizer at http://www.chami.com/colorizer/, or, alternatively by the service at http://tohtml.com/Clipper/ — they tend to look a bit better than the Wikibook highlighting).

We will comment on each line of the helloworld program.

function MAIN

The first line defines a function named MAIN. Defining such a function is not compulsory with Harbour, as if it is missed errors would occur during compilation, but I will keep it to make sure the examples work with all compilers. A function cannot be defined when typing in commands at the dot prompt (hbrun/xbscript).

Every xBase language is case insensitive, which means that all the following lines are the same:

function MAIN
FUNCTION main
FuNcTiOn mAiN

Of course, this feature is beneficial only if you use it to improve the code readability.

We will learn later how to define and use functions and procedures.

* This is an example

The second line is a comment. Commenting your programs will help you when you are to modify them later. If they aren’t commenting, modifying them will be a very hard task. It will be much more difficult if you are to modify programs written by others if they didn’t comment them: figuring out what a program does using only its code is very difficult and even the cleanest programming language may prove to be write-only if not properly commented.

You can write comments in many different styles: using an asterisk (*), two sweeps (//), a double ampersand (&&) or a couple sweep-asterisk (/*) and asterisk-sweep (*/), as shown below:

* This is a comment...
// ...and so is this...
&& ...and this.
/* This is an example of the fourth commenting style,
which may span over several lines.*/

The second and the fourth commenting styles are derived from the C programming language, the first and the third are peculiar of the Clipper/xBase standard. None of these comments are accepted by xbscript, but hbrun (Harbour) accepts the last three.

clear

No, the purpose of this command is not to make the source code clear (that would be too easy! It is up to us to write clear source code, and to do so we must comment it well), but instead to clean the screen.  :-) You could also use clear screen or cls, although these two commands are not exactly the same of this clear (the difference will be clear later when we can GET the point — then, you could also appreciate the pun in this paragraph — but will more likely not).

What are commands?
Harbour commands are defined via the #command macro directive (http://harbour.edu.pl/clipper/en/ng122d3c.html). The first commands we encountered are defined in the file std.ch by these lines:

#command CLS                        => Scroll() ; SetPos(0,0)
#command ?  [<explist,...>]         => QOut( <explist> )
? "Hello, the weather is fine today"

The ? is a command which means print. In the BASIC programming language, it is also an abbreviation for its print command (the syntax of xBase is quite similar to that of the BASIC programming language).

In this case ? print the string «Hello, the weather is fine today«. Please note that a string can be enclosed in single quotes (or apostrophes), double quotes or square brackets: all of the following are the same:

? "Hello, the weather is fine today"
? 'Hello, the weather is fine today'
? [Hello, the weather is fine today]

The last line:

return nil

Return is used to mark the end of the function. We will explain later what the return exactly does.

Today Harbour needs not an explicitly defined main function/procedure. The following version of helloworld will compile and is exactly the same as the previous one:

&& hello world without commands and main
Scroll() ; SetPos(0,0)
QOut( "Hello world" )

The Harbour Interpreter and Virtual Machine
The program above, stored in a text file named hello.prg, can be run with the command

hbrun hello.prg

hbrun is an interpreter for Harbour. This means that if we run it, we get to a screen with a «Dot prompt» on its last line, where we can enter and run instructions. For example, entering

? "Hello world"

will get Hello world printed on the screen, but only after the interpreter hbrun itself is closed. To quit the interpreter and get the greeting printed type

QUIT

All in all, hbrun permits to feel how handling databases was done in the old dBase «Dot prompt» mode — that is, like this: http://manmrk.net/tutorials/database/dbase/IntrodBASEIIIPlus.htm

Running the compiler harbour (harbour.exe on Windows) on a printA.prg containing the line

? "A"

will output a printA.c file. The bottom of this file reads:

HB_FUNC( PRINTA )
{
	static const HB_BYTE pcode[] =
	{
		36,1,0,176,1,0,106,2,65,0,20,1,7
	};

	hb_vmExecute( pcode, symbols );
}

that is, as an intermediate step the Harbour compiler compiles pcode, or bytecode for a virtual machine.

If the compilation is done with the /gh option

hbmk2 /gh printA.prg
harbour /gh printA.prg

the result will be a file named printA.hrb, a «Harbour Portable Object» file which can be executed by

hbrun printA.hrb

In this way, hbmk2 and hbrun work in couple as a perfectly equivalent tools to the Java compiler javac and java interpreter java.

As a parenthesis, virtual machines are not a new concept. If we look into the retrocomputing field, we’ll see that in the late 1970s and early 1980s the University of California San Diego has a portable operating system based on pcode, the UCSD P-System which was written in UCSD Pascal and could be run on 6502, 8080, Z-80, and on PDP-11 http://www.threedee.com/jcm/psystem/index.html (it actually was a competitor of MS-DOS, PC DOS and CP/M — http://www.digitalresearch.biz/CPM.HTM and http://www.seasip.info/Cpm/index.html).

Also, in 1979 Joel Berez and Marc Blank developed the Z-machine as a virtual machine to run Infocom’s text adventure games, the name not hiding they were mainly thinking about Zork. The programming language for the Z-machine was called ZIL (Zork Implementation Language). A modern compiler for ZIL to Microsoft .NET is ZILF https://bitbucket.org/jmcgrew/zilf/wiki/Home and a Z-machine.NET is available https://zmachine.codeplex.com/. More information at http://inform-fiction.org/zmachine/index.html.

Apart from the JVM (Java Virtual Machine), the Microsoft .NET CLR (Common Language Runtime), is another modern virtual machine.

A flowchart of the compilation process (kindly supplied by Wojtek Birula).

hbmk2 was created to support all shells, all compilers on all platforms, also to replace old ‘bld.bat’ solution, while staying compatible with existing hbmk script features and options.

Pieces of information on how to get an executable without using hbmk2 can be found at http://www.kresin.ru/en/hrbfaq.html.

Remember that the PATH Environment Variable (in Windows) must be updated to include the directory containing the compiler: use the command SET PATH=C:hb32bin;%PATH% locally in a Prompt Window or update it globally: «Start» → «Control Panel» → «System» → «Advanced system settings» → «Environment Variables…» → select «Path», then click «Edit…»

Data Types in General (and Their Operators)[edit | edit source]

The list of types supported by Clipper is as follows:

  • A Array
  • B (Code) Block
  • C Character
  • D Date
  • L Logical
  • M Memo
  • N Numeric
  • O Object
  • U NIL

These letters can be used as a prefix to a variable name, to indicate «at first sight» what kind of item it is. This way oBox would be the name of an object, aNames an array, dBirthday a date and so on. An alternative for logical variables is to add an is prefix as in isOk or isExisting (somewhat more readable than lOk and lExisting). This naming convention is called the Hungarian notation and applies to functions as well, and to their synopsis: ACOPY( <aSource>, <aTarget>, [<nStart>], [<nCount>], [<nTargetPos>] ) is the function to copy elements from an array to another, which takes two arrays aSource and aTarget, and optionally three numeric parameters nStart, nCount, nTargetPos; CToD(cDate) takes a character argument and converts it to a date, DBCreate() is a function to create a database.

The type Memo can only be used in a database (it is a link to a subsidiary file to a DBF table, as described in the Wikipedia DBF entry).

This is the list of results returned by the function VALTYPE(). The function TYPE() returns also:

  • U NIL, local, or static
  • UE Error syntactical
  • UI Error indeterminate

Harbour has a longer list (http://www.fivetechsoft.com/harbour-docs/harbour.html):

  • HB_ISARRAY
  • HB_ISBLOCK
  • HB_ISCHAR
  • HB_ISDATE
  • HB_ISDATETIME
  • HB_ISHASH
  • HB_ISLOGICAL
  • HB_ISMEMO
  • HB_ISNIL
  • HB_ISNULL
  • HB_ISNUMERIC
  • HB_ISOBJECT
  • HB_ISPOINTER
  • HB_ISPRINTER
  • HB_ISREGEX
  • HB_ISSTRING
  • HB_ISSYMBOL
  • HB_ISTIMESTAMP

ISPOINTER() (http://www.marinas-gui.org/projects/harbour_manual/ispointer.htm) for example is marked: Not available in CA-Cl*pper. Together with HB_IT_POINTER and HB_ISPOINTER it is used in Harbour’s internals (the C-level API: http://www.fivetechsoft.com/harbour-docs/clevelapi.html#ispointer).

Let us see a little program that shows the use of the most common data types.

I wanted to show, in this example, a computation of π instead of that of √2, but xBase misses the ArcTan function. We may solve this problem by importing it from an external library, or by supplying it ourselves. (Both ways should be pursued in this tutorial).

The last two data types are a bit different from the preceding: «Memo» is not very useful when used outside of a database, and the arrays cannot be used in databases.

 && example of compilation command
 && A:>c:hb32binhbmk2 -quiet -oc:hbcodetest.exe test.prg -run
 
 && please note that this example has not a MAIN function
 
 && an example of string concatenation
 ? "Hello" + " " + "World!"
 
 && let us do now a few numerical computations, integer numbers are a good starting point
 ? 5+13
 ? 12*8
 
 ? 3/2
 SET DECIMALS TO 15
 sqrt2=sqrt(2) && computing the square root of 2...
 ? sqrt2 && ... and printing it
 
 && ? caporetto 
 && if the line above was not commented, the compiler would issue the two following lines
 && Error BASE/1003  Variable does not exist: CAPORETTO
 && Called from TEST(8)
 
 && as xBase is not good at history, let us revise it: http://www.historyofwar.org/articles/battles_caporetto.html,  http://www.firstworldwar.com/battles/caporetto.htm
 && we can then assign the correct date to this war
 caporetto := ctod("10-24-1917")

 a := date() && system date
 ? a + 1 && will print tomorrow's date 
 ? a - caporetto && this will tell us how many days have passed since Caporetto's battle (difference between two dates)
 
 SET DECIMALS TO 2
 ? (a - caporetto) / 365
 ?? " years have passed since Caporetto's battle"
 
 ? 1+1=3
 && it will print ".F.", that is, "FALSE" (of course...)
 
 && The following two instructions should be discussed to expand on the subject of operator precedence
 ? 1/2+2^3*sqrt(25)-3^2
 ? 1/2+2^3*(sqrt(25)-3^2)

The function SQR has been eliminated from Harbour and replaced by SQRT. Trying to use it will result in a linker error «undefined reference to ‘HB_FUN_SQR'».

From the following example (which runs) we see that Harbour is a weakly typed programming language: a variable, such as a in our example can be a number, and then become a string of text.

a := 1+1
? a
a := "abc"
? a

There is a problem: if the variable type changed and the programmer did not get aware of it he may issue some instruction that will cause an error at run time. If we had another line of code

in the program above, Harbour will attempt to add the number 1 to the string «abc», and the result will be the error

Error BASE/1081 Argument error: +.

Strings[edit | edit source]

Strings are essentially a list of characters. They are written between double quotes (eg. «Hello»). Note the difference:

123       => a number
"123"     => a string

Let’s see how to use the function Stuff() to change a character within a string:

sTest:="fun"
?sTest, STUFF(sTest,2,1,"a")
&& => fun fan

Here is a list of the most commonly used functions for handling strings:

Lower()   Convert uppercase characters to lowercase
Upper()   Converts a character expression to uppercase format
Chr()     Convert an ASCII code to a character value
Asc()     Convert a character to its ASCII value
Len()     Return the length of a character string or the number of elements in an array
At()      Return the position of a substring within a character string

Nevertheless in Clipper and Clipper Tools library can also be found very curious functions such as these:

AsciiSum()   Finds the sum of the ASCII values of all the characters of a string
Soundex()    is a character function that indexes and searches for sound-alike or phonetic matches
CHARONE()    Search and remove repeating characters
CHARONLY()   Remove non-standard characters
CHAROR()     "OR" bytes in a string

Let’s see what we can do with these functions.

We show the ASCII codes (http://www.asciitable.com/) corresponding to the keys pressed by the user, concluding the program when ESC is pressed.

#include "Inkey.ch"
DO WHILE .T.
WAIT "" TO cChar
?? " ", Asc( cChar )
IF ( LastKey() == K_ESC )
EXIT
ENDIF
ENDDO

inkey.ch is the eader file for Inkey() function, which serves to obtain the following key code from the keyboard buffer.

Other Considerations about the Classification of Data Types[edit | edit source]

A first classification of data types divides them into simple (or scalar) types and structured (or composite, or aggregate or compound) types.

In xBase the simple data types are numbers, logical values, strings and dates, that is, the types which can be field types in a database table. Memos are not, since they are a pointer to an external file.

Scalar data types can be composed to build up structured data types: arrays, associative arrays (hash tables), tables or databases (which are a «data type» which is stored on a disk). w:Primitive_data_type

Code blocks and objects are special data types.

Operators and Precedence[edit | edit source]

&& First we print the values of two expressions with the exponentiation operator
? 3**3**3 && is 19683
? 3**(3**3) && is 7625597484987

&& Then we let our compiler tell us if they are the same
? 3**3**3 = 3**(3**3) && result is .F.

&& We've a look at how our compiler deals with overflow and underflow...
? 9**9**9
&& ***********************
? 1/9**9**9
&& 0.00
? -(9**9**9)
&& ***********************

We see in this example that the exponentiation operator ** is left-associative (as opposed to mathematics where exponentiation is a right-associative operation).

The fact that 3**3**3 and 3**(3**3) give two different results means that parenthesis alter the operator precedence: whatever is enclosed in parenthesis is evaluated first.

Even when the operation is left-associative, the result of 9**9**9 is quite a «large» number
(196627050475552913618075908526912116283103450944214766927315415537966391196809 to be precise, as you can easily check — maybe using some arbitrary precision calculator program, such as GNU bc, which is available on every Linux distribution and as a download for Windows at http://gnuwin32.sourceforge.net/packages/calc.htm — or by hand spending only some weekend time) which exceeds the resources Harbour allocates for a number (which is called overflow) and it, therefore, prints 23 times a * to indicate this error. It also gives zero (0.00) if we try to compute its reciprocal (which is called underflow). Overflow and underflow errors happen when the result of a computation is, respectively, too big or too small to be represented with the number of bits a compiler has allocated for the variable in which we’re trying to store it in.

The same happens with dates. What it the result of

date()-1000000

(subtracting 1 million of days from the current date)? Let us see:

&& today my outputs are:
?date()
&& ==> 05/15/19
?date()-365000 && more or less 1000 years
&& ==> 01/13/20
set century on && we change an option...
?date()-365000 && ... and try ageing
&& ==> 01/13/1020
?date()-1000000 && more or less 2700 years (i.e. the results should be around 700 B.C.)
&& ==> 00/00/00
?ctod("31-12-9999")+1
&& ==> 00/00/00

Here, the last two outputs («00/00/00») indicate invalid dates, just as the rows of 23 asterisks seen above indicate invalid numeric results. Acceptable dates are those that can be stored in a dBase table (ie a .dbf file) and in these files a date is a string of 8 characters in the «YYYYDDMM» format (4 characters for the year, 2 for the month and 2 for the day). Consequently, negative years (before Christ) or with more than 5 digits are not accepted.

Harbour displays the year with only two digits unless we change its behavior with a SET command and gives wrong results with these large number of years. The reason is simple: in a database application (inventory management, reservation systems) we won’t have to deal with intervals of centuries and Harbour’s routines for handling dates don’t work correctly if we try to do that. In other fields, such as w:Archaeoastronomy this is the case and those who do deal with those problems (e.g. checking the precision of the alignment of the Winter solstice sunrise at Karnak in 2000 B.C. or the megalithic alignments) use their special routines for the computation of the dates.

There is another quandary when doing computation with computers. Look:

store 7 to n && an alternate way of an assignment (dates back to dBase II)
?sqrt(sqrt(n))^2^2=n
&& the result is .F.
set decimals to 15
?sqrt(sqrt(n))^2^2
&& 7.000000000000003

Now, if we extract the square root twice from a number and then square the result twice we should have the starting number. In fact, computers are not so precise and checking for the equality of two floating-point numbers can give unexpected results.

If you want to learn more you could have a look at What Every Computer Scientist Should Know About Floating-Point Arithmetic at https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html (which is part of a Sun Microsystems book entitled Numerical Computation Guide), and the Decimal Arithmetic FAQ at http://speleotrove.com/decimal/decifaq.html.

Fortunately, the precision of the variables used in xBase languages ​​and the fact that in common business applications square roots, logarithms and other mathematical operations that cause loss of precision are rather rare, are circumstances that mitigate the problem.

SET OPTIONS
We’ve seen SET DECIMALS TO n and SET CENTURY ON/OFF commands.
But in fact there are many options which can be set.
The SETMODE(<nRows>, <nCols>) function is particularly useful when using hbrun or xbscript: its purpose is to determine the size of the window.

Boolean Algebra & Flow Control[edit | edit source]

We can print the result of a comparison, which is a Boolean value (represented as .T. or .F.), but they are useful with special words in order to branch or repeat the execution of one or more instructions.

We have a Boolean expression when its result is true (whose xBase symbol is .T.) or false (.F.). The easiest way to get a Boolean result is to use a comparison (relational) operator: =, ==, !=, <>, #, >, <, >=, and <=.
Always remember the difference between the comparison operators = (equal), == (exactly equal) and the assignment operator :=.

Actually, the «real» (mathematical) definition of a Boolean expression is different from what is stated in the last paragraph. A «real» Boolean expression would contain only the two Boolean values .T. and .F. and the Boolean operators (.AND., .OR., .NOT.).

Boolean Algebra is applied to electronic digital circuits since the work of Claude Shannon in 1937. See http://www.allaboutcircuits.com/textbook/digital/chpt-7/introduction-boolean-algebra/ (and the successive pages of that online textbook) to have an idea of what Boolean Algebra means when it’s applied to bits within a circuit (including a microprocessor). Here we’re using it at a much higher level.

Consider Hamlet, Act 3, Scene 1: «[…]To be, or not to be? That is the question—
Whether ’tis nobler in the mind to suffer
The slings and arrows of outrageous fortune…». If Prince Hamlet asked Boole (but he could not, as it is set in the 14th or 15th century whereas Boole was born in 1815), his reply would have certainly baffled him. Why?

to_be=.T. && is it true?
?to_be .OR. .NOT. to_be
&& .T.
to_be=.T. && is it false?
?to_be .OR. .NOT. to_be
&& .T.

As Harbour told us, in Boolean algebra, the answer is «true». Have a look at this page: https://vicgrout.net/2014/07/18/to-be-or-not-to-be-a-logical-perspective/.

Conditional execution[edit | edit source]

A number of graphical ways have been developed for seeing how a program’s flow control is transferred: these include flowcharts (https://www.lucidchart.com/pages/what-is-a-flowchart-tutorial), data flow diagrams (https://www.lucidchart.com/pages/data-flow-diagram), Nassi-Shneiderman diagrams and the JSP and JSD diagrams by Michael A. Jackson (which is almost certainly not the first Michael Jackson you’ll think of).

The following example gets a number from the keyboard and prints it. If the number is 0 it comments that value (I presented this example as a typical nihilist programming). The flowchart shows why conditional execution is sometimes called bifurcation.

Flowchart of a simple bifurcation

Function MAIN()
LOCAL number
INPUT "Key in a number: " TO number
IF number = 0
?? "Congratulations, you keyed the fabolous number "
ENDIF
? number
RETURN

This example prints two different comments, whether the condition of the remainder of the division of the number supplied by 2 is, or is not, 0.

Function MAIN()
LOCAL number
INPUT "Key in a number: " TO number
IF number % 2 = 0
   ? "You keyed in an even number"
ELSE
   ? "You keyed in an odd number"
ENDIF
RETURN

This example shows that more than a command can be executed.

Function MAIN()
LOCAL number
INPUT "Key in a number: " TO number
IF number % 2 = 0
   ? "You keyed in an even number"
   ? "I can prove it:"
   ? "the result of ",number," % 2 = 0 is ", number % 2 = 0
ELSE
   ? "You keyed in an odd number"
   ? "I can prove it:"
   ? "the result of ",number," % 2 = 0 is ", number % 2 = 0
ENDIF
RETURN

This example adds another keyword, ELSEIF, to show that the choices are not necessarily dichotomic. This is a chained conditional. Only one of the branches will be executed.

function MAIN
LOCAL nNumber := 0
//
INPUT "Key in a number: " TO nNumber
//
?? "Your number is "
IF nNumber < 50
? "less than 50"
ELSEIF nNumber = 50
? "equal to 50"
ELSE
? "greater than 50"
ENDIF

The following example checks whether the system time is earlier than 18 (6 p.m.) and prints a greeting appropriate to the time of day.

   ? Time()
   // CToN source is numconv.prg, library is libct.
   IF CToN( SubStr( Time(), 1, 2 ) ) < 18
      ? "Good day"
   ELSE
      ? "Good evening"
   ENDIF

There are three logical operators: .AND., .OR., and .NOT.

Here is an example with a rather long condition, coordinating more comparisons with .OR. operators. The example is terribly stupid, but it shows how a semicolon allows you to continue an instruction on the following line.

WAIT "Key in a letter: " TO char
IF  char = "a" .OR. char = "A" .OR. char = "e" .OR. char = "E" .OR. ;
         char = "i" .OR. char = "I" .OR. char = "o" .OR. char = "O" .OR. ;
         char = "u" .OR. char = "U"
? char, " is a vowel"
ELSE
? char, " is not a vowel"
ENDIF

This same thing is however achieved in a more concise way using the substring comparison operator $ (or regular expressions, an advanced topic that we will see later).

   WAIT "Key in a letter: " TO char
   IF  char $ [aeiouAEIOU]
      ? char, " is a vowel"
   ELSE
      ? char, " is not a vowel"
   ENDIF

Looping[edit | edit source]

DO WHILE, EXIT, LOOP, ENDDO are keywords used To repeatedly execute a series of statements (loop body) while a condition is true (i.e. its result is .T.).

Loops come in several flavours: the pre-tested loop, the post-tested loop, and the definite iteration, which is done via a count-controlled loop (usually called a for loop). In practice, we may have a middle-tested loop as well, but no specific syntax for it… we need to put an EXIT statement within an already existing loop body to get this one.
The next program we will key in is of some interest for the mathematicians (Real Programmers aren’t afraid of maths, do you know this famous adage?)

Here is it:

 && Function MAIN LOCAL number, sum, n 
 && An anonymous contributor renamed the variable "num" into "number", increasing this short program readability, but the line above would give
 && Error E0030  Syntax error "syntax error at 'LOCAL'"
 Function MAIN
 LOCAL number, sum, n
 CLS 
 ? "Let's sum up the first n odd numbers." 
 INPUT "How many numbers shall I sum up? " TO n 
 sum=0 
 number=1 
 DO WHILE number <= 2*n    
  sum=sum+number    
  number=number+2 
 ENDDO 
 ? "The sum requested is ", sum

As you can see, this looping statement is similar to the IF statement: both of them are ended by a END-corresponding statement, both of them contains a logical espression.

This looping statement will continue until its condition remains true (will evaluate to .T.).

The two instructions it repeats are sum=sum+num and num=num+2. The second is fundamental: if it wasn’t there or was wrong (for example if you keyed in num=num/2), the condition would not evaluate to .F. and the program would not stop its execution (this is called infinite looping). When this happens to you, press the keys Ctrl and C at the same time. This should convince the computer to give his attention to you instead of running the loop.

The programs above is a nice example of how an extremely methodical calculator without any creativity would attack the problem of summing up the first n odd numbers. Notes about the creative approach to it can be found at this address: http://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/ (along with the usual anedocte about Gauss’ show off about it in elementary school).

The WHILE looping statement is said to have the control expression in its head, opposed to the Pascal REPEAT-UNTIL looping statement (a post-test loop) which has the control of the condition in its tail (these are the Italian computer science slang for pre- and post- tested loops, aren’t they funny?). How does the xBase/Clipper say REPEAT-UNTIL? It doesn’t. Here is how to emulate it (copied & pasted from the Norton Guide):

LOCAL lMore := .T.
DO WHILE lMore
loopbody
lMore := condition
ENDDO

As you see, we first set a variable to be true, enter the loop, and specify the condition at the end of the loop, to make sure its body is executed at least once.

Here is an example, equivalent to the one at the pascal_repeat_until_loop page in tutorialspoint.com.

LOCAL a := 10
LOCAL lMore := .T.

   DO WHILE lMore
      ? 'value of a: ', a
      a := a + 1
      lMore := ( a != 20 )
   ENDDO

But the code above changed the condition. If we didn’t want this to happen, we can simply negate the condition we’d use in the Pascal code:

repeat loopbody until condition

becomes then:

LOCAL a := 10
LOCAL lMore := .T.

   DO WHILE lMore
      ? 'value of a: ', a
      a := a + 1
      lMore := .NOT. ( a = 20 ) && or, in alternative, lMore := ! ( a = 20 )
   ENDDO

Let us now see this kind of loop:

 DO WHILE .T. 
 ? "I won't stop." 
 ENDDO

This loop prints «I won’t stop.» as long as ‘true’ is… true. It is thus called an infinite loop because the ending condition will never be satisfied. It is the first example of control flaw studied in computer science classes. By definition, you incur in an infinite loop every time you specify a tautology as the condition to be checked. It is not always obvious to detect this and other control flaws and errors — it is indeed a process that involves the use of a specific piece of software called a debugger.

Counter-controlled Loops, and Nested Loops[edit | edit source]

In this section, we will see how to use FOR loops to print multiplication tables, how to nest loops, how to format output on the console screen and the importance of indenting code to improve readability.

The FOR…NEXT construct (counter-controlled loop) is useful when we know how many times we want the loop body be executed. We shall now use it to print out and revise multiplication tables.

 CLEAR
 FOR I := 1 TO 8
   FOR J := 1 TO 8
    ?? I*J
   NEXT
 NEXT

(Please note in this example we have a loop inside the body of another loop: this is called a nested loop).
Well, this works, but its output is not very nice…
Moreover, it is customary to print the multiplication tables up to 10, since we’re using a decimal numeration system… let us try it again!

 CLEAR
 FOR I := 1 TO 10  
   FOR J := 1 TO 10   
     @i,j*4 SAY  I*J PICTURE "999"  
   NEXT
 NEXT

this way we can print it much prettier… by the way, when nesting loops and branching statements, it becomes important to arrange the indentations in order to make the program easier to read… in The Oasis are available «source code beautifiers» such as dst314.zip. Harbour gives us the hbformat tool, https://vivaclipper.wordpress.com/tag/hbformat/.

PICTURE «999» is the instruction to specify we want the output format — as we specified three digits, the numbers in output will be printed as if they were three digits long, thus aligning them in our multiplication table.

As a second example of nested loops, the following is one of the most irritating programs I’ve ever written. It asks the user for an opinion and then always responds its contrary. It even quits when the user says he has more to tell him and keeps asking for input when the user says he has nothing else to add. Since it is particularly difficult for a program to answer the opposite of the user’s assertions, this program simply prints the input string reversed, using the SubStr function (SubStr(<cString>, <nStart>, [<nCount>]) —> cSubstring — extract a substring from a character string cString, at index nStart with length nCount).

User input is obtained through the ACCEPT command (a COBOL reminiscence), and the control flow uses a DO WHILE loop (from FORTRAN) and a FOR … TO … STEP loop (from BASIC).

LOCAL cContinue := "N"
DO WHILE cContinue = "N"

ACCEPT "What's your opinion? " TO cOpinion
?""
?? "NO!! According to me, on the contrary: "
FOR i := Len( cOpinion ) TO 1 STEP -1
??SubStr( cOpinion, i, 1 )
NEXT

WAIT "Tell me, do you have any other opinions to discuss with me? (Y/N) " TO cContinue
cContinue := Upper( cContinue )
IF cContinue = "N"
? "Ok, then. "
ELSE
? "In this case let me go."
ENDIF
ENDDO

How do we deal with such an awkward customer? Just try typing «remmargorp revelc yrev a era uoy» and the solution will be clear. In Italy there is an expression to call a person who always contradicts his interlocutors: he is called a «bastian contrario». They do work like this program.

& — the Macro Evaluation Operator[edit | edit source]

Consider this short piece of code:

 i = 2
 myMacro = "i + 10"
 i = &myMacro && will execute "i+10"
 ? i          && will print "12"

The & is an operator that will evaluate (runtime compilation) an expressions and will permit text substitution within strings (see https://harbour.github.io/ng/c53g01c/ng110bc2.html). Let’s make a simple calculator using it.

ACCEPT "Please enter the first number: " TO cNumber1
ACCEPT "Please enter the second number: " TO cNumber2

WAIT "Enter operation: " TO cOperation && we get a single character for the operation

? Number1+cOperation+Number2+"="       && we print the operation and an equal sign
? &(Number1+cOperation+Number2)        && and the result on the following line, evaluating the string as it appeared on the line above

Here is an example of interaction with this program:

Please enter the first number: 12
Please enter the second number: 23.5
Enter operation: -
12-23.5=
       -11.5

Arrays[edit | edit source]

An array is an ordered grouping of data, whose elements are identified by a number called an index. In many programming languages ​​the indices (or «indexes») start at 0, but in xBase they start from 1. Since in mathematics the indices are written next to the variable slightly below the line, sometimes they are called subscripts and, for this reason, arrays are sometimes called subscripted variables.

Consider this first example of arrays. We create two arrays, one with the names of the months of the year and one with their duration in days, and then we print them in an orderly manner. The same result can be obtained in a much more elegant way using associative arrays.

 && C:hb32binhbmk2 -quiet -oc:hbcodemonths.exe months.prg -run
 DECLARE months [12]
 ? LEN (months) && the function LEN() shows how many items an array has
 && We shall now load some data into our arrays
 PRIVATE month_names: = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
 PRIVATE months: = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} && for simplicity we do not consider leap years
 
 && Let us make some output (using a FOR loop - see below)
 FOR I: = 1 TO LEN (months)
 ? month_names [i], "is", months [i], "days long."
 NEXT

In the next example we show that xBase has high-level support for dynamic arrays (implementing them in a low level language like C requires pointer arithmetic and memory management functions).

Note: This example will reappear many times in these notes. Often when we will introduce a new feature of the language we will write a new program which does the same thing of this program in a different way. It is one of the best pedagogical advice I can give you. Since I don’t provide you with exercises, think of different ways of redoing some program using new language features, i.e. just to give you an idea: how difficult is it to redo the program that shows the multiplication tables on the screen using code blocks?

&& compile with ''hbmk2 averaging.prg -lhbmisc''
PROCEDURE MAIN

   LOCAL n, sum := 0, average    && let's initialize the variables
   aNumbers := {}                && and an array without elements

   ? "enter a list of integer numbers, and a non-number when you are finished"
   WHILE .T.                     && we begin an endless loop
      ACCEPT "next element: " TO item
      IF IsDec( item )           && the function IsDec() from the libmisc library checks if we have entered a number
         AAdd ( aNumbers, item ) && if we did, then we add the number as a new element to the array
         sum := sum + &item      && (and we update the sum of the elements in our array)...
      ELSE
         EXIT                    && ...if we did not, we quit this loop
      ENDIF
   ENDDO

   average := sum / Len( aNumbers ) && we compute the average of the values in the array

   ?
   ? "to average the array you must correct each element by adding to it the corresponding value below"
   ?
   FOR n := 1 to LEN ( aNumbers )
      ?? AVERAGE - aNumbers[n]
   NEXT
RETURN

Here is the list of functions in hbmisc: https://harbour.github.io/doc/hbmisc.html.

The program above is not very satisfactory: due to the use of the IsDec() function it can treat only positive integer numbers. What if we’d like it to accept numbers like -8 and 2.78? Three solutions come to mind offhand: write ourselves function that checks if the string represents a number (an improved version of IsDec()), test input using regular expressions, using xBase functions for error handling. We will use this last technique in the next section of the tutorial.

  FOR EACH n in aNumbers        && FOR EACH is a more modern control flow statement Harbour syntax
     ?? AVERAGE - &n
  NEXT

In addition to a function to add elements to an array we have one to delete them:

 aFruitSalad:={"peaches", "plums"}
 AAdd ( aFruitSalad, "onions" ) && we add onions
 ADel(aFruitSalad, 3) && on second thought, onions don't mix well: we remove them
 local f; for each f in aFruitSalad; ?? f," " ;  next && we print our ingredients
 && => peaches  plums  NIL
Harbour provides a function, hb_ADel, which accepts a third Boolean element and (if it's .T.) shrinks the array.

Multidimensional arrays are made by nesting arrays within other arrays.

Error Handling (the Clipper Way)[edit | edit source]

All of the programs showed up to this point will fail and show a runtime error if the user entered an unexpected input (in simple words, they crash). Programs called «robust» don’t. Checking the conditions in which errors can occur and take countermeasures to prevent crashes is a job that was normally done with if-then-else.

BEGIN SEQUENCE … END[SEQUENCE] is a control structure that executes some code and optionally some statements if the code produced an error. In our example if the conversion of the user input into a number generates an error, we will call EXIT to leave the while loop and continue our program.

PROCEDURE MAIN

   LOCAL n, sum := 0, average    && let's initialize the variables
   local bError := errorblock ( { |oError| break ( oError ) } )
   aNumbers := {}                && and an array without elements

   ? "enter a list of integer numbers, and a non-number when you are finished"
   WHILE .T.                     && we begin an endless loop
      BEGIN SEQUENCE
      ACCEPT "next element: " TO item
         AAdd ( aNumbers, &item ) && if we did, then we add the number as a new element to the array
         sum := sum + &item      && (and we update the sum of the elements in our array)...
      RECOVER
         EXIT                    && ...if we did not, we quit this loop
      END SEQUENCE
   ENDDO

   average := sum / Len( aNumbers ) && we compute the average of the values in the array

   ?
   ? "to average the array you must correct each element by adding to it the corresponding value below"
   ?
   FOR n := 1 to Len ( aNumbers )
      ?? average - aNumbers[n]
   NEXT
RETURN

Clipper 5 (C5) provided four classes:

Error           Provides objects with information about runtime errors
Get             Provides objects for editing variables and database fields
TBrowse         Provides objects for browsing table-oriented data
TBColumn        Provides the column objects TBrowse objects

The Clipper 5.3 Norton Guide lists these classes:

Error class       Provides objects with information about runtime errors
CheckBox class    Provides objects for creating checkboxes
Get class         Provides objects for editing variables and database fields
ListBox class     Provides objects for creating list boxes
MenuItem class    Provides objects for creating menu items
PopUpMenu class   Provides objects for creating pop-up menus
PushButton class  Provides objects for creating push buttons
RadioButto class  Provides objects for creating radio buttons
RadioGroup class  Provides objects for creating radio button groups
Scrollbar class   Provides objects for creating scroll bars
TBColumn class    Provides objects for browsing table-oriented data
TBrowse class     Provides the column objects TBrowse objects
TopBarMenu class  Provides objects for creating top menu bars

Functions and Procedures[edit | edit source]

A function is a piece of code that returns a result every time it is called. Let us consider a function to convert Celsius into Fahrenheit (the same function is provided by libct, but we redo it for educational purposes):

FUNCTION cels2f( tempCelsius )
tempFahrenheit := (tempCelsius*1.8 + 32)
RETURN tempFahrenheit

FUNCTION MAIN()
? cels2f(100)
? cels2f(0)

But have a look at the following:

/**
 * by choosing better variable names this function becomes self-explanatory
 */
function convert_Celsius_to_Fahrenheit(Celsius_temperature)
  return Celsius_temperature * 1.8 + 32

FUNCTION MAIN()
? convert_Celsius_to_Fahrenheit(100)
? convert_Celsius_to_Fahrenheit(0)

Consider this example of use for the function HB_Random():

PROCEDURE Main
 // Random number between 0.01 and 0.99
 ? HB_Random()
 // Random number between 0.01 and 9.99
 ? HB_Random(10)
 // Random number between 8.01 and 9.99
 ? HB_Random(8,10)
 // Random integer number between -100 and 100
 ? HB_RandomInt(-100,100)
 RETURN

A good function would function as a «black box», that is you can use it without worrying about how it internally works.
An example usually given at this point is that of driving a car: you can use it without worrying about how the engine works (do you know anybody which looked at the pistons of their new car before buying it?). Someone else designed the engine. But there may be problems: if we change our Celsius into Fahrenheit function as follows

FUNCTION cels2f( tempCelsius )

   tempFahrenheit := (tempCelsius*1.8 + 32)
   number := number + 1

   RETURN tempFahrenheit

FUNCTION MAIN()

   number := 0
   ? cels2f( 100 )
   ? cels2f( 0 )
   ? number

we’ll get a side effect. This program output is

      212.0
       32.0
        2

That is, our new function did not only return a value, it also increased by 1 the variable number.

The Clipper Norton Guides read, «A procedure in CA-Clipper is the same as a user-defined function, with the exception that it always returns NIL» (http://www.oohg.org/cl53/ng10a778.html), thus a procedure is really just a type of function that relies on these side effects to get something done.

The utility of functions is that they improve program readability, maintainability. Splitting a program into functions is a good design approach, which lets breaking a complex problem into smaller, simpler problems (top-down).

Harbour has four different kinds of subroutines/subprograms:

  • the FUNCTION and
  • the PROCEDURE (which is a FUNCTION with no return value),
  • the method (which has no associated keyword, works like every object-oriented programming language) and
  • the code block.

Why the Main Function?[edit | edit source]

The main function is the designated start of a program written in C or C++ (Java uses a static main method). Since a procedure is a function that returns NIL, we can have a procedure main instead of a function main in our program. With Harbour it is not necessary anymore.

Another characteristic of variables: scope identifiers[edit | edit source]

Variables have a name, a type, a scope and a lifetime (http://www.dbase.com/Knowledgebase/dbulletin/bu05vari.htm) which may be explicitly declared as (list below copied verbatim from w:Harbour (software)):

  • LOCAL: Visible only within the routine which declared it. Value is lost upon exit of the routine.
  • STATIC: Visible only within the routine which declared it. Value is preserved for subsequent invocations of the routine. If a STATIC variable is declared before any Procedure/Function/Method is defined, it has a MODULE scope, and is visible within any routine defined within that same source file, it will maintain its life for the duration of the application lifetime.
  • PRIVATE: Visible within the routine which declared it, and all routines called by that routine.
  • PUBLIC: Visible by all routines in the same application.

They do not make sense before we work with functions and procedures.

/* Work on the following.
 * hbformat was run on this piece of code
 * need to provide comments, nest more functions and procedures to help figuring what goes on with scope modifiers
 */

STATIC x := 9

   ? x
   A()
   ? x
   B()
   ? x
   C()
   ? x
   D()
   ? x
   E()
   ? x

PROCEDURE A

   LOCAL x := 10

   ? "x from A=", x

   RETURN

PROCEDURE B

   PRIVATE x := 5

   ? "x from B=", x

   RETURN

PROCEDURE C

   PUBLIC x := -1

   ? "x from C=", x

   RETURN

PROCEDURE D

   ? "x from D before updating value=", x

   x := 12

   ? "x from D=", x

   RETURN

PROCEDURE E

   ? "x from E=", x

   RETURN

On running this, we get a strange output:

         9
x from A=         10
         9
x from B=          5
         9
x from C=          -1
         9
x from D before updating value=          -1
x from D=         12
         9
x from E=         12
         9

This program sets a variable x and five different procedures, A, B, C, D, E. The first three procedures define a variable x within themselves, assign it a value and print it. The fourth function assigns a new value to some variable named x without declaring it. The fifth function shows the value of some x variable, which happens to be the value of the fourth x variable. The main fact to remember here is that two variables are not the same, even if hey have the same name, provided they have different scopes and this feature is called shadowing.

x := 9

   ? x
   A()
   ? x
   B()
   ? x
   C()
   ? x
   D()
   ? x
   E()
   ? x

PROCEDURE A

   LOCAL x := 10

   ? "x from A=", x

   RETURN

PROCEDURE B

   PRIVATE x := 5

   ? "x from B=", x

   RETURN

PROCEDURE C

   PUBLIC x := -1

   ? "x from C=", x

   RETURN

PROCEDURE D

   ? "x from D before updating value=", x

   x := 12

   ? "x from D=", x

   RETURN

PROCEDURE E

   ? "x from E=", x

   RETURN
         9
x from A=         10
         9
x from B=          5
         9
x from C=         -1
        -1
x from D before updating value=         -1
x from D=         12
        12
x from E=         12
        12

As static variables seem to require further informations (they work like C static variables), here is an example:

// adapted from "An example of static local variable in C" (from Wikipedia Static_variable)
FUNCTION func()
	static x := 0
	/* x is initialized only once, the first time func() is called */
	x := x+1
	? x
RETURN

FUNCTION main() 
	func() // calls func() a first time: it prints 1
	func() // value 1 was preserved; this time it prints 2
	func() // prints 3
	func() // prints 4
	func() // prints 5

See pascal_variable_scope in tutorialspoint.com and http://aelinik.free.fr/c/ch14.htm

Variable scope is a foretaste of object oriented programming, in the sense that it anticipates some encapsulation concepts.

The search for the Ludolphine[edit | edit source]

Part 1: Using the Clipper Tools (CT) Library[edit | edit source]

If you checked the list of functions you will have noticed that the xBases have no trigonometric functions. Not that in general they miss them: these languages are targeted database applications such as «accounting systems and airline reservations systems» (see w:Database application. ) in which trigonometric functions are not really important. But we now ask ourselves how to compute an approximation to the Ludolphine number, π (more information on this «search» at http://www.mathpages.com/home/kmath457.htm), We can do it using the CT library (see http://vouch.info/harbour/index.html?hbct.htm), or importing the C standard library function atan.

 && compile with ''hbmk2 computepi.prg -lhbct''
 PROCEDURE MAIN
 SET DECIMAL TO 14
 ? 4 * ATAN (1)

Part 2: Mixing C and Harbour Code[edit | edit source]

We get the idea from Harbour for beginners by Alexander Kresin (http://www.kresin.ru/en/hrbfaq_3.html).

  #pragma BEGINDUMP
  #include <extend.h>
  #include <math.h>
   HB_FUNC( ATAN )
   {
      double x = hb_parnd(1);
      hb_retnd( atan( x ) );
   };     
 #pragma ENDDUMP
 SET DECIMAL TO 14 
 ? 4 * ATAN (1)

It must be noted that the extend.h file (* Compatibility header file for CA-Cl*pper Extend System) contains this warning:

/* DON'T USE THIS FILE FOR NEW HARBOUR C CODE */
/* This file is provided to support some level of */
/* Harbour compatibility for old Clipper C extension code */

In fact this example is here only to consider how the open source cross-compilers (Harbour in this case) extend themselves with C library functions, which gives them a lot of flexibility. Not that computing π would be useful in itself for the average xBase programmer (by the way the CT library contains a function to directly compute π). We shall not concern ourselves with a method to do that, but move to something more conventional.

The FizzBuzz interview question: critical thinking and algorithms, with an introduction to table trace and the concept of flag[edit | edit source]

FizzBuzz is a little problem that is quite often asked in job interviews. A good discussion is found at the page https://micheleriva.medium.com/about-coding-the-fizzbuzz-interview-question-9bcd08d9dfe5. As always there are many ways of solving even a simple problem like this, that can be worded as follows,

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

The first thing one should do is to think as many ways as possible to solve the problem. Also, you may be asked to show that your solution works without having access to a computer: the way of doing so is also one of the best ways of reading a program written by someone else, and even of checking the program you yourself wrote. You take a piece of paper and a pencil and check how the program instructions change the variables and what input they produce by arranging the content of the variables in a table and behaving like the computer. I heard this being called called w:Trace table, tracing an algorithm, hand tracing, dry running. For the moment I point you to a tutorial on YouTube which should give you a taste of how the thing works: https://www.youtube.com/watch?v=UbANyxE7pGE (Trace tables tutorial GCSE Computer Science).

Take for example the following trivial solution of FizzBuzz:

FOR I = 1 TO 100
    FLAG = 0
    IF I % 5 = 0 
        FLAG = 1
        ?? "Fizz"
    ENDIF
    IF I % 3 = 0 
        FLAG = 1
        ?? "Buzz"
    ENDIF
    IF FLAG = 0 
        ?? I
    ENDIF
    ?? ", "
NEXT

This example introduces a flag variable, that is, a variable that is checked to know whether the program executed a particular instruction or set of instructions.

Sorting Algorithms[edit | edit source]

Sorting data is an important application in computer science. In fact, in the ancient times (which means in the 50s), an important component of a computer was a piece of hardware called a Card Sorter, which was used to sort punched cards, see one at http://www.columbia.edu/cu/computinghistory/sorter.html, but the Census Machine built by Hollerith in the 1880’s already had its own sorter box, and the French word for computer, ordinateur, can even be literally translated to sorter.

Let’s start with a piece of code

   // we'll declare and load random numbers from 1 to 100 in an array
   DECLARE arrayToSort [12]
   FOR I = 1 TO 12
      arrayToSort [I] = Int( HB_Random( 1,101 ) )
   NEXT

   // we review our array
   FOR I = 1 TO 12
      ?? arrayToSort [I]
   NEXT

   // we'll do Exchange Sort as described in http://www.ee.ryerson.ca/~courses/coe428/sorting/exchangesort.html
   // where there is also a nice animation showing how it works! :)
   for i := 2 TO Len(arrayToSort)
      for j := Len(arrayToSort) TO i step -1
         IF arrayToSort [j - 1] > arrayToSort [j] 
		TEMP := arrayToSort [j - 1]
		arrayToSort [j - 1] := arrayToSort [j]
		arrayToSort [j] := TEMP
	 ENDIF
      NEXT
   NEXT

   ?
   ? "Sorted array:"
   ?

   // we look at our sorted array
   FOR I = 1 TO 12
      ?? arrayToSort [I]
   NEXT

From the version above we can (and should) separate the sorting routine in a procedure, this way:

PROCEDURE ExchangeSort(array)
   // we'll do Exchange Sort as described in http://www.ee.ryerson.ca/~courses/coe428/sorting/exchangesort.html
   // where there is also a nice animation showing how it works! :)
   for i := 2 TO Len(array)
      for j := Len(array) TO i step -1
         IF array [j - 1] > array [j] 
		TEMP := array [j - 1]
		array [j - 1] := array [j]
		array [j] := TEMP
	 ENDIF
      NEXT
   NEXT
RETURN

FUNCTION MAIN
   // we'll declare and load random numbers from 1 to 100 in an array
   DECLARE arrayToSort [12]
   FOR I = 1 TO 12
      arrayToSort [I] = Int( HB_Random( 1,101 ) )
   NEXT

   // we review our array
   FOR I = 1 TO 12
      ?? arrayToSort [I]
   NEXT

   ExchangeSort(arrayToSort) // we call the procedure and pass to it our array called arrayToSort

   ?
   ? "Sorted array:"
   ?

   // we show the array is sorted
   FOR I = 1 TO 12
      ?? arrayToSort [I]
   NEXT

Usually the first sorting algorithm introduced (even in my high school textbook) is Bubble Sort, which is a bad choice. Here we use Exchange Sort, which is equally bad, but at least we vary a little.

Grasping Recursion[edit | edit source]

We have recursion when a function calls itself. The definition is really this simple.

Put like that, it doesn’t seem like a good idea, because it seems that a recursive function will trap the program in an infinite loop.
In reality a recursive function does not just call itself, but includes a criterion to stop doing it and provide some actual result.

A first example is the factorial function, of which we take a definition from a dictionary (https://www.dictionary.com/browse/factorial): « Mathematics. the product of a given positive integer multiplied by all lesser positive integers: The quantity four factorial (4!) = 4 ⋅ 3 ⋅ 2 ⋅ 1 = 24. Symbol: n!, where n is the given integer».

FUNCTION main
 ? factorial(10)
RETURN 0

FUNCTION factorial(n)
    IF n = 0
        RETURN 1
    ELSE
        RETURN n * factorial(n - 1)
    ENDIF
RETURN -1

Code blocks[edit | edit source]

https://github.com/vszakats/harbour-core/blob/master/doc/codebloc.txt

Sites around the Net say that Clipper 5 documentation called them unnamed assignable functions.

Let us get back at our Celsius to Fahrenheit temperature converting function:

FUNCTION cels2f( tempCelsius )
tempFahrenheit := (tempCelsius*1.8 + 32)
RETURN tempFahrenheit

and redo it as a codeblock:

Cels2F := { | celsius | Fahrenheit := (Celsius * 1.8 + 32) } // our first codeblock

? Eval(Cels2F,100)
? Eval(Cels2F,0)

In the first line we assigned a code block to a variable named Cels2F. The code block is comprised in braces. The first thing is a variable that is to be passed to the block, between vertical bars (|). More variables should be separated by commas. Then we can write the instructions (more than one should be separated by commas).

Later we use two times the Eval function giving it two arguments: the name we assigned to our codeblock and the parameter to pass it.
In addition to Eval, other functions can evaluate code block: AEval() and dbEval(). Ascan() and Asort() can be given code blocks to change their behavior.

As code blocks can’t contain commands, we can’t put a ? command in them, but have to use the corresponding QOut() function.

Command Line Arguments[edit | edit source]

Suppose that we wish to write a clone of the Unix cat command, which means that we will have a program to which we’ll pass a command line argument that is a file name and output the content of the file.

PROCEDURE MAIN(file)
    ? MEMOREAD(file)
RETURN

That’s it! In fact, it is quite limited, and it is more likely a clone of the DOS type command (or even of the CP/M type command!). Procedure This file’s procedure MAIN receives one argument, and gets it from the command line. Then passes it to the MEMOREAD function (description: Return the text file’s contents as a character string), and sends the result to the console output.

File Management[edit | edit source]

Accessing files can be done using low-level functions, which are: FOPEN(), FCREATE(), FWRITE(), FREAD(), FREASDSTR(), FERASE(), FERROR(), FSEEK(), FCLOSE() and FRENAME().

Harbour, however, provides functions that permit manipulating text files in a similar way to DBF files (https://vivaclipper.wordpress.com/tag/memoread/).

<⌃ | ☰

Less than—binary (Relational)

Syntax

Description

The less than () operator is a binary operator that compares two values of the same data type and returns true (.T.) if <exp1 is less than exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for «A» is 65 and the code for «Z» is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: False (.F.) is less than true (.T.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples

■  These examples illustrate how the less than operator (<)
   behaves with different data types:

   // Character
   ? "Z" < "A"                 // Result: .F.
   ? "ZA" < "A"                // Result: .F.
   ? "A" < "AZ"                // Result: .T.

   // Date
   ? CToD("12/12/88") < ;
      CToD("12/11/88")         // Result: .F.

   // Logical
   ? .F. < .T.                 // Result: .T.


   // Numeric
   ? 2 < 1                     // Result: .F.
   ? 1 < 2                     // Result: .T.

Platforms

Available on MS-DOS

See also

<=, <> != #, = (equality), ==, >, >=, $

<=⌃ | ☰

Less than or equal—binary (Relational)

Syntax

Description

The less than or equal (<= ) operator compares two values of the same data type and returns true (.T.) if exp1 is less than or equal to exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for «A» is 65 and the code for «Z» is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: False (.F.) is less than true (.T.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples

■  These examples illustrate how the less than or equal operator
   (<=) behaves with different data types:

   // Character
   ? "Z" <= "A"               // Result: .F.
   ? "ZA" <= "A"              // Result: .F.
   ? "A" <= "AZ"              // Result: .T.

   // Date
   ? CToD("12/12/88") <= ;
      CToD("12/11/88")        // Result: .F.


   // Logical
   ? .F. <= .T.               // Result: .T.

   // Numeric
   ? 2 <= 1                  // Result: .F.
   ? 1 <= 2                  // Result: .T.
   ? 1 <= 1                  // Result: .T.

Platforms

Available on MS-DOS

See also

<, <> != #, = (equality), ==, >, >=, $

<> != #⌃ | ☰

Not equal—binary (Relational)

Syntax

<exp1> <> <exp2>
<exp1> != <exp2>
<exp1> #  <exp2>

Description

The not equal ( <>) operator compares two values of the same data type and returns true (.T.) if exp1 is not equal to exp2 according to the following rules:

■ Character: The comparison is based on the underlying ASCII

code and is the inverse of the equal operator (=). This means that the comparison is sensitive to the current EXACT SETting. See the examples below.

■ Date: Dates are compared according to the underlying date

value.

■ Logical: False (.F.) is not equal to true (.T.).

■ Memo: Treated the same as character.

NIL: All values compared to NIL other than NIL return true

(.T.).

■ Numeric: Compared based on magnitude.

Examples

■  These examples illustrate how the not equal operator (<>)
   behaves with different data types:

   // Character
   SET EXACT ON
   ? "123" <> "12345"         // Result: .T.
   ? "12345" <> "123"         // Result: .T.
   ? "123" <> ""              // Result: .T.
   ? "" <> "123"              // Result: .T.
   SET EXACT OFF
   ? "123" <> "12345"         // Result: .T.
   ? "12345" <> "123"         // Result: .F.
   ? "123" <> ""              // Result: .F.
   ? "" <> "123"              // Result: .T.

   // Date
   ? CToD("12/12/88") <> ;
      CToD("12/12/88")        // Result: .F.

   // Logical
   ? .T. <> .T.               // Result: .F.
   ? .T. <> .F.               // Result: .T.

   // NIL
   ? NIL <> NIL               // Result: .F.
   ? NIL <> 12                // Result: .T.
   ? NIL <> "hello"           // Result: .T.

   // Numeric
   ? 2 <> 1                   // Result: .T.
   ? 1 <> 1                   // Result: .F.

Platforms

Available on MS-DOS

See also

<, <=, = (equality), ==, >, >=, $

= (assign)⌃ | ☰

Simple assign—binary (Assignment)

Syntax

Description

The simple assignment operator (=) assigns a value to a variable. It is identical in operation to the STORE command that initializes a single variable and must be specified as a program statement. The inline assignment operator (:=) is like the = operator except that you can specify it within expressions. If you specify the simple assign operator (=) within an expression, it is interpreted as the equality (=) operator.

Note: You cannot initialize a specific variable using the simple assign operator (=) in a declaration statement. Only the inline assign (:=) operator can be used for this purpose.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. At runtime, if no private or public variable exists with the specified name, a private variable is created. To assign a field variable with the = operator, you must declare the field variable name in a FIELD statement or refer to the field name prefaced by the FIELD-> alias or the name of the work area.

Examples

■  These examples are valid simple assignment statements:

   nValue = 25
   nNewValue = Sqrt(nValue) ** 5
   nOldValue = nValue

■  In this example, the two lines are equivalent:

   FIELD->CustAge = 20
   REPLACE CustAge WITH 20

Platforms

Available on MS-DOS

See also

= (compound assign), --, :=, ++, STORE*

= (compound assign)⌃ | ☰

Compound assignment—binary (Assignment)

Syntax

<idVar>  += <cString>         (concatenation)
<idVar>  += <nNumber>         (addition)
<idVar>  -= <cString>         (concatenation)
<idVar>  -= <nNumber>         (subtraction)
<idVar>  -= <dDate>           (subtraction)
<idVar>  *= <nNumber>         (multiplication)
<idVar>  /= <nNumber>         (division)
<idVar>  %= <nNumber>         (modulus)
<idVar>  ^= <nNumber>         (exponentiation)

Description

In addition to the simple and inline assignment operators (= and :=), there are a series of compound assignment operators that perform an operation then assign a value. They have the form:

idVar operator= exp

Each compound assignment expression is equivalent to the assignment expression:

idVar := ( idVar operator exp )

For each data type that supports an operator, the compound assignment operator performs the same operation before performing the assignment operation. The following table details all of the compound operators:

Compound Operators

    Operator     Defined as     Operations

    a += b       a := (a + b)   concatenation, addition

    a -= b       a := (a — b)   concatenation, subtraction

    a *= b       a := (a * b)   multiplication

    a /= b       a := (a / b)   division

    a %= b       a := (a % b)   modulus

    a ^= b       a := (a ^ b)   exponentiation

Note: The exponentiation operator (**) does not have a corresponding compound assignment operator. The exponentiation compound assignment operator is ^=.

Since the compound assignment operators are based on the inline assignment operator (:=), the operation returns the result of its operation as the value of the expression. This means you can use these operators within expressions just like the inline assignment operator (:=).

Examples

■  These examples use the compound addition and concatenation
   assignment operator:

   // Character (concatenation)
   LOCAL cString := "Hello"
   ? cString += " there"           // Result: "Hello there"

   // Date (addition)
   LOCAL dDate := CToD("12/12/90")
   dDate += 12                     // Result: 12/24/90

   // Numeric (addition)
   LOCAL nValue := 10
   ? Sqrt(nValue += 15)            // Result:  5.00
   ? nValue                        // Result: 25.00

■  These examples use the compound subtraction and concatenation
   assignment operator:

   // Character (concatenation)
   LOCAL cString := "Hello   "
   ? cString -= "There"            // Result: HelloThere

   // Date (subtraction)
   LOCAL dDate := CToD("12/24/90")
   dDate -= 12                     // Result: 12/12/90

   // Numeric (subtraction)
   LOCAL nValue := 10
   ? newValue := (nValue -= 5) ** 2       // Result: 25
   ? nValue                               // Result:  5

■  This example uses the compound multiplication assignment
   operator:

   LOCAL nValue := 10
   ? newValue := (nValue *= 5) + 100      // Result: 150
   ? nValue                               // Result:  50

■  This example uses the compound division assignment operator:

   LOCAL nValue := 10
   ? newValue := (nValue /= 5) + 100      // Result: 102.00
   ? nValue                               // Result:   2.00

■  This example uses the compound modulus assignment operator:

LOCAL nValue := 10
   ? newValue := (nValue %= 4) * 100      // Result: 200.00

   ? nValue                               // Result:   2.00

■  This example uses the compound exponentiation assignment
   operator:

   LOCAL nValue := 10
   ? newValue := (nValue ^= 3) + 50       // Result: 1050.00
   ? nValue                               // Result: 1000.00

Platforms

Available on MS-DOS

See also

-, --, :=, /, *, **, %, +, ++

= (equality)⌃ | ☰

Equal—binary (Relational)

Syntax

Description

The equal operator (= ) compares two values of the same data type and returns true (.T.) if exp1 is equal to exp2 according to the following rules:

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for «A» is 65 and the code for «Z» is 90).

When EXACT is OFF, two character 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 null, returns true (.T.).

— If Len(cRight) is greater than Len(cLeft), returns false

(.F.).

— Compare all characters in cRight with cLeft. If all

characters in cRight equal cLeft, returns true (.T.); otherwise, returns false (.F.).

With EXACT ON, two strings must match exactly except for trailing blanks.

■ Date: Dates are compared according to the underlying date

value.

■ Logical: True (.T.) is equal to true (.T.) and false (.F.)

equal to false (.F.).

■ Memo: Treated the same as character.

NIL: True (.T.) if compared to a NIL value; false (.F.) if

compared to a value of any other data type.

■ Numeric: Compared based on magnitude.

Examples

■  These examples illustrate how the equal operator (=) behaves
   with different data types:

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

   // Date
   ? CToD("12/12/88") = ;
      CToD("12/12/88")      // Result: .T.

   // Logical
   ? .T. = .T.              // Result: .T.
   ? .F. = .T.              // Result: .F.

   // NIL
   ? NIL = NIL              // Result: .T.
   ? NIL = 12               // Result: .F.
   ? NIL = CToD("")         // Result: .F.

   // Numeric
   ? 2 = 1                  // Result: .F.
   ? 1 = 1                  // Result: .T.

Platforms

Available on MS-DOS

See also

<, <=, <> != #, ==, >, >=, $

==⌃ | ☰

Exactly equal—binary (Relational)

Syntax

Description

The exactly equal operator (==) is a binary operator that compares two values of the same data type for exact equality depending on the data type. It returns true (.T.) if exp1 is equal to exp2 according to the following rules:

■ Array: Compares for identity. If exp1 and exp2 are

variable references to the same array, returns true (.T.); otherwise, returns false (.F.).

■ Character: Comparison is based on the underlying ASCII code.

ASCII codes for alphabetic characters are ascending (e.g., the code for «A» is 65 and the code for «Z» is 90). Unlike the relational equality operator (=) , true (.T.) is returned if exp1 and exp2 are exactly equal including trailing spaces; otherwise, the comparison returns false (.F.). SET EXACT has no effect.

■ Date: Dates are compared according to the underlying date

value; behaves the same as the relational equality operator (=).

■ Logical: True (.T.) is exactly equal to true (.T.), and false

(.F.) is exactly equal to false (.F.).

■ Memo: Treated the same as character.

NIL: True (.T.) if compared to a NIL value; false (.F.) if

compared to a value of any other data type.

■ Numeric: Compared based on magnitude; behaves the same as the

relational equality operator (=).

■ Object: Treated the same as array.

Examples

■  These examples illustrate how the == operator behaves with
   different data types:

   // Character
   ? "A" == "A"             // Result: .T.
   ? "Z" == "A"             // Result: .F.
   ? "A" == "A "            // Result: .F.
   ? "AA" == "A"            // Result: .F.

   // Array or object

   aOne := { 1, 2, 3 }
   aTwo := { 1, 2, 3 }
   aThree := aOne
   ? aOne == aTwo           // Result: .F.
   // values within the arrays are equal, but the arrays,
   // themselves, are separate and distinct
   ? aOne == aThree         // Result: .T.

Platforms

Available on MS-DOS

See also

<, <=, <> != #, = (equality), >, >=, $

>⌃ | ☰

Greater than—binary (Relational)

Syntax

Description

The greater than (>) operator compares two values of the same data type and returns true (.T.) if exp1 is greater than exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for «A» is 65 and the code for «Z» is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: True (.T.) is greater than false (.F.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples

■  These examples illustrate how the greater than operator (>)
   behaves with different data types:

   // Character
   ? "Z" > "A"             // Result: .T.
   ? "AZ" > "A"            // Result: .F.
   ? "A" > "AZ"            // Result: .F.

   // Date

   ? CToD("12/12/88") > ;
      CToD("12/11/88")     // Result: .T.

   // Logical
   ? .T. > .F.             // Result: .T.

   // Numeric
   ? 2 > 1                 // Result: .T.
   ? 1 > 2                 // Result: .F.

Platforms

Available on MS-DOS

See also

<, <=, <> != #, = (equality), ==, >=, $

>=⌃ | ☰

Greater than or equal—binary (Relational)

Syntax

Description

The greater than or equal to operator (>=) is a binary operator that compares two values of the same data type and returns true (.T.) if exp1 is greater than or equal to exp2.

■ Character: The comparison is based on the underlying ASCII

code. ASCII codes for alphabetic characters are ascending (e.g., the code for «A» is 65 and the code for «Z» is 90).

■ Date: Dates are compared according to the underlying date

value.

■ Logical: True (.T.) is greater than false (.F.).

■ Memo: Treated the same as character.

■ Numeric: Compared based on magnitude.

Examples

■  These examples illustrate how the greater than or equal
   operator (>=) behaves with different data types:

   // Character
   ? "Z" >= "A"             // Result: .T.

   ? "AZ" >= "A"            // Result: .T.
   ? "A" >= "AZ"            // Result: .F.

   // Date
   ? CToD("12/12/88") >= ;
      CToD("12/11/88")      // Result: .T.

   // Logical
   ? .T. >= .F.             // Result: .T.

   // Numeric
   ? 2 >= 1                 // Result: .T.
   ? 1 >= 2                 // Result: .F.
   ? 2 >= 2                 // Result: .T.

Platforms

Available on MS-DOS

See also

<, <=, <> != #, = (equality), ==, >, $

-⌃ | ☰

Subtraction, unary negative, concatenation (Math, Character)

Syntax

<nNumber1> - <nNumber2>             (subtraction)
<dDate1>   - <dDate2>               (subtraction)
<dDate>    - <nNumber>              (subtraction)
<cString1> - <cString2>             (concatenation)

Description

The (-) operator performs different operations depending on the data types of the operands:

■ Unary negative sign (numeric): A numeric expression prefaced

with the minus (-) operator performs the equivalent of multiplying the operand by (-1), returning a negative numeric value.

■ Binary subtraction (numeric, date): If both operands are

numeric data type, nNumber2 is subtracted from nNumber1 and the result is returned as a numeric value. If both operands are date data type, dDate2 is subtracted from dDate1 and the result is returned as a numeric value representing the number of days between the two dates. If the left operand is date data type and the right operand numeric data type, the nNumber is subtracted as days from dDate and a date value is returned. If the order of operands is reversed, a runtime error occurs.

■ Concatenation (character, memo): If both operands are

character data type, cString2 is joined to cString1, returning a character string. Trailing blanks are trimmed from cString1 and joined to the end of the return string.

Examples

■  These examples illustrate the various forms of the - operator:

   // Binary subtraction (numeric)
   ? 1 - 1                           // Result: 0
   ? 1 - 0                           // Result: 1
   ? 0 - 1                           // Result: -1

   // Binary subtraction (date)

   ? CToD("12/12/88") - 12         // Result: 11/30/88
   ? 12 - CToD("12/12/88")         // Result: Runtime error

   // Concatenation (character)
   ? "Hi " - "There" + "*"         // Result: Hithere *

Platforms

Available on MS-DOS

See also

= (compound assign), /, *, **, %, +

->⌃ | ☰

Alias assignment—binary (Special)

Syntax

<idAlias>-><idField>
<idAlias>->(<exp>)
(<nWorkArea>)-><idField>
(<nWorkArea>)->(<exp>)
FIELD-><idVar>
MEMVAR-><idVar>

Description

When used with an idAlias as the first operand, the alias operator

(->) accesses field information or evaluates an expression in the indicated work area. The alias operator implicitly SELECTs the idAlias before evaluating the idField or exp operand. When the evaluation is complete, the original work area is SELECTed again. An alias reference can be in an expression or on a line by itself:

? Customer->Name Customer->(UpdateTransaction())

Using the alias operator lets you:

■ Access information from unselected work areas within

expressions

■ Access environmental information from unselected work areas

■ Access information from unselected work areas in modes such as

REPORT and LABEL FORMs

■ Write more compact code

In addition to allowing expression and field evaluation in unselected work areas, the alias operator makes an explicit reference to a field or variable using either the FIELD or the MEMVAR keyword aliases. MEMVAR forces idVar to refer to a memory variable name, and FIELD forces it to reference a database field. These special alias identifiers allow you to avoid ambiguity when there are conflicts between field and memory variable names. Remember that a reference to a variable identifier not prefaced with an alias defaults to a field if there are both field and memory variables with the same name. To override this, use the (/V) option when compiling.

In addition to specifying the alias as an identifier, you can access the target work area using an expression that returns the work area number if the expression is enclosed by parentheses. This lets you use work area numbers as handles, which is useful for passing references to work areas without using macros, aliases, names, etc.

Examples

■  This example accesses database and work area information in an
   unselected work area:

   USE Customer NEW
   USE Invoices NEW
   ? Customer->CustName                  // Result: Bill Smith
   ? Customer->(RecNo())                 // Result: 1
   ? Customer->(Found())                 // Result: .F.
   ? Customer->(City + ", " + State + ;
      "  " + Zip)                        // Result: ShadowVille,
                                         //         CA  90415

■  This example uses a user-defined function (MySeek()) as an
   operand of the alias operator for a common operation that normally
   requires many more statements:

   IF Invoices->(MySeek(CustNum))
      <process customer>...
   ELSE
      <process no find>...
   ENDIF
   RETURN

   FUNCTION MySeek( cSearch )
      SEEK cSearch
   RETURN (Found())

   Note:  This example is just an illustration of the alias operator
   with a user-defined function.  CA-Clipper's dbSeek() could be used
   instead of MySeek().

■  This example explicitly references field and memory variables
   with the same name:

   USE Customer NEW
   MEMVAR->CustName = "Bill Smith"      // Create a memvar
                                        // CustName
   LOCATE FOR MEMVAR->CustName = FIELD->CustName

■  This example uses an expression as a work area handle to
   create a work area-independent database operation:

   cTable1 := "C:Myfile.dbf"
   cTable2 := "D:Myfile.dbf"
   USE (cTable1) NEW
   hArea1 = Select()
   USE (cTable2) NEW
   hArea2 = Select()
   DoStuff( hArea1, hArea2 )

   FUNCTION DoStuff( hArea1, hArea2 )
      LOCAL nCount, nSave
      nSave := Select()
      SELECT (hArea1)
      FOR nCount := 1 TO FCount()
         FieldPut( nCount, ( hArea2 )-> ;
            ( FieldGet( nCount )))
      NEXT
      SELECT (nSave)
      RETURN NIL

Platforms

Available on MS-DOS

See also

--⌃ | ☰

Decrement—unary (Mathematical)

Syntax

--<idVar>       (prefix decrement)
<idVar>--       (postfix decrement)

Description

The decrement operator (—) decreases the value of its operand by one. This operator subtracts one from the value of idVar and assigns the new value to idVar.

The — operator can appear before or after idVar. Specifying the operator before idVar decrements and assigns the value before the value is used. This is called prefix notation, and it is the most common usage. Specifying the operator after idVar decrements and assigns the value after it is used. This is postfix notation. Stated differently, postfix notation delays the assignment portion of the operation until the rest of the expression is evaluated, and prefix notation gives the assignment precedence over all other operations in the expression.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. You can assign field variables by declaring the field variable name in a FIELD statement or by referring to the field name prefaced by the FIELD-> alias or by the name of the work area.

Examples

■  In this example of the postfix decrement operator the
   assignment takes place before the original variable is decremented,
   thus the two values are not the same when queried:

   nValue := 1
   nNewValue := nValue--
   ? nNewValue                  // Result:   1
   ? nValue                     // Result:   0

■  In this example, the prefix decrement operator decreases the
   first operand of the multiplication by one, making its value 9.
   Then, the assignment of this new value to the nValue variable takes
   place before the rest of the expression is evaluated.  Thus, the new
   value is used to perform the multiplication operation, and the result
   of 9 * 9 is 81.

   nValue := 10
   ? --nValue * nValue          // Result:  81
   ? nValue                     // Result:   9

Platforms

Available on MS-DOS

See also

= (compound assign), -, :=, ++

:⌃ | ☰

Send—binary (Object)

Syntax

<object>:<message>[(<argument list>)]

Description

Each class defines a set of operations that can be performed on objects of that class. Perform these operations by sending a message to the object using the send operator (:).

When a message is sent to an object, the system examines the message. If the object is of a class that defines an operation for that message, the system automatically invokes a method to perform the operation on the specified object. If the class does not define a method for the specified message, a runtime error occurs.

Executing a message send produces a return value, much like a function call. The return value varies depending on the operation performed.

Examples

■  In this example, myBrowse is the name of a variable that
   contains a TBrowse object reference.  pageUp() is a method that
   specifies the operation to be performed.  The available operations
   and corresponding methods vary depending on the class of the object.
   The Error, Get, TBColumn, and TBrowse classes are documented in this
   chapter.

   myBrowse:pageUp()

■  This example forces the checkbox state to true (.T.):

   myCheck : Select (.T.)

Platforms

Available on MS-DOS

:=⌃ | ☰

Inline assign—binary (Assignment)

Syntax

Description

The inline assignment operator (:=) assigns values of any data type to variables of any storage class. The operator evaluates exp, assigns the resulting value to idVar, and returns the resulting value as the return value of the operation. This latter behavior permits multiple assignments such as idVar1 := idVar2 := value. Unlike the simple assign operator (=), the inline assignment operator (:=) can be used anywhere an expression or constant is allowed, including variable declaration statements. With a variable declaration statement, assignment initializes a variable. Note, however, you cannot declare an array and initialize elements within the same program statement.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. At runtime, if no private or public variable exists with the specified name, a private variable is created. You can assign field variables with the := operator by declaring the field variable name in a FIELD statement or referring to the field name prefaced by the FIELD-> alias or the name of the work area.

Examples

■  Several examples of inline assignment follow:

   LOCAL nValue := 10
   //
   IF (dDate := (Date() - 1000)) = CToD("12/20/79")
   //
   ? Sqrt(nValue := (nValue ** 2))
   //
   cTransNo := cSortNo := (CustId + DToC(Date()))

■  This last example performs multiple assignments using the
   inline assignment operator as you would with the STORE command.  When
   := is used in this way, the assignments are executed from right to
   left.  This feature is particularly useful when you need to store the
   same value to many different fields, possibly in different database
   files.

   CustFile->CustId := TransFile-> ;
      TransNo := (CustId + DToC(Date())

Platforms

Available on MS-DOS

See also

= (assign), = (compound assign), --, ++, STORE*

?|??⌃ | ☰

Display one or more values to the console

Syntax

Arguments

exp list is a list of values to display and can be any combination of data types, including memo.

If you specify no argument and use the ? command, a carriage return/linefeed is sent to the console. If you use the ?? command without arguments, nothing happens.

Description

? and ?? are console commands that display the results of one or more expressions, separated by a space, to the console. These commands are also command synonyms for the QOut() and QQOut() functions, respectively.

Although functionally similar, ? and ?? differ slightly. ? sends a carriage return/linefeed to the console before displaying the results of the expression list. ?? displays output at the current screen cursor or printhead position. This lets you use successive ?? commands to display output to the same line.

A ? or ?? command locates the cursor or printhead one position to the right of the last character displayed. If SET PRINTER is OFF, Row() and Col() are updated to reflect the new cursor position. If SET PRINTER is ON, PRow() and PCol() are updated with the new printhead position.

If output from a ? or ?? command reaches the edge of the screen as reported by MaxCol(), it wraps to the next line. If the output reaches the bottom of the screen as reported by MaxRow(), the screen scrolls up one line.

You can echo output from the ? or ?? commands to the printer by specifying a SET PRINTER ON command before beginning output. You can echo output from both of these commands to a text file using SET ALTERNATE TO xcFile to create the file, and SET ALTERNATE ON to begin echoing to the file. Like other console commands, SET CONSOLE OFF suppresses the display to the screen without affecting output to the printer or text file.

To format any expression specified, use Transform() or a user-defined function. If you need to pad a variable length value for column alignment, use any of the Pad() functions to left-justify, right- justify, or center the value. See the examples below.

Examples

■  This example prints a record from a database file using ? and
   ?? commands with PadR() to ensure column alignment:

   LOCAL nPage := 0, nLine := 99
   USE Salesman INDEX Salesman NEW
   SET PRINTER ON
   SET CONSOLE OFF
   DO WHILE !Eof()
      IF nLine > 55
         IF nPage != 0
            EJECT
         ENDIF
         ? PadR("Page", LTrim(Str(nPage++)), 72)
         ?? DToC(Date())
         ?
         ?
         ? PadC("Sales Listing", 79)
         ?
         nLine := 5
      ENDIF
      ? Name, Address, PadR(RTrim(City) + "," ;
            + State, 20), ZipCode
      nLine++
      SKIP
   ENDDO
   SET CONSOLE ON
   SET PRINTER OFF
   CLOSE Salesman

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

/⌃ | ☰

Division—binary (Mathematical)

Syntax

Description

The division operator (/) returns a numeric value from the division of nNumber1 by nNumber2.

Note: Dividing nNumber1 with zero value for nNumber2 results in a runtime error.

Examples

■  This example shows division results to 16 decimal places,
   using different operands:

   SET DECIMALS TO 16
   ?  3 /  0            // Result: Runtime error
   ?  3 / -2            // Result: -1.500000000
   ? -3 /  2            // Result: -1.500000000
   ? -3 /  0            // Result: Runtime error
   ? -1 / -3            // Result: +0.333333333
   ? -2 /  3            // Result: -0.666666667
   ?  2 / -3            // Result: -0.666666667
   ?  1 / -3            // Result: -0.333333333

Platforms

Available on MS-DOS

See also

.AND.⌃ | ☰

Logical AND—binary (Logical)

Syntax

<lCondition1> .AND. <lCondition2>

Description

The .AND. operator is a binary logical operator that executes a logical AND operation using the following modified Boolean rules:

■ Returns true (.T.) if both lCondition1 and lCondition2

evaluate to true (.T.)

■ Returns false (.F.) if either lCondition1 and lCondition2

evaluate to false (.F.)

Warning! In a departure from Summer ’87 and other dialect behavior, CA-Clipper shortcuts the evaluation of .AND. operands. This means that lCondition1 and lCondition2 are both evaluated only when lCondition1 evaluates to TRUE (.T.). If lCondition1 evaluates to FALSE (.F.), the .AND. operation is FALSE (.F.) and lCondition2 is therefore not evaluated.

For backward compatibility, shortcutting can be suppressed by compiling with the /Z option.

Examples

■  This example shows .AND. results using different operands:

   ? .T. .AND. .T.            // Result: .T.
   ? .T. .AND. .F.            // Result: .F.
   ? .F. .AND. .T.            // Result: .F.   (shortcut)
   ? .F. .AND. .F.            // Result: .F.   (shortcut)

Platforms

Available on MS-DOS

See also

.NOT., .OR.

.NOT.⌃ | ☰

Logical NOT—unary (Logical)

Syntax

! <lCondition>
.NOT. <lCondition>

Description

The not (!) operator is a unary logical operator that returns the logical inverse of lCondition.

Examples

■  This example shows .NOT. results using different operands:

   ? ! (.T.)               // Result: .F.
   ? ! 1 > 2               // Result: .T.
   ? .NOT. 1 > 2           // Result: .T.

Platforms

Available on MS-DOS

See also

.AND., .OR.

.OR.⌃ | ☰

Logical OR—binary (Logical)

Syntax

<lCondition1> .OR. <lCondition2>

Description

The .OR. operator is a binary logical operator that executes a logical OR operation using the following modified Boolean rules:

■ Returns true (.T.) if either lCondition1 or lCondition2

evaluates to true (.T.)

■ Returns false (.F.) if both lCondition1 and lCondition2

evaluates to false (.F.)

Warning! In a departure from the Summer ’87 and other dialect behavior, CA-Clipper shortcuts the evaluation of .OR. operands. This means that lCondition1 and lCondition2 are both evaluated only when lCondition1 evaluates to false (.F.). If lCondition1 evaluates to true (.T.), the .OR. operation is true (.T.) and lCondition2 is, therefore, not evaluated. For backward compatibility, shortcutting can be suppressed by compiling with the /Z option.

Examples

■  This example shows .OR. results using different operands:

   ? .T. .OR. .T.            // Result: .T.   (shortcut)
   ? .T. .OR. .F.            // Result: .T.   (shortcut)
   ? .F. .OR. .T.            // Result: .T.
   ? .F. .OR. .F.            // Result: .F.

Platforms

Available on MS-DOS

See also

( )⌃ | ☰

Function or grouping indicator (Special)

Description

Parentheses (()) in expressions are used to group certain operations for readability or to force a particular evaluation order. Parentheses also identify a function call.

When specifying the grouping operator, the item that falls within the parentheses must be a valid expression. Subexpressions may be further grouped.

For function calls, a valid function name must precede the left parenthesis, and the function arguments, if any, must be contained within the parentheses.

Examples

■  This example changes the default order of expression
   evaluation:

   ? 5 * (10 + 6) / 2         // Result: 40

■  The next example shows a function call:

   x := Sqrt(100)

Platforms

Available on MS-DOS

See also

[ ]⌃ | ☰

Array element indicator (Special)

Syntax

<aArray>[<nSubscript>, ... ]
<aArray>[<nSubscript1>][<nSubscript2>] ...

Description

The subscript operator ([]) specifies a single array element. The name of a previously declared array must precede the left bracket and the array element subscript must appear as a numeric expression within the brackets. You can make array element references using Pascal or C-style syntax.

Examples

■  This example accesses each element in a two-dimensional array
   of known dimensions:

   LOCAL i, j
   FOR i := 1 TO 5
      FOR j := 1 TO 10
         ? aOne[i, j]
      NEXT
   NEXT

■  These examples specify an <aArray> expression:

   LOCAL aArray := { 1, 2, 3, 4, 5 }
   //
   ? ArrayFunc()[2]                     // Result: 2
   ? { {1, 2}, {3, 4} }[1][2]           // Result: 2
   ? aArray[5]                          // Result: 5

   FUNCTION ArrayFunc
      STATIC aArray := { 1, 2 }
      RETURN aArray

■  This example queries and assigns a static array encapsulated
   within a function definition:

   ? ArrayFunc()[1]                     // Result: 1
   ArrayFunc()[1] := 10
   ? ArrayFunc()[1]                     // Result: 10

   FUNCTION ArrayFunc
      STATIC aArray := { 1, 2 }
      RETURN aArray

Platforms

Available on MS-DOS

See also

{ }⌃ | ☰

Literal array and code block delimiters (Special)

Syntax

{ <exp list> }                 (literal array)
{ |<param list>| <exp list> }  (code block definition)

Description

Curly braces ({}) delimit references to literal arrays or code blocks. If the reference is a literal array, you can use them to create an array in either an assignment or a variable declaration statement. If the reference is a variable declaration, the array can contain expressions of any kind as elements, unless STATIC is the declaration statement. In this case, the literal array can only contain constant values.

Examples

■  This example uses literal arrays in declaration statements to
   create a variable and initialize it with an array reference:

   LOCAL aPerson := { "Name", "Address", Date() }
   STATIC aNumList := { 1, 2, 3, 4, 5, 6, 7, 8 }

■  This example creates a multidimensional literal array:

   aMulti := { {1, 2, 3}, {"A", "B", "C"} }

■  This example uses curly braces to formulate a simple code
   block with a single parameter:

   LOCAL bSayBlock
   bSayBlock := { |x| QOut(x) }
   Eval(bSayBlock, 10)               // Result: 10

Platforms

Available on MS-DOS

See also

@⌃ | ☰

Pass-by-reference—unary (Special)

Syntax

Description

The pass-by-reference operator (@) passes variables by reference to functions or procedures invoked with function-calling syntax. It is a unary prefix operator whose operand may be any variable name.

Passing a variable by reference means that a reference to the value of the argument is passed instead of a copy of the value. The receiving parameter then refers to the same location in memory as the argument. If the called routine changes the value of the receiving parameter, it also changes the argument passed from the calling routine.

Passing a variable by value means that the argument is evaluated and its value is copied to the receiving parameter. Changes to a receiving parameter are local to the called routine and lost when the routine terminates. The default method of passing arguments is by value for all data types including references to arrays and objects.

Examples

■  This example demonstrates the difference between passing a
   user-defined function argument by reference and by value:

   LOCAL nNum := 1                     // Initial values

   LOCAL aArr := { "a", "b", "c" }
   //
   CLS
   // Print initial values
   ? ValType(nNum), nNum
   ? ValType(aArr), aArr[1], aArr[2], aArr[3]
   //
   Udf1(nNum)                          // Pass by value (default)
   ? ValType(nNum), nNum               // Result:  N, 1
   //
   Udf1(aArr[1])                       // Pass by value (default)
   ? ValType(aArr), aArr[1],;
         aArr[2], aArr[3]              // Result:  A, "a" "b" "c"
   //
   Udf2(aArr)                          // Pass a reference to
   ? ValType(aArr), aArr[1],;          // the array (default)
         aArr[2], aArr[3]              // A, "Oi!" "b" "c"
   //
   Udf1(@nNum)                         // Force pass by reference
   ? ValType(nNum), nNum               // Result:  N, 1000
   //
   Udf3(@aArr)                         // Pass array by reference
   ? ValType(aArr)                     // Result:  N
   //
   RETURN NIL


   FUNCTION Udf1(nParam)               // Receive as a local
   ? nParam                            // parameter
   nParam := 1000
   ? nParam
   RETURN NIL
   //
   FUNCTION Udf2( aParam )             // Receive as a local
   ? ValType(aParam), aParam[1]        // parameter
   aParam[1] := "Oi!"
   ? aParam[1]
   RETURN NIL
   //
   FUNCTION Udf3(aParam)               // Receive as a local
   ? ValType(aParam), aParam[1]        // parameter
   aParam := 1000
   ? aParam
   RETURN NIL

Platforms

Available on MS-DOS

See also

@...BOXHarbour implementation⌃ | ☰

Draw a box on the screen

Syntax

@ <nTop>, <nLeft>, <nBottom>, <nRight>
   BOX <cBoxString> [COLOR <cColorString>]

Arguments

nTop, nLeft, nBottom, nRight define the coordinates of the box. @...BOX draws a box using row values from zero to MaxRow(), and column values from zero to MaxCol(). If nBottom and nRight are larger than MaxRow() and MaxCol(), the bottom-right corner is drawn off the screen.

BOX cBoxString defines a string of eight border characters and a fill character. If cBoxString is specified as a single character, that character draws the whole box.

COLOR cColorString defines the display color of the drawn box. If not specified, the box is drawn using the standard color setting of the current system color as defined by SetColor(). Note that cColorString is a character expression containing the standard color setting. If you want to specify a literal color setting, enclose it within quote marks.

Description

@...BOX draws a box on the screen using configurable border and fill characters. @...BOX draws the box using cBoxString starting from the upper left-hand corner, proceeding clockwise and filling the screen region with the ninth character. If the ninth character is not specified, the screen region within the box is not painted. Existing text and color remain unchanged.

After @...BOX executes, the cursor is located in the upper corner of the boxed region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.

Examples

■  These examples draw two boxes using box manifest constants
   defined in the supplied header file, box.ch.  The first example draws
   a box using the specified characters for the border, but leaves all
   other areas of the screen intact.  The second example draws the same
   box filling the box region with space characters.

   #include "Box.ch"
   // Draw a box with a double-line top with a
   // single-line side
   @ 1, 1, 22, 79 BOX B_DOUBLE_SINGLE
   // Draw the same box filling the box region with
   // spaces
   @ 1, 1, 22, 79 BOX B_DOUBLE_SINGLE + Space(1)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is box.ch.

See also

@...CLEARHarbour implementation⌃ | ☰

Clear a rectangular region of the screen

Syntax

@ <nTop>, <nLeft> [CLEAR
   [TO <nBottom>, <nRight>]]
   [DOUBLE] [COLOR <cColor>]

Arguments

nTop and nLeft define the upper-left corner coordinate.

TO nBottom, nRight defines the lower-right corner coordinates of the screen region to CLEAR. If the TO clause is not specified, these coordinates default to MaxRow() and MaxCol().

Description

@...CLEAR erases a rectangular region of the screen by filling the specified region with space characters using the current standard color setting. After @...CLEAR erases the designated region, the cursor is located in the upper corner of the region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.

Examples

■  This example erases the screen from 10, 10 to 20, 40, painting
   the region blue and then displaying a bright cyan box on blue:

   SetColor("BG+/B")
   @ 10, 10 CLEAR TO 20, 40
   @ 10, 10 TO 20, 40

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

@...GETHarbour implementation⌃ | ☰

Create a new Get object and display it to the screen

Syntax

@ <nRow>, <nCol>
   [SAY <exp>
      [PICTURE <cSayPicture>]
      [COLOR <cColorString>]]
   GET <idVar>
      [PICTURE <cGetPicture>]
      [COLOR <cColorString>]
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [RANGE* <dnLower>, <dnUpper>] |
      [VALID <lPostExpression>]
      [SEND <msg>]
      [GUISEND <guimsg>]

Arguments

nRow and nCol specify the row and column coordinates for the operation. If the SAY clause is present, nRow and nCol specify the coordinates for the SAY, and the GET is displayed to the right of the SAY output. If the SAY clause is not present, nRow and nCol directly specify the coordinates for the GET. In either case, output which extends beyond the visible extent of the display is clipped and does not appear.

SAY exp displays the value of exp at the specified coordinates. If you specify the PICTURE cSayPicture clause, exp is formatted according to the rules of SAY pictures.

GET idVar specifies the name of the variable associated with the GET. idVar may be of any storage class (if the storage class is ambiguous, FIELD is assumed). If idVar contains an array value, you must supply one or more subscripts. The current value of idVar is displayed at the GET coordinates. The value must be character, date, numeric, or logical type. Array, NIL, code block, and null string values are not permitted.

PICTURE cGetPicture specifies the display format and editing rules for the GET.

COLOR cColorString defines the color settings for the current Get object. cColorString is a character expression containing one or more color settings. You must specify literal color settings enclosed in quote marks.

If you specify two color settings, the first determines the unselected color (the display color for the Get object) and the second determines the selected color (the color when the Get object has focus). If you only specify one color, it determines both the unselected and selected colors for the Get object.

On a combined @...SAY...GET command, two COLOR clauses are required to specify colors for both the SAY and the GET: one for the SAY, and one for the GET.

CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse’s left button is clicked and its cursor is on the caption. By default, the caption appears to the right of the GET. Use the Get object’s capRow or capCol variable to change the screen position of the caption. Note that if the SAY clause is used, the CAPTION clause is ignored.

When present, the & character specifies that the character immediately following it in the caption is the GET‘s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the GET. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.

MESSAGE cMessage specifies a character string that is displayed on the Get system’s status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the SET MESSAGE command for details pertaining to the Get system’s status bar.

WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

RANGE* dnLower, dnUpper specifies a range of allowable values for input to the GET. During a READ command, if you enter a new GET value that does not fall within the specified range, the cursor cannot leave the GET.

VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.

GUISEND guimsg can be used to send a message (such as the Display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.

Description

The @...GET command creates a new Get object, displays its value, and adds it to the array referred to by the variable GetList. If no variable called GetList has been declared or created in the current procedure, and no PRIVATE variable called GetList exists from a previous procedure, the system uses the predefined PUBLIC variable GetList. A subsequent READ command activates the GETs contained in the GetList array and allows the user to edit their contents.

Each Get object has an associated variable, idVar. The variable may be of any storage class, including a database field, private, public, local, or static variable. If idVar is followed by one or more subscripts, the specified array element is associated with the GET. When the Get object is created, the idVar name is stored in the Get object, along with a code block which allows the value of idVar to be retrieved or assigned during the READ.

The READ command performs a full-screen edit of the GETs in the GetList array. As the user moves the cursor into each GET, the value of the associated idVar is retrieved by evaluating the code block saved in the Get object. The value is converted to textual form and placed in a buffer within the Get object. This buffer is displayed on the screen, and the user is allowed to edit the text from the keyboard. When the user moves the cursor out of the GET, the updated buffer is converted back to the appropriate data type and assigned to idVar.

Automatic formatting and validation: During a READ, some formatting and edit validation is automatically performed for numeric, date, and logical values. As the user is typing, an automatic data type test is performed on each key pressed, preventing the user from entering an invalid character.

Prevalidation: The WHEN clause specifies a condition which must be satisfied before the cursor can enter the GET. During a READ, lPreExpression is evaluated whenever the user attempts to move the cursor into the GET. If it evaluates to true (.T.), the cursor can enter; otherwise, the GET is skipped.

Postvalidation: You may perform postvalidation using either the VALID or RANGE* clauses. VALID specifies a condition which must be satisfied before the cursor can leave the GET. During a READ, lPostExpression is evaluated whenever the user attempts to move the cursor out of the GET. If it evaluates to true (.T.), the cursor can leave; otherwise, the cursor remains in the GET. RANGE* specifies a range of acceptable values for numeric or date values. If the value entered by the user is not within the specified range, the cursor cannot leave the GET.

Note: You may specify either a VALID or RANGE clause, but not both.

PICTURE: When you specify the PICTURE clause for a GET, the character string specified by cGetPicture controls formatting and edit validation. The picture string controls the display format like a SAY picture. It also controls the way the user can edit the buffer. A picture string consists of two distinct parts, a function string and a template string, either or both of which may be present.

■ Function string: A PICTURE function string specifies

formatting or validation rules which apply to the GET‘s display value as a whole, rather than to particular character positions within it. The function string consists of the @ character, followed by one or more additional characters, each of which has a particular meaning (see the following table). The function string must be the first element of a PICTURE clause and cannot contain spaces. A function string may be specified alone or with a template string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

GET PICTURE Format Functions

       Function     Type Action

       A            C    Allows only alphabetic characters.

       B            N    Displays numbers left-justified.

       C            N    Displays CR after positive numbers.

       D            D,N  Displays dates in SET DATE format.

       E            D,N  Displays dates with day and month inverted

                         independent of the current DATE SETting, numerics

                         with comma and period reverse (European style).

       K            ALL  Deletes default text if first key is not a cursor

                         key.

       R            C    Nontemplate characters are inserted in the display

                         but not saved in the variable.

       S<n>         C    Allows horizontal scrolling within a GET.  <n> is

                         an integer that specifies the width of the region.

       X            N    Displays DB after negative numbers.

       Z            N    Displays zero as blanks.

       (            N    Displays negative numbers in parentheses with

                         leading spaces.

       )            N    Displays negative numbers in parentheses without

                         leading spaces.

       !            C    Converts alphabetic character to uppercase.

■ Template string: A PICTURE template string specifies

formatting or validation rules on a character by character basis. The template string consists of a series of characters, some of which have special meanings (see the following table). Each position in the template string corresponds to a position in the displayed GET value. Characters in the template string that do not have assigned meanings are copied verbatim into the displayed GET value. If you use the @R picture function, these characters are inserted between characters of the display value, and are automatically removed when the display value is reassigned to idVar; otherwise, they overwrite the corresponding characters of the display value and also affect the value assigned to idVar. You may specify a template string alone or with a function string. If you use both, the function string must precede the template string, and the two must be separated by a single space.

GET PICTURE Template Symbols

       Template     Action

       A            Allows only alphabetic characters

       N            Allows only alphabetic and numeric characters

       X            Allows any character

       9            Allows digits for any data type including sign for

                    numerics

       #            Allows digits, signs and spaces for any data type

       L            Allows only T, F, Y or N

       Y            Allows only Y or N

       !            Converts an alphabetic character to uppercase

       $            Displays a dollar sign in place of a leading space in a

                    numeric

       *            Displays an asterisk in place of a leading space in a

                    numeric

       .            Displays a decimal point

       ,            Displays a comma

SCOREBOARD: If a new value is rejected because it fails the RANGE* test or because it is a malformed date value, a message appears on the screen. The message displays in the SCOREBOARD area, which you can enable or disable using the SET SCOREBOARD command.

Exit with Esc: If the user exits a GET by pressing Esc, the GET variable is restored to the value it had on entry to the GET, and the READ is terminated. No postvalidation is performed. You can enable or suppress this behavior with the SET ESCAPE command.

SET KEY procedures: The SET KEY command lets you specify a procedure to be executed whenever a specific key is pressed during a READ. After a SET KEY procedure terminates, the GET is reactivated with the cursor restored to its previous position.

Lifetime of a Get object: Get objects, like arrays, exist as long as there are active references to them somewhere in the current program. Normally, only the array in the GetList variable maintains a reference to the Get object; the GET is released when GetList is released or reassigned. The CLEAR and CLEAR GETS commands assign an empty array to GetList, as does the READ command unless you specify the SAVE clause.

Assignment: Each GET is associated with a variable, idVar, in the @...GET command. At various times during the editing process, idVar may be assigned the current value of the Get object’s buffer. This occurs in the following instances:

■ After the user presses an exit key and before the validation

expression is executed

■ After the user presses a SET KEY

Also, the current Get object’s buffer is refreshed from idVar and redisplayed at various intervals:

■ After a SET KEY procedure terminates

■ After a WHEN expression is evaluated

■ After a VALID expression is evaluated

This lets you explicitly assign idVar within any of these operations. See the note below for more information.

GET coordinates and display: When you create a Get object using the @...GET command, the row and column coordinates at which the GET is initially displayed are stored in the Get object. When the @...GET command executes, the new GET displays at nRow and nCol, unless you specify the SAY clause which positions the GET so there is one display column between the last character of the SAY output and the first character of the GET (or of the DELIMITERS, see below).

If SET DELIMITERS is ON when the @...GET command executes, the current DELIMITER characters display on either side of the initial GET display, and the column coordinate of the GET is adjusted accordingly. Note that the delimiters are not attributes of the Get object, but simply display as the SAY clause does.

If INTENSITY is ON, GETs initially display in the current unselected color (or the enhanced color, if no unselected color has been specified). During a READ, the active GET displays in the enhanced color, while the remaining GETs display in the unselected color. With INTENSITY OFF, all GETs display in the standard color.

When a GET displays, the width of the displayed value is determined by the length of the value in idVar or, if you specify the PICTURE clause, by the number of positions in cGetPicture. If you specify the @S function as a part of cGetPicture, the @S argument controls the width of the displayed value.

Notes

WHEN and VALID: The expressions specified in the WHEN and

VALID clauses may be of arbitrary complexity and may include calls to user-defined functions. This is useful for attaching automatic actions to the activation or deactivation of a GET.

■ Assigning idVar: Because of the automatic refresh and

display properties of a Get object while it is being READ, you can make an explicit assignment to the Get object’s idVar within a WHEN or VALID expression. You can directly assign the variable by name in the validation expression or, for private, public, local, or static variables, by passing a reference to idVar to a function; the function can then assign idVar by assigning the corresponding formal parameter. If idVar is a field, it is globally visible and can be assigned by name in a function called by the validation expression.

When including a GET in a called function, do not include an idVar with the same name as a field idVar. Field references have precedence over public variables so the public idVar will be ignored.

GET specific help: You can use a SET KEY procedure to display

help text associated with a Get object. Within the SET KEY procedure, use the ReadVar() function to determine the idVar associated with the current Get object. Use this information to display the appropriate help text. Remember that when a CA-Clipper- compiled program loads, the F1 KEY is automatically SET TO a procedure or user-defined function named Help.

SET DEVICE TO PRINTER: SET DEVICE TO PRINTER does not direct

display of a Get object under the @...GET command to the printer or file.

Examples

■  This  example uses the VALID clause to validate input into a
   GET:

   LOCAL nNumber := 0
   @ 10, 10 SAY "Enter a number:" ;
      GET nNumber VALID nNumber > 0

■  This example demonstrates passing a code block with the VALID
   clause.  The parameter oGet is the current Get object.  Udf() changes
   the value of the GET:

   LOCAL GetList := {}, cVar := Space(10)
   CLS
   @ 10, 10 GET cVar  VALID { |oGet| Udf1( oGet ) }
   READ
   .
   .
   .
   * Udf( <oGet> ) --> .T.

   FUNCTION Udf1( oGet )

   IF "test" $ oGet:BUFFER          // Compare buffer contents
   oGet:varPut( "new value " )      // Change contents
   ENDIF

   RETURN .T.

■  This example uses the WHEN clause to prohibit entry into GETs
   based on the value of another GET.  In this example, entering Y in the
   Insured field indicates the client has insurance and the user is
   allowed to enter insurance information.  If the client does not have
   insurance, the cursor moves to the Accident field:

   @ 10, 10 GET Insured PICTURE "Y"
   @ 11, 10 GET InsNumber WHEN Insured
   @ 12, 10 GET InsCompany WHEN Insured
   @ 13, 10 GET Accident PICTURE "Y"
   READ

■  This is an example of a GET in a secondary work area:

   USE Invoice NEW
   APPEND BLANK
   USE Inventory NEW
   @ 1, 1 GET Invoice->CustNo
   READ

■  This example uses the @K function to suggest a default input
   value, but deletes it if the first key pressed is not a cursor key or
   Return:

   LOCAL cFile := "Accounts"
   @ 1, 1 SAY "Enter file" GET cFile PICTURE "@K"
   READ

■  This is an example of a nested READ using a GetList and
   lexical scoping:

   #include "inkey.ch"
   //
   // Local to this function only
   LOCAL GetList := {}
   LOCAL cName   := Space( 10 )
   //
   CLS
   SetKey( K_F2, { || MiscInfo() } )   // Hot key to special READ
   //
   // Get object added to getlist
   // works on local getlist
   @ 10, 10 SAY "Name" GET cName
   READ
   //
   RETURN NIL

   /***
   *  MiscInfo() ---> NIL
   */FUNCTION MiscInfo()
   //
   LOCAL GetList    := {}               // Local to this
   LOCAL cExtraInfo := Space( 30 )      // function only
   //
   // Get object added to getlist
   // works on local getlist
   @ 12, 10 SAY "Note: " GET cExtraInfo
   READ
   //
   RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

@...GET CHECKBOXHarbour implementation⌃ | ☰

Create a new check box Get object and display it to the screen

Syntax

@ <nRow>, <nCol>
   GET <lVar>
   CHECKBOX
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [COLOR <cColorString>]
      [FOCUS <fblock>
      [STATE <bBlock>]
      [STYLE <cStyle>]
      [SEND <msg>]
      [GUISEND <guimsg>]
      [BITMAPS <aBitmaps>]

Arguments

nRow and nCol specify the row and column coordinates for the check box and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.

GET lVar specifies the name of the variable associated with the GET. lVar must contain a logical value. A value of true (.T.) indicates that the check box is checked; otherwise, a value of false (.F.) indicates that it is not checked.

CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse’s left button is clicked and its cursor is on the caption. By default, the caption appears to the left of the GET. Use the Get object’s capRow or capCol variable to change the screen position of the caption.

When present, the & character specifies that the character immediately following it in the caption is the check box’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the check box. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.

MESSAGE cMessage specifies a character string that is displayed on the Get system’s status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system’s status bar.

WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

COLOR cColorString defines the color settings for the check box. cColorString is a character expression containing exactly four color settings.

CheckBox Color Attributes

    Position     Applies To                             Default Value from

    in colorSpec                                        System Color Setting

    1            The check box when it does not have      Unselected

                 input focus

    2            The check box when it has input focus    Enhanced

    3            The check box’s caption                  Standard

    4            The check box caption’s accelerator key  Background

Note: In graphic mode, colorSpec positions 1 and 2 have no affect and are ignored.

FOCUS fblock specifies a code block that is evaluated each time the check box receives focus. The code block takes no implicit arguments. Use the CheckBox:hasFocus instance variable to determine if the check box has focus.

STATE bBlock specifies a code block that is evaluated each time the check box’s state changes. The code block takes no implicit arguments. Use the CheckBox:buffer instance variable to determine if the check box is being checked or unchecked. A value of true (.T.) indicates that it is being checked; otherwise, a value of false (.F.) indicates that it is being unchecked.

STYLE cStyle specifies a character string that indicates the check box’s delimiter characters. The string must contain four characters. The first is the left delimiter. Its default value is the left square bracket ([) character. The second is the checked indicator. Its default value is the square root

() character. The third is the unchecked indicator. Its default is

the space character (» «). The fourth character is the right delimiter. Its default value is the right square bracket (]) character.

Note: The style clause is ignored in graphic mode.

SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.

GUISEND guimsg can be used to send a message (such as the Display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.

BITMAPS aBitmaps contains an array of exactly two elements. The first element of this array is the file name of the bitmap to be displayed when the check box is selected. The second element of this array is the file name of the bitmap to be displayed when the check box is not selected.

Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.

CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed.

This argument only affects applications running in graphic mode and is ignored in text mode.

Examples

■  This example demonstrates how to add a check box to a data entry screen:

   @ 5, 20 GET lReadOnly CHECKBOX

■  This example demonstrates a check box that has a caption and a
   message:

   @ 5, 20 GET lReadOnly CHECKBOX ;
           CAPTION "&Read Only" ;
           MESSAGE "Check to open file for reading only"

■  This example demonstrates a check box that uses the X
   character as the checked character instead of the square root
   character.

   @ 5, 20 GET lReadOnly CHECKBOX ;
           CAPTION "&Read Only" ;
           MESSAGE "Check to open file for reading only" ;
           STYLE "[X ]"

Platforms

Available on MS-DOS

File

Libraries are CLIPPER.LIB and LLIBG.LIB.

See also

@...GET LISTBOXHarbour implementation⌃ | ☰

Create a new list box Get object and display it to the screen

Syntax

@ <nTop>, <nLeft>, <nBottom>, <nRight>
   GET <nVar|cVar>
   LISTBOX <aList>
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [COLOR <cColorString>]
      [FOCUS <fblock>]
      [STATE <bBlock>]
      [DROPDOWN]
      [SCROLLBAR]
      [SEND <msg>]
      [GUISEND <guimsg>]
      [BITMAP <cBitmap>]

Arguments

nTop, nLeft, nBottom and nRight specify the screen position for the list box and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.

GET nVar|cVar specifies the name of the variable associated with the GET. Its value indicates which item (if any) in the list is selected. A numeric value refers to the position in the list of the selected item. A value of 0 indicates no selected item. A character string value refers to the data or text contained within the selected item. A character string that does not refer to any item in the list indicates no selected item.

LISTBOX aList specifies an array that contains the items in the list. The array may be either a single- or two-dimensional array. Use a single-dimension array when the data being displayed is the same as the data being saved; otherwise, use a two-dimensional array. In this case, the data in the first element of each subarray is displayed and the data in the second element is used for determining which item is selected.

CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse’s left button is clicked and its cursor is on the caption. By default, the caption appears to the left of the GET. Use the Get object’s capRow or capCol variable to change the screen position of the caption.

When present, the & character specifies that the character immediately following it in the caption is the list box’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the list box. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.

MESSAGE cMessage specifies a character string that is displayed on the Get system’s status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system’s status bar.

WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

COLOR cColorString defines the color settings for the list box. cColorString is a character expression containing exactly seven color settings if there is no drop-down list box, and eight if there is a drop-down list box.

ListBox Color Attributes

    Position     Applies To                             Default Value from

    in colorSpec                                        System Color Setting

    1            List box items that are not selected     Unselected

                 when the list does not have input focus

    2            The selected list box item when the      Unselected

                 List does not have input focus

    3            List box items that are not selected     Unselected

                 when the list has input focus

    4            The selected list box item when the      Enhanced

                 list has input focus

    5            The list box’s border                    Border

    6            The list box’s caption                   Standard

    7            The list box caption’s accelerator key   Background

    8            The list box’s drop-down button          Standard

Note: In graphic mode, colorSpec position 8 has no affect and is ignored.

FOCUS fblock specifies a code block that is evaluated each time the list box receives focus. The code block takes no implicit arguments. Use the PushButton:hasFocus instance variable to determine if the push button has focus.

STATE bBlock specifies a code block that is evaluated immediately after the list box object’s selection changes. The code block takes no implicit arguments. Use the ListBox:buffer instance variable to determine the current selection.

DROPDOWN indicates that the list box will be a drop-down list box. Drop-down list boxes are displayed differently on the screen than regular list boxes. A regular list box is always displayed regardless of whether it has input focus. A drop-down list box’s display behavior is determined by whether it is closed or open. By default, a drop-down list box is closed. In this case, only the caption, the selected item, and the open button are displayed.

When open, the actual list box is displayed in addition to the caption, selected item, and open button.

Drop-down list boxes are useful in situations where screen space is limited.

SCROLLBAR indicates that the list box will be created with a scroll bar whether or not it is needed. Normally a scroll bar is not needed if the data being displayed fits inside the list box.

SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.

GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.

BITMAP cBitmap defines the bitmap that will be used as the down arrow on a drop-down list box. Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.

CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed.

Examples

■  This example demonstrates how to add a list box to a data
   entry screen.  It utilizes the position-oriented method of selection:

   nColor := 1     //default to the first item.
   @ 5, 20, 8, 28 GET nColor LISTBOX { "Red", Green", "Blue" }

■  This example demonstrates a list box that has a caption and a
   message.  It utilizes the data-oriented method of selection:

   cColor := "Red" //default to red.
   @ 5, 20, 8, 28 GET cColor LISTBOX { "Red", Green", "Blue" };
           CAPTION "&Color" ;
           MESSAGE "Select the background color"

■  This example demonstrates a list box that utilizes a two-
   dimensional array.

   cState := "NY"

   @ 5, 20, 10, 30 GET cState LISTBOX { { "Alabama", "AL" }, ;
                                { "Alaska", AK" }   , ;
                                { "Arizona", "AZ" }, ;
                                { etc...          } } ;
           CAPTION "&State" ;
           MESSAGE "Select the client's state"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

@...GET PUSHBUTTONHarbour implementation⌃ | ☰

Create a new push button Get object and display it to the screen

Syntax

@ <nRow>, <nCol>
   GET <lVar>
   PUSHBUTTON
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [COLOR <cColorString>]
      [FOCUS <fblock>
      [STATE <bBlock>]
      [STYLE <cStyle>]
      [SEND <msg>]
      [GUISEND <guimsg>]
      [SIZE X <nSizeX> Y <nSizeY>]
      [CAPOFF X <nCapXOff> Y <nCapYOff>]
      [BITMAP <cBitmap>]
      [BMPOFF X <nBmpXOff> Y <nBmpYOff>]

Arguments

nRow and nCol specify the row and column coordinates for the push button and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.

GET lVar specifies the name of the variable associated with the GET. lVar may contain a value of any type, but upon return from the READ, will always contain logical false (.F.). The purpose of lVar is to provide a place holder in the GetList for the push button.

CAPTION cCaption specifies a character string that concisely describes the GET on the screen. caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position, is maintained within the Get object. This allows the GET to receive input when the mouse’s left button is clicked and its cursor is on the caption. By default, the caption appears within the push button’s border. Use the Get object’s capRow or capCol variable to change the screen position of the caption.

When present, the & character specifies that the character immediately following it in the caption is the push button’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the push button. The case of an accelerator key is ignored.

MESSAGE cMessage specifies a character string that is displayed on the Get system’s status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system’s status bar.

WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

COLOR cColorString defines the color settings for the push button. cColorString is a character expression containing exactly four color settings.

PushButton Color Attributes

    Position     Applies To                             Default Value from

    in colorSpec                                        System Color Setting

    1            The push button when it does not have    Unselected

                 input focus

    2            The push button when it has input focus  Enhanced

                 and is not pressed

    3            The push button when it has input focus  Standard

                 and is pressed

    4            The push button caption’s accelerator    Background

                 key

Note: The background colors of the PushButton Color Attributes are ignored in graphic mode.

FOCUS fblock specifies a code block that is evaluated each time the push button recieves focus. The code block takes no implicit arguments. Use the PushButton:hasFocus instance variable to determine if the push button has focus.

STATE bBlock specifies a code block that is evaluated each time the push button object’s state changes. The code block takes no implicit arguments. Use the PushButton:buffer instance variable to determine if the push button is pressed or released. A value of true (.T.) indicates that it is being pressed; otherwise, a value of false (.F.) indicates that it is being released.

STYLE cStyle specifies a character string that indicates the delimiter characters that are used by the push button’s display() method. When specified, the string must contain either zero, two, or eight characters. The default is two characters. The first is the left delimiter. Its default value is the less than () character. The second character is the right delimiter. Its default value is the greater than () character.

When the style string is empty, the button has no delimiters. When the string length is two, the button has left and right delimiters and occupies one row on the screen. The first character is the left delimiter. The second character is the right delimiter. When the string length is eight, the button is contained within a box that occupies three rows on the screen.

Standard Box Types

    Constant            Description

    B_SINGLE            Single-line box

    B_DOUBLE            Double-line box

    B_SINGLE_DOUBLE     Single-line top/bottom, double-line sides

    B_DOUBLE_SINGLE     Double-line top/bottom, single-line sides

Box.ch contains manifest constants for the PushButton:style value.

The default style for the @...GET PUSHBUTTON is «<>».

Note: The Style clause is ignored in graphic mode.

SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.

GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.

SIZE X nSizeX Y nSizeY defines the size of the button to be displayed. The coordinates are in pixels. nSizeX represents the number of pixels in the x direction (horizontally) and nSizeY represents the number of pixels in the y direction (vertically). This argument only affects applications running in graphic mode and is ignored in text mode.

CAPOFF X nCapXOff Y nCapYOff defines the offset where the caption is displayed. The coordinates are in pixels. nCapXOff represents the number of pixels in the x direction (horizontally) from the left edge of the button where the caption will be displayed. nCapYOff represents the number of pixels in the y direction (vertically) from the top edge of the button where the caption will be displayed. If the CAPOFF clause is not supplied, the caption will be centered on the button. This argument only affects applications running in graphic mode and is ignored in text mode.

BITMAP cBitmap defines a bitmap file to be displayed on the button. Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.

CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed.

BMPOFF X nBmpXOff Y nBmpYOff defines the offset where the bitmap is displayed. The coordinates are in pixels. nCapXOff represents the number of pixels in the x direction (horizontally) from the left edge where the bitmap will be displayed. nCapYOff represents the number of pixels in the y direction (vertically) from the top edge where the bitmap will be displayed. If the BMPOFF clause is not supplied, the bitmap will be placed at the upper-left corner of the button. This argument only affects applications running in graphic mode and is ignored in text mode.

Examples

■  This example demonstrates how to add a push button to a data
   entry screen:

   @ 5, 20 GET lCancel PUSHBUTTON ;
           CAPTION "&Cancel"
           STATE { || ReadKill( .T. ) }

Platforms

Available on MS-DOS

File

Libraries are CLIPPER.LIB and LLIBG.LIB.

See also

@...GET RADIOGROUPHarbour implementation⌃ | ☰

Create a new radio button group Get object and display it to the screen

Syntax

@ <nTop>, <nLeft>, <nBottom>, <nRight>
   GET <nVar|cVar>
   RADIOGROUP <aGroup>
      [CAPTION<cCaption>]
      [MESSAGE <cMessage>]
      [COLOR <cColorString>]
      [FOCUS] <fblock>
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [SEND <msg>]
      [GUISEND <guimsg>]

Arguments

nTop, nLeft, nBottom and nRight specify the screen position for the radio button group and its caption. Output which extends beyond the visible extent of the display is clipped and does not appear.

GET nVar|cVar specifies the name of the variable associated with the GET. Its value indicates which radio button (if any) in the group is selected. A numeric value refers to the position in the group of the selected button. A value of 0 indicates no selected button. A character string value refers to the data or text contained within the selected button. A character string that does not refer to any item in the list indicates no selected item.

RADIOGROUP aGroup specifies an array of RadioButto objects.

CAPTION cCaption specifies a character string that concisely describes the GET on the screen. Caption differs from the SAY argument in two ways. The first is that the caption is displayed each time the GET is shown on the screen. The other difference is that the caption, along with its screen position is maintained within the Get object. This allows the GET to receive input when the mouse’s left button is clicked and its cursor is on the caption. By default, the caption appears in the top-left border of the GET. Use the Get object’s capRow or capCol variable to change the screen position of the caption.

When present, the & character specifies that the character immediately following it in the caption is the radio group’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the radio group. The case of an accelerator key is ignored.

MESSAGE cMessage specifies a character string that is displayed on the Get system’s status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system’s status bar.

COLOR cColorString defines the color settings for the radio button group. cColorString is a character expression containing exactly three color settings.

RadioGroup Color Attributes

    Position     Applies To                             Default Value from

    in colorSpec                                        System Color Setting

    1            The radio group’s border                   Border

    2            The radio group’s caption                  Standard

    3            The radio group caption’s accelerator key  Background

FOCUS fblock specifies a code block that is evaluated each time the radio button group receives focus. The code block takes no implicit arguments. Use the RadioGroup:hasFocus instance variable to determine if the radio group has focus.

WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

Note: There is no STATE clause for the @...GET RADIOGROUP command. Instead each radio button in the group can have its own sBlock instance variable. See sBlock under RadioButto class for more details.

SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.

GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.

Examples

■  This example demonstrates how to add a radio button group to a
   data entry screen.  It utilizes a position-oriented method of
   selection:

   nColor := 1            //default to the first item.
   aGroup := Array( 3 )
   aGroup[ 1 ] := RadioButto( 6, 22, "&Red" )
   aGroup[ 2 ] := RadioButto( 7, 22, "&Green" )
   aGroup[ 3 ] := RadioButto( 8, 22, "&Blue" )
   @ 5, 20, 9, 40 GET nColor RADIOGROUP aGroup

  The nColor variable will return a position, in this case 1, 2, or 3.

■  This example demonstrates a radio button group that utilizes a
   data-oriented method of selection:

   cColor := "R"          //default to red.
   aGroup := Array( 3 )
   aGroup[ 1 ] := RadioButto( 6, 22, "&Red", "R" )
   aGroup[ 2 ] := RadioButto( 7, 22, "&Green", "G" )
   aGroup[ 3 ] := RadioButto( 8, 22, "&Blue", "B" )
   @ 5, 15, 9, 40 GET cColor RADIOGROUP aGroup

  The nColor variable will return data, in this case "R", "G", or "B".

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

@...GET TBROWSEHarbour implementation⌃ | ☰

Create a new TBrowse Get object and display it to the screen

Syntax

@ <nTop>, <nLeft>, <nBottom>, <nRight>
   GET <idVar>
   TBROWSE <oBrowse>
      [MESSAGE <cMessage>]
      [WHEN <lPreExpression>]
      [VALID <lPostExpression>]
      [SEND <msg>]
      [GUISEND <guimsg>]

Arguments

nTop, nLeft, nBottom and nRight specify the screen position for the TBrowse object. Output which extends beyond the visible extent of the display is clipped and does not appear.

GET idVar specifies the name of the variable associated with the GET. Its value is neither queried nor modified by the Get system. The GET is merely a mechanism used for integrating a TBrowse object into the @...GET/READ system.

TBROWSE oTBrowse specifies a previously defined TBrowse object.

MESSAGE cMessage specifies a character string that is displayed on the Get system’s status bar line when the GET has input focus. Typically, it describes the anticipated contents or user response of the GET. Refer to the READ command for details pertaining to the Get system’s status bar.

WHEN lPreExpression specifies an expression that must be satisfied before the cursor can enter the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

VALID lPostExpression specifies an expression that must be satisfied before the cursor can leave the GET during a READ. The expression can optionally be a code block. The Get object is passed as a parameter to the code block.

SEND msg sends the specified message to the Get object. msg is sent before the GET is displayed. Any message can be sent, including method calls and instance variable assignments. Method calls must include parentheses even if no arguments are passed.

GUISEND guimsg can be used to send a message (such as the display() method) to a GUI object. The GUI objects available in CA-Clipper are check boxes, list boxes, push buttons, and radio button groups. To send a message to a non-GUI object, such as standard GETs and TBrowses, use the SEND clause.

Examples

■  This example demonstrates how to add a TBrowse object to a
   data entry screen:

   oTB := TBrowseDB( 10, 10, 15, 40 )
   oTB:AddColumn(TBColumnNew("Last Name",{||Customer->lName}))
   oTB:AddColumn(TBColumnNew("First Name",{||Customer->fName}))
   oTB:AddColumn(TBColumnNew("Phone",{||Customer->Phone}))
   uDummy := NIL
   @ 10, 10, 15, 40 GET uDummy TBROWSE oTB

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

@...PROMPTHarbour implementation⌃ | ☰

Paint a menu item and define a message

Syntax

@ <nRow>, <nCol> PROMPT <cMenuItem>
   [MESSAGE <cExpression>]

Arguments

nRow and nCol are the row and column coordinates of the menu item display. Row values can range from zero to MaxRow(), and column values can range from zero to MaxCol().

PROMPT cMenuItem is the menu item string to display.

MESSAGE cExpression defines the message to display each time the current menu item is highlighted. A code block evaluating to a character expression may optionally be used.

Description

@...PROMPT is the display portion of the CA-Clipper lightbar menu system. Each @...PROMPT command paints a menu item in the current standard color and defines an associated MESSAGE to be displayed on the line specified by SET MESSAGE. The lightbar menu is then invoked with MENU TO. You can specify menu items in any order and configuration of row and column position. MENU TO, however, navigates the current list of menu items in the order they were defined. You can define up to 4096 menu items for each menu.

After each @...PROMPT command, the cursor is located one column position to the right of the last menu item character and Row() and Col() are updated to reflect the new cursor position. This lets you use Row() and Col() to specify consecutive menu item positions relative to the first one painted. See the example below.

Examples

■  This example displays a lightbar menu with the associated
   messages displayed on the next line.  When the user presses Return,
   the position of the item in the list of menu items is assigned to
   nChoice:

   LOCAL nChoice := 1
   SET WRAP ON
   SET MESSAGE TO 2
   @ 1, 3 PROMPT "File" MESSAGE "Access data files"
   @ Row(), Col() + 2 PROMPT "Edit" ;
      MESSAGE "Edit current record"
   MENU TO nChoice

■  This example shows how to pass the MESSAGE clause a code block
   which calls a user-defined function that displays a message in a
   different color:

   SET COLOR TO gr+/b,r+/n
   SET MESSAGE TO 23    // This is necessary.
   CLEAR SCREEN

   @ 3,4 PROMPT "one "  MESSAGE {||UDF("Message One  ")}
   @ 4,4 PROMPT "two "  MESSAGE {||UDF("Message Two  ")}
   @ 5,4 PROMPT "three" MESSAGE {||UDF("Message Three")}

   MENU TO test

   FUNCTION UDF(cParm)
   cOldColor := SetColor("w+/n")
   @ 22,1 SAY cParm        // Must be different row than the
                           // SET MESSAGE TO nRow
   SetColor(cOldColor)
   RETURN ""               // Character string must be returned

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

@...SAYHarbour implementation⌃ | ☰

Display data at a specified screen or printer row and column

Syntax

@ <nRow>, <nCol>
   SAY <exp> [PICTURE <cSayPicture>]
   [COLOR <cColorString>]

Arguments

nRow and nCol are the row and column coordinates of the display. Row values can range from zero to a maximum of MaxRow(), if the current DEVICE is the SCREEN, or 32,766, if the current DEVICE is the PRINTER. Also, column values can range from zero to a maximum of MaxCol() or 32,766 if the current DEVICE is the PRINTER.

SAY exp displays the result of a character, date, logical, or numeric expression to the current DEVICE.

PICTURE cSayPicture defines the formatting control for the display of exp. CA-Clipper provides two mechanisms, functions and templates, to control formatting. Functions apply to an entire SAY, while templates format characters position by position.

COLOR cColorString defines the display color of exp. If not specified, exp displays in the standard color as defined by SetColor(). cColorString is a character expression containing the standard color setting. If you specify a literal color setting, it must be enclosed in quote marks.

On a combined @...SAY...GET command, two COLOR clauses are required to specify colors for both the SAY and the GET: one for the SAY and one for the GET.

Description

@...SAY is a full-screen command that outputs the results of exp to either the screen or the printer at the specified row and column coordinates. It can optionally format output using the PICTURE clause. @...SAY creates data entry screens or reports that can be sent to the screen or printer.

When an @...SAY command executes , the output from exp is sent to the current device defined with SET DEVICE. The current DEVICE can be the SCREEN or PRINTER. Unlike console commands, @...SAY output to the printer is not echoed to the screen and SET CONSOLE has no effect on @...SAY output to the screen.

If the current DEVICE is the SCREEN (the system default), @...SAY displays output to the screen leaving the cursor one column position to the right of the last character displayed. Row() and Col() are then updated with this position. Output that displays off the screen, as defined by MaxRow() and MaxCol(), is clipped and the cursor is positioned beyond the visible screen. All @...SAY output displays are in standard color. Refer to the SetColor() reference in this chapter for more information on color.

If the current DEVICE is set to PRINTER, the display is directed to the printer at the specified nRow and nCol position. If the current MARGIN value is greater than zero, it is added to nCol first. The printhead is then advanced one column position to the right of the last character output and PRow() and PCol() are updated. @...SAY commands to the printer behave differently from those to the screen if output is addressed to a printer row or column position less than the current PRow() and PCol() values:

■ If nRow is less than PRow(), an automatic EJECT (Chr(12)) is

sent to the printer followed by the number of linefeed characters (Chr(10)) required to position the printhead on nRow on the following page

■ If nCol including the SET MARGIN value is less than PCol(),

a carriage return character (Chr(13)) and the number of spaces required to position exp at nCol are sent to the printer

To override this behavior and send control codes to the printer, or for any other reason, you can use SetPRC() to reset PRow() and PCol() to new values. See the SetPRC() function reference for more information.

If the current DEVICE is the PRINTER, redirect output from @...SAY commands to a file using the SET PRINTER TO xcFile command.

@...SAY command output can be formatted using the PICTURE clause with a cSayPicture. This performs the same action as the Transform() function. A cSayPicture may consist of a function and/or a template. A PICTURE function imposes a rule on the entire @...SAY output. A PICTURE template defines the length of the @...SAY output and the formatting rule for each position within the output.

■ Function string: A PICTURE function string specifies

formatting rules which apply to the SAY‘s entire display value, rather than to particular character positions within it. The function string consists of the @ character, followed by one or more additional characters, each of which has a particular meaning (see table below). The function string must not contain spaces. A function string may be specified alone or with a template string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

SAY and Transform() PICTURE Format Functions

       Function     Action

       B            Displays numbers left-justified

       C            Displays CR after positive numbers

       D            Displays dates in SET DATE format

       E            Displays dates and numbers in British format

       R            Nontemplate characters are inserted

       X            Displays DB after negative numbers

       Z            Displays zeros as blanks

       (            Encloses negative numbers in parentheses

       !            Converts alphabetic characters to uppercase

■ Template string: A PICTURE template string specifies

formatting rules on a character-by-character basis. The template string consists of a series of characters, some of which have special meanings (see table below). Each position in the template string corresponds to a position in the displayed SAY value. Characters in the template string that do not have assigned meanings are copied verbatim into the displayed SAY value. If you use the @R picture function, characters without special PICTURE template string meaning are inserted between characters of the display value; otherwise, they overwrite the corresponding characters of the display value. You may specify a template string alone or with a function string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

SAY and Transform() Template Symbols

       Template     Action

       A,N,X,9,#    Displays digits for any data type

       L            Displays logicals as «T» or «F»

       Y            Displays logicals as «Y» or «N»

       !            Converts alphabetic characters to uppercase

       $            Displays a dollar sign in place of a leading space in a

                    number

       *            Displays an asterisk in place of a leading space in a

                    number

       .            Specifies a decimal point position

       ,            Specifies a comma position

Examples

■  This example uses an @...SAY with a PICTURE clause to display
   formatted output:

   nNetIncome = 7125.50
   nNetLoss = -125.50
   cPhone = "2134567890"
   cName = "Kate Mystic"
   //
   @ 1, 1 SAY nNetIncome PICTURE "@E 9,999.99"
   // Result: 7.125,50

   @ 2, 1 SAY nNetLoss PICTURE "@)"
   // Result: (125.50)

   @ 3, 1 SAY cPhone PICTURE "@R (999)999-9999"
   // Result: (213)456-7890

   @ 4, 1 SAY cName PICTURE "@!"
   // Result: KATE MYSTIC

■  This example is a small label printing program that uses SET
   DEVICE to direct output to the printer and SetPRC() to suppress
   automatic EJECTs:

   USE Salesman INDEX Salesman NEW
   SET DEVICE TO PRINTER
   DO WHILE !Eof()                     // Print all records
      @ 2, 5 SAY RTrim(FirstName) + ", " + LastName
      @ 3, 5 SAY Street
      @ 4, 5 SAY RTrim(City) + ", " + State + "  " + ;
               PostalCode
      @ 6, 0 SAY Space(1)            // Move to label bottom
      SetPRC(0, 0)                   // Suppress page eject
      SKIP                           // Next record
   ENDDO
   SET DEVICE TO SCREEN
   CLOSE Salesman

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

@...TOHarbour implementation⌃ | ☰

Draw a single- or double-line box

Syntax

@ <nTop>, <nLeft>
   TO <nBottom>, <nRight> [DOUBLE] [COLOR <cColorString>]

Arguments

nTop, nLeft, nBottom, and nRight define the coordinates of the box. @...TO draws the box using row values from zero to MaxRow() and column values from zero to MaxCol(). nBottom and nRight can be larger than the screen size, but output is clipped at MaxRow() and MaxCol().

DOUBLE draws the box with a double line. If not specified, the box is drawn with a single line.

COLOR cColorString defines the display color of the drawn box. If not specified, the box is drawn using the standard color setting of the current system color as defined by SetColor(). Note that cColorString is a character expression containing the standard color setting. If you specify a literal color setting, enclose it within quote marks.

Description

@...TO draws a single- or double-line box on the screen. If nTop and nBottom are the same, a horizontal line is drawn. If nLeft and nRight are the same, a vertical line is drawn.

After @...TO finishes drawing, the cursor is located in the upper-left corner of the boxed region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.

@...TO is like @...BOX except that @...BOX lets you define the characters of the box and supports a fill character. @...TO, however, is recommended for portability since it does not require the specification of hardware-dependent graphics characters.

Examples

■  This example erases a region of the screen, then draws a box
   of the same size:

   @ 10, 10 CLEAR TO 20, 40
   @ 10, 10 TO 20, 40 DOUBLE COLOR "BG+/B"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

$⌃ | ☰

Substring comparison—binary (Relational)

Syntax

Description

The $ operator is a binary relational operator that performs a case- sensitive substring search and returns true (.T.) if cString1 is found within cString2.

Examples

■  This example illustrates the case-sensitivity of the substring
   operator ($):

   ? "A" $ "ABC"            // Result: .T.
   ? "a" $ "ABC"            // Result: .F.

Platforms

Available on MS-DOS

See also

<, <=, <> != #, = (equality), ==, >, >=

*⌃ | ☰

Multiplication—binary (Mathematical)

Syntax

Description

The multiplication operator (*) is a binary operator that returns a numeric value from its operation on nNumber1 and nNumber2.

Examples

■  This example shows multiplication results using different
   operands:

   ?  3 *  0            // Result:  0
   ?  3 * -2            // Result: -6
   ? -3 *  2            // Result: -6
   ? -3 *  0            // Result:  0
   ? -1 *  3            // Result: -3
   ? -2 * -3            // Result:  6
   ?  2 * -3            // Result: -6
   ?  1 * -3            // Result: -3

Platforms

Available on MS-DOS

See also

**⌃ | ☰

Exponentiation—binary (Mathematical)

Syntax

<nNumber1> ** <nNumber2>
<nNumber1> ^  <nNumber2>

Description

The exponentiation operator (**) is a binary operator that raises nNumber1 to the power of nNumber2.

Examples

■  This example shows exponentiation results to 16 decimal
   places, using different operands:

   SET DECIMALS TO 16
   ?  3 **  0            // Result:  1.000000000
   ?  3 **  1            // Result:  3.000000000
   ?  3 ** -2            // Result:  0.111111111
   ? -3 **  2            // Result:  9.000000000
   ? -3 **  0            // Result:  1.000000000
   ? -1 **  3            // Result: -1.000000000
   ? -2 **  3            // Result: -8.000000000
   ?  2 ** -3            // Result:  0.125000000
   ?  1 ** -3            // Result:  1.000000000

Platforms

Available on MS-DOS

See also

&⌃ | ☰

Macro evaluation—unary (Special)

Syntax

&<cMacroVar>[.]
&(<cMacroExp>)

Description

The macro operator in CA-Clipper is a special operator that allows runtime compilation of expressions and text substitution within strings. Whenever the macro operator (&) is encountered, the operand is submitted to a special runtime compiler (the macro compiler) that compiles expressions, but not statements or commands.

Text Substitution

Whenever a reference to a private or public macro variable, embedded in a character string, is encountered, the variable reference is replaced by the content of the macro variable. For example,

cMacro := «there» ? «Hello &cMacro» // Result: Hello there

If you specify a macro expression (e.g., &(cMacro1 + cMacro2)), and the macro variable is a local, static, field variable, or an array element, it is treated as literal text and not expanded.

Macro operator:nesting Compile and Run

When a macro variable or expression specified within an expression is encountered, it is treated like an expression, with the macro symbol behaving as the compile and run operator. If the macro is specified as a macro variable,

cMacro := «DToC(Date())» ? &cMacro

the macro compiler compiles, then executes the content of the macro variable. The compiled code is then discarded.

If you specify an expression enclosed in parentheses and prefaced by the macro operator (&),

? &(IndexKey(0))

the expression is evaluated and the resulting character string is compiled and run as a macro variable.

Using the macro operator, you can compile a character string containing a code block definition:

bBlock := &(«{ |exp| QOut(exp) }»)

The run portion of the operation returns the code block as a value. You may then use the code block by invoking it with the Eval() function. This is especially significant in activations that involve extensive looping through user-defined conditions (operations that in earlier versions of CA-Clipper required macro expansion). In those versions, the macro expression was compiled and run for each iteration of the loop. With the combination of a macro expansion and a code block Eval(), the compilation is performed once at compile time, and the Eval() merely executes the code block each time through the loop:

Eval(bBlock, Date())

The time savings at runtime can be enormous.

Notes

■ Command keywords: You cannot use the macro operator (&) to

substitute or compile command keywords. However, you can redefine command keywords by modifying the command definition in std.ch, overriding an existing command definition with a new definition using the #command directive, or redefining a command keyword using the #translate directive. In any case, you may redefine a command keyword only at compile time, not at runtime.

■ Command arguments: In prior versions of CA-Clipper as well as

in other dialects, you could use macro variables as the arguments of commands requiring literal text values. These included all file command arguments and SET commands with toggle arguments. In these instances, you can now use an extended expression enclosed in parentheses in place of the literal argument. For example,

xcDatabase = «Invoices» USE &xcDatabase.

can be replaced with:

xcDatabase = «Invoices» USE (xcDatabase)

It is important to use extended expressions if you are using local and static variables. Generally, commands are preprocessed into function calls with command arguments translated into function arguments as valid CA-Clipper values. File names in file commands, for instance, are stringified using the smart stringify result marker and passed as arguments to the functions that actually perform the desired actions. If you specify a literal or macro value as the command argument, it is stringified. If, however, the argument is an extended expression, it is written to the result text exactly as specified. This example,

#command RENAME xcOld TO xcNew; =>;

FRename( (xcOld), (xcNew) )

// RENAME &xcOld TO &xcNew RENAME (xcOld) TO (xcNew)

is written to the result text as this:

FRename( «&xcOld», «&xcNew» ) FRename( xcOld, xcNew )

when preprocessed. When the macro variables are stringified, the macro variable names are hidden in the string and not compiled. Later, at runtime, they are substituted into the string and passed as arguments to the FRename() function. This precludes local and static macro variables since the names of the variables are not present at runtime to be substituted. Public and private variables, however, behave as expected.

■ Lists as arguments of commands: The macro operator (&) will

not fully substitute or compile a list as an argument of most commands. In particular, these are commands where an argument list is preprocessed into an array or a code block. Instances of this are arguments of the FIELDS clause and SET INDEX. An exception is the SET COLOR command which preprocesses the list of colors into a single character string and passes it to the SetColor() function.

In any case, list arguments should always be specified as extended expressions with each list argument specified:

LOCAL xcIndex := { «Ntx1», «Ntx2» } SET INDEX TO (xcIndex[1]), (xcIndex[2])

■ Arrays: You can use the macro operator (&) with arrays and

array elements. However, because of the increased power of CA-Clipper arrays, you may find less need to use the macro operator (&) to make variable references to arrays. You can now assign array references to variables, return array references from user-defined functions, and nest array references within other arrays. You may also create arrays by specifying literal arrays or using the Array() function.

You can, therefore, make references to arrays and array elements using both macro variables and macro expressions with the restriction that you cannot make the subscript references in a PRIVATE or PUBLIC statement. Also, you cannot specify the macro operator (&) in a declaration statement, such as a LOCAL or STATIC statement. Attempting this will generate a fatal compiler error.

This example references array elements using macro variables:

cName := «aArray» nElements := 5 cNameElement := «aArray[1]» // PRIVATE &cName.[nElements] // Creates «array» with 5

// elements

&cNameElement. := 100 // Assigns 100 to element 1 &cName.[3] := «abc» // Assigns «abc» to element 3

You can successfully apply a macro operator (&) to an array element if the reference is made using a macro expression. A macro variable reference, however, will generate a runtime error. For example, the following lists the values of all fields of the current record:

USE Customer NEW aStruc := dbStruct() // FOR nField := 1 TO Len(aStruc)

? &(aStruc[nField, 1])

NEXT

■ Code blocks: You can apply the macro operator (&) to a macro

variable or expression in a code block in most cases. There is a restriction when the macro variable or macro expression contains a declared variable. A runtime error occurs if you specify a complex expression (an expression that contains an operator and one or more operands) that includes the macro operator (&) within a code block.

This has important implications for the use of local and static variables in the conditional clauses of commands, since these clauses are blockified as they are written to the result text during preprocessing. This applies to all FOR and WHILE clauses, the SET FILTER command, and the SET RELATION linking expression. The general workaround is to gather the entire expression into a single macro variable then apply the macro operator (&) to the variable.

■ Macro conditions: When using the macro operator (&) to specify

conditional clauses of database commands such as FOR or WHILE clauses, there are some restrictions based on the expression’s complexity and size:

— The maximum string size the macro compiler can process is 254

characters.

— There is a limit to the complexity of conditions (the more

complex, the fewer the number of conditions you can specify).

■ Procedures and functions: You can reference procedure and

function calls using macro variables and expressions. With DO, the macro variable reference to the procedure can be all or part of the procedure name. With a call to a function (built-in or user- defined), the macro variable reference must include the function name and all of its arguments.

In CA-Clipper, because of the added facility code blocks, all invocations of procedures and functions using the macro operator should be converted to the evaluation of code blocks. This code fragment

cProc := «AcctsRpt» . . . DO &cProc

can be replaced with:

bProc := &( «{ || AcctsRpt() }» ) . . . Eval(bProc)

The advantage of a code block over a macro evaluation is that the result of the compilation of a string containing a code block can be saved and, therefore, need only be compiled once. Macro evaluations compile each time they are referenced.

■ References into overlays: You must declare procedures and

user-defined functions that are used in macro expressions and variables but not referenced elsewhere as EXTERNAL, or the linker will not include them into the executable (.EXE) file.

TEXT...ENDTEXT: Macro variables referenced within a

TEXT...ENDTEXT construct are expanded. Note that a field cannot be expanded, so you must first assign the field value to a memory variable then reference the memory variable as a macro variable within the TEXT...ENDTEXT. For example:

USE Customer NEW myVar := Customer->CustName TEXT This is text with a macro &myVar ENDTEXT

■ Nested macros: The processing of macro variables and

expressions in CA-Clipper permits nested macro definitions. For example, after assigning a macro variable to another macro variable, the original macro variable can be expanded resulting in the expansion of the second macro variable and evaluation of its contents:

cOne = «&cTwo» // expand cTwo cTwo = «cThree» // yielding «cThree» cThree = «hello» // ? &cOne // Result: «hello»

Platforms

Available on MS-DOS

See also

#command | #translate⌃ | ☰

Specify a user-defined command or translation directive

Syntax

#command   <matchPattern> => <resultPattern>
#translate   <matchPattern> => <resultPattern>

Arguments

matchPattern is the pattern the input text should match.

resultPattern is the text produced if a portion of input text matches the matchPattern.

The => symbol between matchPattern and resultPattern is, along with #command or #translate, a literal part of the syntax that must be specified in a #command or #translate directive. The symbol consists of an equal sign followed by a greater than symbol with no intervening spaces. Do not confuse the symbol with the >= or the <= comparison operators in the CA-Clipper language.

Description

#command and #translate are translation directives that define commands and pseudofunctions. Each directive specifies a translation rule. The rule consists of two portions: a match pattern and a result pattern. The match pattern matches a command specified in the program (.prg) file and saves portions of the command text (usually command arguments) for the result pattern to use. The result pattern then defines what will be written to the result text and how it will be written using the saved portions of the matching input text.

#command and #translate are similar, but differ in the circumstance under which their match patterns match input text. A #command directive matches only if the input text is a complete statement, while #translate matches input text that is not a complete statement. #command defines a complete command and #translate defines clauses and pseudofunctions that may not form a complete statement. In general, use #command for most definitions and #translate for special cases.

#command and #translate are similar to but more powerful than the #define directive. #define, generally, defines identifiers that control conditional compilation and manifest constants for commonly used constant values such as Inkey() codes. Refer to any of the header files in the CLIP53INCLUDE directory for examples of manifest constants defined using #define.

#command and #translate directives have the same scope as the #define directive. The definition is valid only for the current program (.prg) file unless defined in std.ch or the header specified with the /U option on the compiler command line. If defined elsewhere, the definition is valid from the line where it is specified to the end of the program file. Unlike #define, a #translate or #command definition cannot be explicitly undefined. The #undef directive has no effect on a #command or #translate definition.

As the preprocessor encounters each source line preprocessor, it scans for definitions in the following order of precedence: #define, #translate, and #command. When there is a match, the substitution is made to the result text and the entire line is reprocessed until there are no matches for any of the three types of definitions. #command and #translate rules are processed in stack-order (i.e., last in-first out, with the most recently specified rule processed first).

In general, a command definition provides a way to specify an English language statement that is, in fact, a complicated expression or function call, thereby improving the readability of source code. You can use a command in place of an expression or function call to impose order of keywords, required arguments, combinations of arguments that must be specified together, and mutually exclusive arguments at compile time rather than at runtime. This can be important since procedures and user-defined functions can now be called with any number of arguments, forcing any argument checking to occur at runtime. With command definitions, the preprocessor handles some of this.

All commands in CA-Clipper are defined using the #command directive and supplied in the standard header file, std.ch, located in the CLIP53INCLUDE directory. The syntax rules of #command and #translate facilitate the processing of all CA-Clipper and dBASE-style commands into expressions and function calls. This provides CA-Clipper compatibility, as well as avenues of compatibility with other dialects.

When defining a command, there are several prerequisites to properly specifying the command definition. Many preprocessor commands require more than one #command directive because mutually exclusive clauses contain a keyword or argument. For example, the @...GET command has mutually exclusive VALID and RANGE clauses and is defined with a different #command rule to implement each clause.

This also occurs when a result pattern contains different expressions, functions, or parameter structures for different clauses specified for the same command (e.g., the @...SAY command). In std.ch, there is a #command rule for @...SAY specified with the PICTURE clause and another for @...SAY specified without the PICTURE clause. Each formulation of the command is translated into a different expression. Because directives are processed in stack order, when defining more than one rule for a command, place the most general case first, followed by the more specific ones. This ensures that the proper rule will match the command specified in the program (.prg) file.

For more information and a general discussion of commands, refer to the «Basic Concepts» chapter in the Programming and Utilities Guide.

Match Pattern

The matchPattern portion of a translation directive is the pattern the input text must match. A match pattern is made from one or more of the following components, which the preprocessor tries to match against input text in a specific way:

■ Literal values are actual characters that appear in the match

pattern. These characters must appear in the input text, exactly as specified to activate the translation directive.

■ Words are keywords and valid identifiers that are compared

according to the dBASE convention (case-insensitive, first four letters mandatory, etc.). The match pattern must start with a Word.

#xcommand and #xtranslate can recognize keywords of more than four significant letters.

■ Match markers are label and optional symbols delimited by

angle brackets (<>) that provide a substitute (idMarker) to be used in the resultPattern and identify the clause for which it is a substitute. Marker names are identifiers and must, therefore, follow the CA-Clipper identifier naming conventions. In short, the name must start with an alphabetic or underscore character, which may be followed by alphanumeric or underscore characters.

This table describes all match marker forms:

Match Markers

       Match Marker             Name

       <idMarker>               Regular match marker

       <idMarker,…>           List match marker

       <idMarker:word list>     Restricted match marker

       <*idMarker*>             Wild match marker

       <(idMarker)>             Extended Expression match marker

— Regular match marker: Matches the next legal expression in the

input text. The regular match marker, a simple label, is the most general and, therefore, the most likely match marker to use for a command argument. Because of its generality, it is used with the regular result marker, all of the stringify result markers, and the blockify result marker.

— List match marker: Matches a comma-separated list of legal

expressions. If no input text matches the match marker, the specified marker name contains nothing. You must take care in making list specifications because extra commas will cause unpredictable and unexpected results.

The list match marker defines command clauses that have lists as arguments. Typically these are FIELDS clauses or expression lists used by database commands. When there is a match for a list match marker, the list is usually written to the result text using either the normal or smart stringify result marker. Often, lists are written as literal arrays by enclosing the result marker in curly ({ }) braces.

— Restricted match marker: Matches input text to one of the

words in a comma-separated list. If the input text does not match at least one of the words, the match fails and the marker name contains nothing.

A restricted match marker is generally used with the logify result marker to write a logical value into the result text. If there is a match for the restricted match marker, the corresponding logify result marker writes true (.T.) to the result text; otherwise, it writes false (.F.). This is particularly useful when defining optional clauses that consist of a command keyword with no accompanying argument. std.ch implements the REST clause of database commands using this form.

— Wild match marker: Matches any input text from the current

position to the end of a statement. Wild match markers generally match input that may not be a legal expression, such as #command NOTE *x* in std.ch, gather the input text to the end of the statement, and write it to the result text using one of the stringify result markers.

— Extended expression match marker: Matches a regular or

extended expression, including a file name or path specification. It is used with the smart stringify result marker to ensure that extended expressions will not get stringified, while normal, unquoted string file specifications will.

■ Optional match clauses are portions of the match pattern

enclosed in square brackets ([ ]). They specify a portion of the match pattern that may be absent from the input text. An optional clause may contain any of the components allowed within a matchPattern, including other optional clauses.

Optional match clauses may appear anywhere and in any order in the match pattern and still match input text. Each match clause may appear only once in the input text. There are two types of optional match clauses: one is a keyword followed by match marker, and the other is a keyword by itself. These two types of optional match clauses can match all of the traditional command clauses typical of the CA-Clipper command set.

Optional match clauses are defined with a regular or list match marker to match input text if the clause consists of an argument or a keyword followed by an argument (see the INDEX clause of the USE command in std.ch). If the optional match clause consists of a keyword by itself, it is matched with a restricted match marker (see the EXCLUSIVE or SHARED clause of the USE command in std.ch).

In any match pattern, you may not specify adjacent optional match clauses consisting solely of match markers, without generating a compiler error. You may repeat an optional clause any number of times in the input text, as long as it is not adjacent to any other optional clause. To write a repeated match clause to the result text, use repeating result clauses in the resultPattern definition.

Result Pattern

The resultPattern portion of a translation directive is the text the preprocessor will produce if a piece of input text matches the matchPattern. resultPattern is made from one or more of the following components:

■ Literal tokens are actual characters that are written directly

to the result text.

■ Words are CA-Clipper keywords and identifiers that are written

directly to the result text.

■ Result markers: refer directly to a match marker name. Input

text matched by the match marker is written to the result text via the result marker.

This table lists the Result marker forms:

Result Markers

       Result Marker     Name

       <idMarker>        Regular result marker

       #<idMarker>       Dumb stringify result marker

       <«idMarker»>      Normal stringify result marker

       <(idMarker)>      Smart stringify result marker

       <{idMarker}>      Blockify result marker

       <.idMarker.>      Logify result marker

— Regular result marker: Writes the matched input text to the

result text, or nothing if no input text is matched. Use this, the most general result marker, unless you have special requirements. You can use it with any of the match markers, but it almost always is used with the regular match marker.

— Dumb stringify result marker: Stringifies the matched input

text and writes it to the result text. If no input text is matched, it writes a null string («»). If the matched input text is a list matched by a list match marker, this result marker stringifies the entire list and writes it to the result text.

This result marker writes output to result text where a string is always required. This is generally the case for commands where a command or clause argument is specified as a literal value but the result text must always be written as a string even if the argument is not specified.

— Normal stringify result marker: Stringifies the matched input

text and writes it to the result text. If no input text is matched, it writes nothing to the result text. If the matched input text is a list matched by a list match marker, this result marker stringifies each element in the list and writes it to the result text.

The normal stringify result marker is most often used with the blockify result marker to compile an expression while saving a text image of the expression (See the SET FILTER condition and the INDEX key expression in std.ch).

— Smart stringify result marker: Stringifies matched input text

only if source text is enclosed in parentheses. If no input text matched, it writes nothing to the result text. If the matched input text is a list matched by a list match marker, this result marker stringifies each element in the list (using the same stringify rule) and writes it to the result text.

The smart stringify result marker is designed specifically to support extended expressions for commands other than SETs with xlToggle arguments. Extended expressions are command syntax elements that can be specified as literal text or as an expression if enclosed in parentheses. The xcDatabase argument of the USE command is a typical example. For instance, if the matched input for the xcDatabase argument is the word Customer, it is written to the result text as the string «Customer,» but the expression (cPath + cDatafile) would be written to the result text unchanged (i.e., without quotes).

— Blockify result marker: Writes matched input text as a code

block without any arguments to the result text. For example, the input text x + 3 would be written to the result text as {|| x + 3}. If no input text is matched, it writes nothing to the result text. If the matched input text is a list matched by a list match marker, this result marker blockifies each element in the list.

The blockify result marker used with the regular and list match markers matches various kinds of expressions and writes them as code blocks to the result text. Remember that a code block is a piece of compiled code to execute sometime later. This is important when defining commands that evaluate expressions more than once per invocation. When defining a command, you can use code blocks to pass an expression to a function and procedure as data rather than as the result of an evaluation. This allows the target routine to evaluate the expression whenever necessary.

In std.ch, the blockify result marker defines database commands where an expression is evaluated for each record. Commonly, these are field or expression lists, FOR and WHILE conditions, or key expressions for commands that perform actions based on key values.

— Logify result marker: Writes true (.T.) to the result text if

any input text is matched; otherwise, it writes false (.F.) to the result text. This result marker does not write the input text itself to the result text.

The logify result marker is generally used with the restricted match marker to write true (.T.) to the result text if an optional clause is specified with no argument; otherwise, it writes false (.F.). In std.ch, this formulation defines the EXCLUSIVE and SHARED clauses of the USE command.

■ Repeating result clauses are portions of the resultPattern

enclosed by square brackets ([ ]). The text within a repeating clause is written to the result text as many times as it has input text for any or all result markers within the clause. If there is no matching input text, the repeating clause is not written to the result text. Repeating clauses, however, cannot be nested. If you need to nest repeating clauses, you probably need an additional #command rule for the current command.

Repeating clauses are the result pattern part of the #command facility that create optional clauses which have arguments. You can match input text with any match marker other than the restricted match marker and write to the result text with any of the corresponding result markers. Typical examples of this facility are the definitions for the STORE and REPLACE commands in std.ch.

Notes

■ Less than operator: If you specify the less than operator (`)

in the resultPattern expression, you must precede it with the escape character ().

■ Multistatement lines: You can specify more than one statement

as a part of the result pattern by separating each statement with a semicolon. If you specify adjacent statements on two separate lines, the first statement must be followed by two semicolons.

Examples

These examples encompass many of the basic techniques you can use when
defining commands with the #command and #translate directives.  In
general, these examples are based on standard commands defined in
Std.ch.  Note, however, the functions specified in the example result
patterns are not the actual functions found in std.ch, but fictitious
functions specified for illustration only.

■  This example defines the @...BOX command using regular match
   markers with regular result markers:

   #command  @ <top>, <left>, <bottom>, <right> BOX ;
         <boxstring>;
   =>;
         CmdBox( <top>, <left>, <bottom>, ;
         <right>,<boxstring> )

■  This example uses a list match marker with a regular result
   marker to define the ? command:

   #command ? [<list,...>] => QOut(<list>)

■  This example uses a restricted match marker with a logify
   result marker to implement an optional clause for a command
   definition.  In this example, if the ADDITIVE clause is specified,
   the logify result marker writes true (.T.) to the result text;
   otherwise, it writes false (.F.):

   #command RESTORE FROM <file> [<add: ADDITIVE>];
   =>;
         CmdRestore( <(file)>, <.add.> )

■  This example uses a list match marker with a smart stringify
   result marker to write to the result text the list of fields
   specified as the argument of a FIELDS clause.  In this example, the
   field list is written as an array with each field name as an element
   of the array:

   #command COPY TO <file> [FIELDS <fields,...>];
   =>;
         CmdCopyAll( <(file)>, { <(fields)> } )

■  These examples use the wild match marker to define a command
   that writes nothing to the result text.  Do this when attempting to
   compile unmodified code developed in another dialect:

   #command SET ECHO <*text*>    =>
   #command SET TALK <*text*>    =>

■  These examples use wild match markers with dumb stringify
   result markers to match command arguments specified as literals, then
   write them to the result text as strings in all cases:

   #command SET PATH TO <*path*>  =>  ;
      Set( _SET_PATH, #<path> )
   #command SET COLOR TO <*spec*> =>  SetColor( #<spec> )

■  These examples use a normal result marker with the blockify
   result marker to both compile an expression and save the text version
   of it for later use:

   #command SET FILTER TO <xpr>;
   =>;
         CmdSetFilter( <{xpr}>, <"xpr"> )

   #command INDEX ON <key> TO <file>;
   =>;
         CmdCreateIndex( <(file)>, <"key">, <{key}> )

■  This example demonstrates how the smart stringify result
   marker implements a portion of the USE command for those arguments
   that can be specified as extended expressions:

   #command USE <db> [ALIAS <a>];
   =>;
         CmdOpenDbf( <(db)>, <(a)> )

■  This example illustrates the importance of the blockify result
   marker for defining a database command.  Here, the FOR and WHILE
   conditions matched in the input text are written to the result text
   as code blocks:

   #command COUNT [TO <var>];
         [FOR <for>] [WHILE <while>];
         [NEXT <next>] [RECORD <rec>] [<rest:REST>] [ALL];
   =>;
         <var> := 0,;
         dbEval( {|| <var>++}, <{for}>, <{while}>,;
            <next>, <rec>, <.rest.> )

■  In this example the USE command again demonstrates the types
   of optional clauses with keywords in the match pattern.  one clause
   is a keyword followed by a command argument, and the second is solely
   a keyword:

   #command USE <db> [<new: NEW>] [ALIAS <a>] ;
         [INDEX <index,...>][<ex: EXCLUSIVE>] ;
         [<sh: SHARED>] [<ro: READONLY>];
   =>;
         CmdOpenDbf(<(db)>, <(a)>, <.new.>,;
            IF(<.sh.> .OR. <.ex.>, !<.ex.>, NIL),;
               <.ro.>, {<(index)>})

■  This example uses the STORE command definition to illustrate
   the relationship between an optional match clause and a repeating
   result clause:

   #command STORE <value> TO <var1> [, <varN> ];
   =>;
         <var1> := [ <varN> := ] <value>

■  This example uses #translate to define a pseudofunction:

   #translate AllTrim(<cString>) => LTrim(RTrim(<cString>))

Platforms

Available on MS-DOS

See also

#define⌃ | ☰

Define a manifest constant or pseudofunction

Syntax

#define <idConstant> [<resultText>]
#define <idFunction>([<arg list>]) [<exp>]

Arguments

idConstant is the name of an identifier to define.

resultText is the optional replacement text to substitute whenever a valid idConstant is encountered.

idFunction is a pseudofunction definition with an optional argument list (arg list). If you include arg list, it is delimited by parentheses (()) immediately following idFunction.

exp is the replacement expression to substitute when the pseudofunction is encountered. Enclose this expression in parentheses to guarantee precedence of evaluation when the pseudofunction is expanded.

Note: #define identifiers are case-sensitive, where #command and #translate identifiers are not.

Description

The #define directive defines an identifier and, optionally, associates a text replacement string. If specified, replacement text operates much like the search and replace operation of a text editor. As each source line from a program file is processed by the preprocessor, the line is scanned for identifiers. If a currently defined identifier is encountered, the replacement text is substituted in its place.

Identifiers specified with #define follow most of the identifier naming rules in CA-Clipper . Defined identifiers can contain any combination of alphabetic and numeric characters, including underscores. Defined identifiers, however, differ from other identifiers by being case- sensitive. As a convention, defined identifiers are specified in uppercase to distinguish them from other identifiers used within a program. Additionally, identifiers are specified with a one or two letter prefix to group similar identifiers together and guarantee uniqueness. Refer to one of the supplied header files in the CLIP53INCLUDE directory for examples.

When specified, each definition must occur on a line by itself. Unlike statements, more than one directive cannot be specified on the same source line. You may continue a definition on a subsequent line by employing a semicolon (;). Each #define directive is specified followed by one or more white space characters (spaces or tabs), a unique identifier, and optional replacement text. Definitions can be nested, allowing one identifier to define another.

A defined identifier has lexical scope like a filewide static variable. It is only valid in the program (.prg) file in which it is defined unless defined in std.ch or the header file specified on the compiler command line with the /U option. Unlike a filewide static variable, a defined identifier is visible from the point where it is defined in the program file until it is either undefined, redefined, or the end of the program file is reached.

You can redefine or undefine existing identifiers. To redefine an identifier, specify a new #define directive with the identifier and the new replacement text as its arguments. The current definition is then overwritten with the new definition, and a compiler warning is issued in case the redefinition is inadvertent. To undefine an identifier, specify an #undef directive with the identifier as its argument. #define directives have three basic purposes:

■ To define a control identifier for #ifdef and #ifndef

■ To define a manifest constant—an identifier defined to

represent a constant value

■ To define a compiler pseudofunction

The following discussion expands these three purposes of the #define directive in your program.

Preprocessor Identifiers

The most basic #define directive defines an identifier with no replacement text. You can use this type of identifier when you need to test for the existence of an identifier with either the #ifdef or #ifndef directives. This is useful to either exclude or include code for conditional compilation. This type of identifier can also be defined using the /D compiler option from the compiler command line. See the examples below.

Manifest Constants

The second form of the #define directive assigns a name to a constant value. This form of identifier is referred to as a manifest constant. For example, you can define a manifest constant for the Inkey() code associated with a key press:

#define K_ESC 27 IF LastKey() = K_ESC

. . statements .

ENDIF

Whenever the preprocessor encounters a manifest constant while scanning a source line, it replaces it with the specified replacement text.

Although you can accomplish this by defining a variable, there are several advantages to using a manifest constant: the compiler generates faster and more compact code for constants than for variables; and variables have memory overhead where manifest constants have no runtime overhead, thus saving memory and increasing execution speed. Furthermore, using a variable to represent a constant value is conceptually inconsistent. A variable by nature changes and a constant does not.

Use a manifest constant instead of a constant for several reasons. First, it increases readability. In the example above, the manifest constant indicates more clearly the key being represented than does the Inkey() code itself. Second, manifest constants localize the definition of constant values, thereby making changes easier to make, and increasing reliability. Third, and a side effect of the second reason, is that manifest constants isolate implementation or environment specifics when they are represented by constant values.

To further isolate the effects of change, manifest constants and other identifiers can be grouped together into header files allowing you to share identifiers between program (.prg) files, applications, and groups of programmers. Using this methodology, definitions can be standardized for use throughout a development organization. Merge header files into the current program file by using the #include directive.

For examples of header files, refer to the supplied header files in the CLIP53INCLUDE directory.

Compiler Pseudo-functions

In addition to defining constants as values, the #define directive can also define pseudofunctions that are resolved at compile time. A pseudofunction definition is an identifier immediately followed by an argument list, delimited by parentheses, and the replacement expression. For example:

#define AREA(nLength, nWidth) (nLength * nWidth) #define SETVAR(x, y) (x := y) #define Max(x, y) (IF(x > y, x, y))

Pseudofunctions differ from manifest constants by supporting arguments. Whenever the preprocessor scans a source line and encounters a function call that matches the pseudofunction definition, it substitutes the function call with the replacement expression. The arguments of the function call are transported into the replacement expression by the names specified in the argument list of the identifier definition. When the replacement expression is substituted for the pseudofunction, names in the replacement expression are replaced with argument text. For example, the following invocations,

? AREA(10, 12) SETVAR(nValue, 10) ? Max(10, 9)

are replaced by :

? (10 * 12) nValue := 10 ? (IF(10 > 9, 10, 9)

It is important when defining pseudofunctions, that you enclose the result expression in parentheses to enforce the proper order of evaluation. This is particularly important for numeric expressions. In pseudofunctions, you must specify all arguments. If the arguments are not specified, the function call is not expanded as a pseudofunction and exits the preprocessor to the compiler as encountered.

Pseudofunctions do not entail the overhead of a function call and are, therefore, generally faster. They also use less memory. Pseudofunctions, however, are more difficult to debug within the debugger, have a scope different from declared functions and procedures, do not allow skipped arguments, and are case-sensitive.

You can avoid some of these deficiencies by defining a pseudofunction using the #translate directive. #translate pseudofunctions are not case- sensitive, allow optional arguments, and obey the dBASE four-letter rule. See the #translate directive reference in this chapter for more information.

Examples

■  In this example a manifest constant conditionally controls the
   compilation of debugging code:

   #define DEBUG
   .
   . <statements>
   .
   #ifdef DEBUG
      Assert(FILE("System.dbf"))
   #endif

■  This example defines a manifest constant and substitutes it
   for an Inkey() value:

   #define K_ESC      27
   .
   . <statements>
   .
   IF Inkey() != K_ESC
      DoIt()
   ELSE
      StopIt()
   ENDIF

■  This example defines pseudofunctions for the standard
   CA-Clipper functions, Max() and AllTrim():

   #define Max(arg1, arg2)      (IF(arg1 > arg2, ;
      arg1, arg2))
   #define AllTrim(cString)   (RTrim(LTrim(cString)))
   .
   . <statements>
   .
   ? Max(1, 2)
   ? AllTrim("  Hello  ")

Platforms

Available on MS-DOS

See also

#error⌃ | ☰

Generate a compiler error and display a message

Syntax

Arguments

messageText is the text of the message to be displayed. messageText is a literal character string—do not enclose the message in quotations unless you want them to appear as part of the display.

Description

#error causes the compiler to generate error number C2074. If the messageText parameter is specified, an error message is displayed.

Examples

■  This example displays an error message based on whether or not
   a NETWORK identifier was defined:

   #ifdef NETWORK
      #error Network version not implemented.
   #endif

Platforms

Available on MS-DOS

See also

#ifdef⌃ | ☰

Compile a section of code if an identifier is defined

Syntax

#ifdef <identifier>
   <statements>...
[#else]
   <statements>...
#endif

Arguments

identifier is the name of a definition whose existence is being verified.

Description

#ifdef…#endif lets you perform a conditional compilation. It does this by identifying a section of source code to be compiled if the specified identifier is defined. The identifier can be defined using either the #define directive or the /D compiler option which lets you define an identifier or manifest constant from the compiler command line.

The #else directive specifies the code to compile if identifier is undefined. The #endif terminates the conditional compilation block.

Conditional compilation is particularly useful when maintaining many different versions of the same program. For example, the demo code and full system code could be included in the same program file and controlled by a single #define statement.

Examples

■  This code fragment is a general skeleton for conditional
   compilation with #ifdef:

   #define DEMO
   .
   . <statements>
   .
   #ifdef DEMO
      <demo specific statements>
   #endif

■  This example controls conditional compilation with an
   identifier defined on the compiler command line with the /D option.

   In DOS:

   C>CLIPPER Myfile /DDEBUG

   In the program (.prg) file:

   #ifdef DEBUG
      Assert(<some condition>)
   #endif

■  This example defines a manifest constant to one value if it
   does not exist and redefines it to another if it exists:

   #ifdef M_MARGIN
      #undef  M_MARGIN
      #define M_MARGIN   15
   #else
      #define M_MARGIN   10
   #endif

Platforms

Available on MS-DOS

See also

#ifndef⌃ | ☰

Compile a section of code if an identifier is undefined

Syntax

#ifndef <identifier>
   <statements>...
[#else]
   <statements>...
#endif

Arguments

identifier is the name of a definition whose absence is being verified.

Description

#ifndef…#endif lets you perform conditional compilation by identifying a section of source code to compile if the specified identifier is undefined.

The #else directive specifies the code to compile if identifier is defined. The #endif terminates the conditional compilation block.

Examples

■  This code fragment is a general skeleton for conditional
   compilation with #ifndef:

   #define DEBUG
   .
   . <statements>
   .
   #ifndef DEBUG
      <optimized version of code>
   #else
      <debugging version of code>
   #endif

■  This example compiles a section of code if a specific
   identifier is undefined.

   In DOS:

   C>CLIPPER Myfile

   In the program (.prg) file:

   #ifndef NODEBUG
      Assert(<some condition>)
   #endif

■  This example overrides a default definition in the program
   (.prg) file using a manifest constant defined on the compiler command
   line with the /D option

   In DOS:

   C>CLIPPER Myfile /DM_MARGIN=10

   In the program (.prg) file:

   #ifndef M_MARGIN
      #define M_MARGIN   15
   #endif

Platforms

Available on MS-DOS

See also

#include⌃ | ☰

Include a file into the current source file

Syntax

#include "<headerFileSpec>"

Arguments

headerFileSpec specifies the name of another source file to include in the current source file. As indicated in the syntax, the name must be enclosed in double quotation marks.

headerFileSpec may contain an explicit path and file name as well as a file extension. If, however, no path is specified, the preprocessor searches the following places:

■ Source file directory

■ Directories supplied with the /I option

■ Directories specified in the INCLUDE environment variable

#include directives may be nested up to 15 levels deep—that is, a file that has been included may contain #include directives, up to 15 levels.

Description

#include inserts the contents of the specified file in place of the #include directive in the source file. By convention, the file inserted is referred to as a header file. Header files should contain only preprocessor directives and external declarations. By convention CA-Clipper header files have a .ch extension.

When deciding where to locate your header files, you have two basic choices. You can place them in the source file directory where they are local to the current system; or, you can make them globally available by placing them in the directory specified in the INCLUDE environment variable. A list of one or more directories can be specified.

Header files overcome the one major drawback of defining constants or inline functions—the #define directive only affects the file in which it is contained. This means that every program which needs access to these statements must have a list of directives at the top. The solution to this problem is to place #define statements in a separate file and use the #include directive to tell the preprocessor to include that file before compiling.

For example, suppose the file «Inkey.ch» contains a list of #define directives assigning key values to constants. Instead of including these directives at the top of each program file (.prg) requiring access to them, you can simply place the following line at the top of each program file:

#include «Inkey.ch»

This causes the preprocessor to look for inkey.ch and place all the directives contained within it at the top of this program.

Another advantage of using the #include directive is that all the #define statements are contained in one file. If any modifications to these statements are necessary, only the #include file need be altered; the program itself remains untouched.

Note that the scope of definitions within an included header file is the current program file unless the header file is included on the compiler command line with the /U option. In this case, the scope is all the program files compiled in the current invocation of the compiler.

Notes

■ Supplied header files: CA-Clipper provides a number of header

files containing manifest constants for common operations. Refer to CLIP53INCLUDE for more information.

std.ch—the standard header file: std.ch is the standard

header file provided with CA-Clipper. Its default location is CLIP53INCLUDE. std.ch contains the definitions of all CA-Clipper commands and the standard functions specified as pseudofunctions. It is strongly recommended that no changes be made to std.ch. If changes are desired, it is advisable to copy std.ch to a new name, make the changes, and compile with /U.

This header file differs somewhat from a header file you might #include in that everything defined in std.ch, with #define, #translate, or #command, has a scope of the entire compile rather than the current source file.

Examples

■  This example uses #include to insert inkey.ch, a file of
   common keyboard definitions, into a key exception handler called by
   an interface function:

   #include "Inkey.ch"

   FUNCTION GetEvent()
      LOCAL nKey, nResult
      nKey = Inkey(0)
      DO CASE
      CASE nKey = K_F10
         nResult := DoMenu("Browse")
      CASE nKey = K_ESC
         nResult := DoQuit()
         .
         . <statements>
         .
      CASE nKey = K_CTRL_RIGHT
         nResult := DoNextRec()
      ENDCASE
      RETURN nResult

Platforms

Available on MS-DOS

See also

#stdout⌃ | ☰

Send literal text to the standard output device

Syntax

Arguments

messageText is the text of the message to display. messageTest is a literal character string. Do not enclose the message in quotation marks unless you want them to appear as part of the display.

Description

#stdout causes the compiler to output the literal text to the standard output device (stdout) during compilation. If messageText is not specified, a carriage return/line feed pair echoes to stdout.

Warning! Manifest constants are not translated in #stdout. Implementation is identical to #error with the following exceptions: output is written to STDOUT and no compiler error is generated.

Examples

This example demonstrates use of #stdout:

#ifdef DEBUG
   #stdout Compiling debugging version...
#endif

PROCEDURE Main()

? "Hello world"
RETURN

#stdout End of "Hello World" program

Platforms

Available on MS-DOS

See also

#undef⌃ | ☰

Remove a #define macro definition

Syntax

Arguments

identifier is the name of the manifest constant or pseudofunction to remove.

Description

#undef removes an identifier defined with the #define directive. After an #undef, the specified identifier becomes undefined. Use #undef to remove an identifier before you redefine it with #define, preventing the compiler warning that occurs when an existing identifier is redefined. Also, use #undef to make conditional compilation specific to certain sections of a program.

Examples

■  To define and then undefine a manifest constant and a
   pseudofunction:

   #define K_ESC  27
   #define Max(x, y)   IF(x > y, x, y)
   .
   . <statements>
   .
   #undef K_ESC
   #undef MAX

■  To use #undef to undefine an identifier before redefining it:

   #define DEBUG
   .
   . <statements>
   .
   #undef DEBUG
   #define DEBUG   .T.

■  To undefine an identifier if it exists, and otherwise define
   it for later portions of the program file:

   #ifdef TEST
      #undef TEST
   #else
      #define TEST
   #endif

Platforms

Available on MS-DOS

See also

#xcommand | #xtranslate⌃ | ☰

Specify a user-defined command or translation directive

Syntax

#xcommand   <matchPattern> => <resultPattern>
#xtranslate <matchPattern> => <resultPattern>

Arguments

matchPattern is the pattern to match in the input text.

resultPattern is the text produced if a piece of input text matches the matchPattern.

Description

The #xcommand and #xtranslate directives work like #command and #translate except that they overcome the dBASE keyword length limitation. They are significant beyond the first four letters, limited only by available memory. All other rules apply.

Platforms

Available on MS-DOS

See also

%⌃ | ☰

Modulus—binary (Mathematical)

Syntax

Description

% returns a number representing the remainder of nNumber1 divided by nNumber2.

Notes

■ Seeking the modulus of any dividend using a zero as the

divisor causes a runtime error. In versions of CA-Clipper prior to Summer ’87, a modulus operation with a zero divisor returned zero.

Examples

■  This example shows modulus results using different operands:

   ?  3 %  0            // Result: Runtime error
   ?  3 % -2            // Result:  1
   ? -3 %  2            // Result: -1
   ? -3 %  0            // Result: Runtime error
   ? -1 %  3            // Result: -1
   ? -2 %  3            // Result: -2
   ?  2 % -3            // Result:  2
   ?  1 % -3            // Result:  1

Platforms

Available on MS-DOS

See also

+⌃ | ☰

Addition, unary positive, concatenation (Math, Character)

Syntax

<nNumber1> + <nNumber2>           (addition)
<dDate>    + <nNumber>            (addition)
<cString1> + <cString2>           (concatenation)

Description

The (+) operator performs a number of different operations depending on the data types of the operands:

■ Unary positive sign (numeric): A numeric expression prefaced

with the plus (+) operator performs no operation on the operand except to enforce a higher level of precedence than other numeric operations (except the unary minus).

■ Binary addition sign (numeric, date): If both operands are

numeric, nNumber2 is added to nNumber1 and the result is returned as a numeric value. If either operand is date data type and the other operand numeric data type, the nNumber is added as days to the dDate and a date value is returned.

■ Concatenation (character, memo): If both operands are

character, cString2 (the right operand) is concatenated to cString1 (the left operand) returning a character string.

Examples

■  These examples illustrate the various forms of the + operator:

   // Binary addition (numeric)
   ? 1 + 1                           // Result: 2
   ? 1 + 0                           // Result: 1
   ? 0 + 1                           // Result: 1

   // Binary addition (date)
   ? CToD("12/12/88") + 12         // Result: 12/24/88
   ? 12 + CToD("12/12/88")         // Result: 12/24/88

   // Concatenation (character)
   ? "Hi " + "there"               // Result: Hi there

Platforms

Available on MS-DOS

See also

= (compound assign), -, /, *, **, %

++⌃ | ☰

Increment—unary (Mathematical)

Syntax

++<idVar>         (prefix increment)
<idVar>++         (postfix increment)

Description

The increment operator (++) increases the value of its operand by one. This operator adds one to the value of idVar and assigns the new value to idVar.

The ++ operator can appear before or after idVar. Specifying the operator before idVar increments and assigns the value before idVar is used. This is called prefix notation, and it is the most common usage. Specifying the operator after idVar, postfix notation, increments and assigns the value after idVar is used. Stated differently, postfix notation delays the assignment portion of the operation until the rest of the expression is evaluated, and prefix notation gives the assignment precedence over all other operations in the expression.

If the reference to idVar is ambiguous (i.e., not declared at compile time and not explicitly qualified with an alias), idVar is always assumed to be MEMVAR. You can assign field variables by declaring the field variable name in a FIELD statement or referring to the field name prefaced by the FIELD-> alias or the name of the work area.

Examples

■  This code uses the prefix increment operator in an assignment
   statement.  Therefore, both variables have the same value when
   queried:

   nValue := 0
   nNewValue := ++nValue
   ? nNewValue               // Result:   1
   ? nValue                  // Result:   1

■  In this example, the postfix increment operator increases the
   first operand of the multiplication operation by one, making its
   value 11; however, the assignment of this new value to the nValue
   variable will not take place until the entire expression is
   evaluated.  Therefore, its value is still 10 when the multiplication
   operation occurs, and the result of 11 * 10 is 110.  Finally, when
   nValue is queried again after the expression is evaluated, the
   postfix increment assignment is reflected in its new value, 11.

   nValue := 10
   ? nValue++ * nValue       // Result: 110
   ? nValue                  // Result:  11

Platforms

Available on MS-DOS

See also

= (compound assign), --, :=, +

AAdd()Harbour implementation


⌃ | ☰

Add a new element to the end of an array

Syntax

AAdd(<aTarget>, <expValue>) → Value

Arguments

aTarget is the array to which a new element is to be added.

expValue is the value assigned to the new element.

Returns

AAdd() evaluates expValue and returns its value. If expValue is not specified, AAdd() returns NIL.

Description

AAdd() is an array function that increases the actual length of the target array by one. The newly created array element is assigned the value specified by expValue.

AAdd() is used to dynamically grow an array. It is useful for building dynamic lists or queues. A good example of this is the GetList array used by the Get system to hold Get objects. After a READ or CLEAR GETS, GetList becomes an empty array. Each time you execute an @...GET command, the Get system uses AAdd() to add a new element to the end of the GetList array, and then assigns a new Get object to the new element.

AAdd() is similar to ASize() but only adds one element at a time; ASize() can grow or shrink an array to a specified size. AAdd(), however, has the advantage that it can assign a value to the new element, while ASize() cannot. AAdd() may also seem similar to AIns(), but they are different: AIns() moves elements within an array, but it does not change the array’s length.

Note: If expValue is another array, the new element in the target array will contain a reference to the array specified by expValue.

Examples

■  These examples demonstrate the effects of multiple invocations
   of AAdd() to an array:

   aArray := {}                  // Result: aArray is an empty array
   AAdd(aArray, 5)               // Result: aArray is { 5 }
   AAdd(aArray, 10)              // Result: aArray is { 5, 10 }
   AAdd(aArray, { 12, 10 })      // Result: aArray is
                                 // { 5, 10, { 12, 10 } }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Abs()Harbour implementation


⌃ | ☰

Return the absolute value of a numeric expression

Syntax

Arguments

nExp is the numeric expression to be evaluated.

Returns

Abs() returns a number representing the absolute value of its argument. The return value is a positive number or zero.

Description

Abs() is a numeric function that determines the magnitude of a numeric value independent of its sign. It lets you, for example, obtain the difference between two numbers as a positive value without knowing in advance which of the two is larger.

As a formalism, Abs(x) is defined in terms of its argument, x, as follows: if x >= 0, Abs(x) returns x; otherwise, Abs(x) returns the negation of x.

Examples

■  These examples show typical results from Abs():

   nNum1 := 100
   nNum2 := 150
   ? nNum1 - nNum2                  // Result: -50
   ? Abs(nNum1 - nNum2)             // Result: 50
   ? Abs(nNum2 - nNum1)             // Result: 50
   ? Abs(-12)                       // Result: 12
   ? Abs(0)                         // Result: 0

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

ACCEPT*Harbour implementation⌃ | ☰

Place keyboard input into a memory variable

Syntax

ACCEPT [<expPrompt>] TO <idVar>

Arguments

expPrompt is an optional prompt displayed before the input area. The prompt can be an expression of any data type.

idVar is the variable that will hold input from the keyboard. If the specified idVar does not exist or is not visible, a private variable is created.

Description

ACCEPT is a console command and wait state that takes input from the keyboard and assigns it as a character string to the specified variable. When ACCEPT is executed, it first performs a carriage return/linefeed, displays the prompt, and then begins taking characters from the keyboard at the first character position following the prompt. You may input up to 255 characters. When input reaches the edge of the screen, as defined by MaxCol(), the cursor moves to the next line.

ACCEPT supports only two editing keys: Backspace and Return. Esc is not supported. Backspace deletes the last character typed. Return confirms entry and is the only key that can terminate an ACCEPT. If Return is the only key pressed, ACCEPT assigns a null value («») to idVar.

Examples

■  This example uses ACCEPT to get keyboard input from the user:

   LOCAL cVar
   ACCEPT "Enter a value: " TO cVar
   IF cVar == ""
      ? "User pressed Return"
   ELSE
      ? "User input:", cVar
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

AChoice()Harbour implementation


⌃ | ☰

Execute a pop-up menu

Syntax

AChoice(<nTop>, <nLeft>, <nBottom>, <nRight>,
   <acMenuItems>,
   [<alSelectableItems> | <lSelectableItems>],
   [<cUserFunction>],
   [<nInitialItem>],
   [<nWindowRow>]) → nPosition

Arguments

nTop, nLeft and nBottom, nRight are the upper- left and lower-right window coordinates. Row values can range from zero to MaxRow() and column values can range from zero to MaxCol().

acMenuItems is an array of character strings to display as the menu items. The individual menu items are later identified by their numeric positions in this array.

alSelectableItems is a parallel array of logical values—one element for each item in acMenuItems—that specify the selectable menu items. Elements can be logical values or character strings. AChoice() will not permit a null string and stops displaying if it encounters one. If the element is a character string, it is evaluated as a macro expression which should evaluate to a logical data type. In either case, a value of false (.F.) means that the corresponding menu item is not available, and a value of true (.T.) means that it is available. If you specify lSelectableItems instead of an array, false (.F.) makes all menu items unavailable and true (.T.) makes all menu items available. By default, all menu items are available for selection.

cUserFunction is the name of a user-defined function that executes when an unrecognizable key is pressed. Specify the function name as a character expression without parentheses or arguments. Note that the behavior of AChoice() is affected by the presence of this argument. Refer to the discussion below for further information.

nInitialItem is the position in the acMenuItems array of the item that will be highlighted when the menu is initially displayed. If you specify an unavailable menu item or no argument at all, the initial menu item is the first selectable item in the array.

nWindowRow is the number of the window row on which the initial menu item will appear. Row numbering begins with zero. By default, the initial menu item appears as close to the top of the window as possible, without leaving any empty rows at the bottom. Thus, if there are enough menu items following the initial one to fill up the window, the initial form will appear on the first row (row zero) of the menu. This function argument is used to control the initial menu appearance when there are more menu items than will fit in the window.

As with all functions, optional arguments are omitted by using a comma instead of the actual argument.

Returns

AChoice() returns the numeric position in the acMenuItems array of the menu item selected. If the selection process is aborted, AChoice() returns zero.

Description

AChoice() is a user interface function that can create various kinds of pop-up menus. Each menu uses an array of character strings as menu items and a parallel array of logical values to determine whether items are selectable. When you invoke AChoice(), the list of menu items is displayed within the specified window coordinates. When the user presses Return, the current item is selected, and AChoice() returns the position of the menu item in acMenuItems. When the user presses Esc, AChoice() aborts and returns zero.

The menu items scroll if the number of items in acMenuItems exceeds the number of rows in the menu window, and the user attempts to move the highlight beyond the top or bottom of the menu window. Note that the highlight does not wrap when you reach the top or bottom of the list of items. Pressing the first letter does, however, wrap the highlight within the set of items whose first letter matches the key you press.

■ Navigating the menu: AChoice() has two modes depending on

whether the cUserFunction argument is specified. If it is not specified the following navigation keys are active:

AChoice() Keys (No User Function)

       Key            Action

       Up arrow       Go to previous item

       Down arrow     Go to next item

       Home           Go to first item in menu

       End            Go to last item in menu

       Ctrl+Home      Go to first item in window

       Ctrl+End       Go to last item in window

       PgUp           Go to previous page

       PgDn           Go to next page

       Ctrl+PgUp      Go to the first item in menu

       Ctrl+PgDn      Go to last item in menu

       Return         Select current item

       Esc            Abort selection

       Left arrow     Abort selection

       Right arrow    Abort selection

       First Letter   Go to next item beginning with first letter

■ Color: Menu items are displayed in standard color, the

highlight in enhanced color, and the unavailable items in the unselected color. For example, the following color statement

SetColor(«W+/N, BG+/B, , , W/N»)

displays a menu that is bright white on black, the highlight is bright cyan on blue, and the unavailable menu items are dim white on black.

■ User function: Like the other user interface functions,

AChoice() supports a user function. The user function is specified when you want to nest AChoice() invocations to create hierarchical menus or to redefine keys.

When a user function is specified, AChoice() processes only a limited set of keys automatically. These are listed in the following table. All other keys generate a key exception which passes control to the user function for handling. Control is also passed to the user function when AChoice() goes idle (i.e., when there are no more keys to process).

AChoice() Keys (User Function Specified)

       Key          Action

       Uparrow      Go to previous item

       Dnarrow      Go to next item

       Ctrl+Home    Go to first item in window

       Ctrl+End     Go to last item in window

       PgUp         Go to previous page

       PgDn         Go to next page

       Ctrl+PgUp    Go to the first item in menu

       Ctrl+PgDn    Go to last item in menu

When AChoice() executes the user function, it automatically passes the following three parameters:

— The current AChoice() mode

— The current element in the array of items

— The relative row position within the menu window

The mode indicates the current state of AChoice() depending on the key pressed and the action taken by AChoice() prior to executing the user function. The mode parameter has the following possible values:

AChoice() Modes

       Mode    Achoice.ch     Description

       0       AC_IDLE        Idle

       1       AC_HITTOP      Attempt to cursor past top of list

       2       AC_HITBOTTOM   Attempt to cursor past bottom of list

       3       AC_EXCEPT      Keystroke exceptions

       4       AC_NOITEM      No selectable items

After the user function has performed whatever operations are appropriate to the AChoice() mode or LastKey(), it must RETURN a value requesting AChoice() to perform an operation from the following set of actions:

AChoice() User Function Return Values

       Value   Achoice.ch     Action

       0       AC_ABORT       Abort selection

       1       AC_SELECT      Make selection

       2       AC_CONT        Continue AChoice()

       3       AC_GOTO        Go to the next item whose first character

                              matches the key pressed

Examples

■  This example uses two literal arrays to specify the menu items
   and selection criteria.  After the menu is displayed and the user
   makes a selection, the name of the selected menu item is displayed:

   acMenuItems := {"One", "Two", "-------", "Three"}
   alSelectableItems := {.T., .T., .F., .T.}
   nPosition := AChoice(10, 10, 12, 15, acMenuItems,;
                            alSelectableItems)
   ? acMenuItems[nPosition]

■  This example declares an array of menu items and supplies a
   user-defined function which displays a message with each highlighted
   choice:

   #include "achoice.ch"
   #include "inkey.ch"

   PROCEDURE Main()

      LOCAL acMenuItems[4], cUserFunction, nRetVal
      LOCAL nKey, nPos

      acMenuItems[1] := "Add"
      acMenuItems[2] := "Edit"
      acMenuItems[3] := "Delete"
      acMenuItems[4] := "Update"

      CLS

      nPos := AChoice( 10, 10, 13, 15, acMenuItems,;
                     .T., "cUserFunction" )
      DO CASE
      CASE nPos == 1
         //  Put ADD routine here
      CASE nPos == 2
         //  Put EDIT routine here
      CASE nPos == 3
         //  Put DELETE routine here
      CASE nPos ==4
         //  Put UPDATE routine here
      ENDCASE

   RETURN


   FUNCTION cUserFunction( nMode, nCurElement, nRowPos )

      LOCAL nRetVal := AC_CONT     // Default, Continue
      LOCAL nKey := LastKey()

      DO CASE
   // After all pending keys are processed, display message
      CASE nMode == AC_IDLE
      DO CASE
         CASE nCurElement == 1
            @ 22, 5 SAY " Adding   "
         CASE nCurElement == 2
            @ 22, 5 SAY " Editing  "
         CASE nCurElement ==  3
            @ 22, 5 SAY " Deleting "
         CASE nCurElement ==  4
            @ 22, 5 SAY " Updating "
      ENDCASE

         nRetVal := AC_CONT            // Continue AChoice()

      CASE nMode == AC_HITTOP          // Attempt to go past Top
         Tone( 100, 3 )
      CASE nMode == AC_HITBOTTOM       // Attempt to go past
                                       // Bottom
         Tone( 100, 3 )

      CASE nMode == AC_EXCEPT          // Key Exception
         DO CASE
         CASE nKey == K_RETURN         // If RETURN key, select
            nRetVal := AC_SELECT
         CASE nKey == K_ESC            // If ESCAPE key, abort
            nRetVal := AC_ABORT
         OTHERWISE
               nRetVal := AC_GOTO      // Otherwise, go to item
         ENDCASE
      ENDCASE

   RETURN nRetVal

■  The next example declares the arrays, specifies a selection
   condition for one of the menu items, and supplies a user function:

   EXTERNAL Updated
   //
   FUNCTION MyMenu
      LOCAL acMenuItems[4], alSelectableItems[4],;
             cUserFunction := "DoIt"
      //
      acMenuItems[1] := "Add Record"
      acMenuItems[2] := "Edit Record"
      acMenuItems[3] := "Delete Record"
      acMenuItems[4] := "Update Record"
      //
      alSelectableItems[1] := .T.
      alSelectableItems[2] := .T.
      alSelectableItems[3] := .T.
      alSelectableItems[4] := "!Updated()"
      // Selection condition

      RETURN AChoice(10, 10, 12, 15, acMenuItems,;
         alSelectableItems, cUserFunction)

■  This example uses two arrays to specify menu items and
   corresponding action blocks.  After the menu is displayed and the
   user makes a selection, the AChoice() return value is used to
   determine which action block of the aActionItems array is evaluated:

   PROCEDURE Main()
      LOCAL nChoice
      LOCAL aMenuItems := { "Add Record   ", ;
                               "Edit Record  ", ;
                               "Delete Record", ;
                               "Update Record"   }

      LOCAL aActionItems := { {|| AddFunc()  }, ;
                               {|| EditFunc() }, ;
                               {|| DelFunc()  }, ;
                               {|| UpdFunc()  }  }

      nChoice := AChoice( 10, 10, 13, 22, aMenuItems )

      IF nChoice == 0
         QUIT      // ESCAPE was pressed
      ENDIF

      Eval( aActionItems[nChoice] )

   RETURN

Platforms

Available on MS-DOS

File

See also

AClone()Harbour implementation


⌃ | ☰

Duplicate a nested or multidimensional array

Syntax

AClone(<aSource>) → aDuplicate

Arguments

aSource is the array to be duplicated.

Returns

AClone() returns a duplicate of aSource.

Description

AClone() is an array function that creates a complete duplicate of the aSource array. If aSource contains subarrays, AClone() creates matching subarrays and fills them with copies of the values in the aSource subarrays. AClone() is similar to ACopy(), but ACopy() does not duplicate nested arrays.

Examples

■  This example creates an array then duplicates it using
   AClone().  The first array is then altered, but the duplicate copy is
   unaffected:

   LOCAL aOne, aTwo
   aOne := { 1, 2, 3 }         // Result: aOne is {1, 2, 3}
   aTwo := AClone(aOne)        // Result: aTwo is {1, 2, 3}
   aOne[1] := 99               // Result: aOne is {99, 2, 3}
                              // aTwo is still {1, 2, 3}

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ACopy()Harbour implementation


⌃ | ☰

Copy elements from one array to another

Syntax

ACopy(<aSource>, <aTarget>,
   [<nStart>], [<nCount>], [<nTargetPos>]) → aTarget

Arguments

aSource is the array to copy elements from.

aTarget is the array to copy elements to.

nStart is the starting element position in the aSource array. If not specified, the default value is one.

nCount is the number of elements to copy from the aSource array beginning at the nStart position. If nCount is not specified, all elements in aSource beginning with the starting element are copied.

nTargetPos is the starting element position in the aTarget array to receive elements from aSource. If not specified, the default value is one.

Returns

ACopy() returns a reference to the target array, aTarget.

Description

ACopy() is an array function that copies elements from the aSource array to the aTarget array. The aTarget array must already exist and be large enough to hold the copied elements. If the aSource array has more elements, some elements will not be copied.

ACopy() copies values of all data types including NIL and code blocks. If an element of the aSource array is a subarray, the corresponding element in the aTarget array will contain a reference to the subarray. Thus, ACopy() will not create a complete duplicate of a multidimensional array. To do this, use the AClone() function.

Examples

■  This example creates two arrays, each filled with a value.
   The first two elements from the source array are then copied into the
   target array:

   LOCAL nCount := 2, nStart := 1, aOne, aTwo
   aOne := { 1, 1, 1 }
   aTwo := { 2, 2, 2 }
   ACopy(aOne, aTwo, nStart, nCount)
   // Result: aTwo is now { 1, 1, 2 }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ADel()Harbour implementation


⌃ | ☰

Delete an array element

Syntax

ADel(<aTarget>, <nPosition>) → aTarget

Arguments

aTarget is the array to delete an element from.

nPosition is the position of the target array element to be deleted.

Returns

ADel() returns a reference to the target array, aTarget.

Description

ADel() is an array function that deletes an element from an array. The contents of the specified array element is lost, and all elements from that position to the end of the array are shifted up one element. The last element in the array becomes NIL.

Warning! CA-Clipper implements multidimensional arrays by nesting arrays within other arrays. If the aTarget array is a multidimensional array, ADel() can delete an entire subarray specified by nPosition, causing aTarget to describe an array with a different structure than the original.

Examples

■  This example creates a constant array of three elements, and
   then deletes the second element.  The third element is moved up one
   position, and the new third element is assigned a NIL:

   LOCAL aArray
   aArray := { 1, 2, 3 }      // Result: aArray is
                              // now { 1, 2, 3 }
   ADel(aArray, 2)            // Result: aArray is
                              // now { 1, 3, NIL }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ADir()*Harbour implementation


⌃ | ☰

Fill a series of arrays with directory information

Syntax

ADir([<cFilespec>],
   [<aFilenames>],
   [<aSizes>],
   [<aDates>],
   [<aTimes>],
   [<aAttributes>]) → nFiles

Arguments

cFilespec is the path specification of files to include in the scan of the DEFAULT directory. It is a standard file specification that can include the wildcard characters * and ?, as well as a drive and path reference. If omitted, the default specification is *.*.

aFilenames is the array to fill with the file names matching cFilespec. Each element contains the file name and extension as a character string in all uppercase letters.

aSizes is the array to fill with the sizes of the corresponding files in the aFilenames array. Each element is a numeric data type.

aDates is the array to fill with the dates of the corresponding files in the aFilenames array. Each element is a date data type.

aTimes is the array to fill with the times of the corresponding files in the aFilenames array. Each element filled contains a character string of the form: hh:mm:ss.

aAttributes is the array to fill with attributes of the corresponding files in the aFilenames array. Each element is a character string. If aAttributes is specified, hidden, system, and directory files are included as well as normal files. If aAttributes is not specified, only normal files are included.

Returns

ADir() returns the number of files matching the directory skeleton described in cFilespec.

Description

ADir() is an array function that performs two basic operations. First, it returns the number of files matching the file specification. Second, it fills a series of arrays with file names, sizes, dates, times, and attributes.

ADir() is a compatibility function and therefore not recommended. It is superseded by the Directory() function which returns all file information in a multidimensional array.

Notes

■ Directories: If you specify the aAttributes argument and

cFilespec is *.*, directories will be included in aFilenames. In the aAttributes array, directories are indicated with an attribute value of «D». If ADir() is executed within a subdirectory, the first two entries of the aFilenames array are «.» and «..», the parent and current directory aliases. The date and time of last update are reported for directories, but the size of a directory is always zero.

Examples

■  This example creates an array to hold the names of all .txt
   files in the current DEFAULT directory, then uses AEval() to list
   them to the console:

   LOCAL aFiles[ADir("*.TXT")]
   ADir("*.TXT", aFiles)
   AEval(aFiles, { |element| QOut(element) })

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

AEval()Harbour implementation


⌃ | ☰

Execute a code block for each element in an array

Syntax

AEval(<aArray>, <bBlock>,
   [<nStart>], [<nCount>]) → aArray

Arguments

aArray is the array to traverse.

bBlock is a code block to execute for each element encountered.

nStart is the starting element. If not specified, the default is element one.

nCount is the number of elements to process from nStart. If not specified, the default is all elements to the end of the array.

Returns

AEval() returns a reference to aArray.

Description

AEval() is an array function that evaluates a code block once for each element of an array, passing the element value and the element index as block parameters. The return value of the block is ignored. All elements in aArray are processed unless either the nStart or the nCount argument is specified.

AEval() makes no assumptions about the contents of the array elements it is passing to the block. It is assumed that the supplied block knows what type of data will be in each element.

AEval() is similar to dbEval() which applies a block to each record of a database file. Like dbEval(), AEval() can be used as a primitive for the construction of iteration commands for both simple and complex array structures.

Refer to the Code Blocks section in the «Basic Concepts» chapter of the Programming and Utilities Guide for more information on the theory and syntax of code blocks.

Examples

■  This example uses AEval() to display an array of file names
   and file sizes returned from the Directory() function:

   #include "Directry.ch"
   //
   LOCAL aFiles := Directory("*.dbf"), nTotal := 0
   AEval(aFiles,;
      { | aDbfFile |;
         QOut(PadR(aDbfFile[F_NAME], 10), aDbfFile[F_SIZE]),;
         nTotal += aDbfFile[F_SIZE]);
      } )
   //
   ?
   ? "Total Bytes:", nTotal

■  This example uses AEval() to build a list consisting of
   selected items from a multidimensional array:

   #include "Directry.ch"
   //
   LOCAL aFiles := Directory("*.dbf"), aNames := {}
   AEval(aFiles,;
      { | file | AAdd(aNames, file[F_NAME]) };
      )

■  This example changes the contents of the array element
   depending on a condition.  Notice the use of the codeblock
   parameters:

   LOCAL aArray[6]
   AFill(aArray,"old")
   AEval(aArray,;
   {|cValue,nIndex| IF(cValue == "old",;
                     aArray[nIndex] := "new",)})

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

AFields()*Harbour implementation


⌃ | ☰

Fill arrays with the structure of the current database file

Syntax

AFields([<aFieldNames>], [<aTypes>],
   [<aWidths>], [<aDecimals>]) → nFields

Arguments

aFieldNames is the array to fill with field names. Each element is a character string.

aTypes is the array to fill with the type of fields in aFieldNames. Each element is a character string.

aWidths is the array to fill with the widths of fields in aFieldNames. Each element is numeric data type.

aDecimals is the array to fill with the number of decimals defined for fields in aFieldNames. Each element is numeric data type. If the field type is not numeric, the aDecimals element is zero.

Returns

AFields() returns the number of fields or the length of the shortest array argument, whichever is less. If no arguments are specified, or if there is no file in USE in the current work area, AFields() returns zero.

Description

AFields() is an array function that fills a series of arrays (structure attribute arrays) with the structure of the database file currently open, one element in each array per field. AFields() works like ADir(), filling a series of existing arrays with information. To use AFields(), you must first create the arrays to hold the database structure information, each with the same number of elements as the number of fields (i.e. FCount()). Once the structure attribute arrays are created, you can then invoke AFields() to fill the structure arrays with information about each field.

By default, AFields() operates on the currently selected work area. It can operate on an unselected work area if you specify it within an aliased expression (see example below).

AFields() is a compatibility function and therefore is not recommended. It is superseded by dbStruct(), which does not require the existence of any arrays prior to invocation and returns a multidimensional array containing the current database file structure.

Examples

■  This example demonstrates how AFields() and AChoice() can be
   used together to create a fields picklist:

   USE Sales NEW
   PRIVATE aFieldNames[FCount()]
   AFields(aFieldNames)
   @ 1, 0 TO 10, 10 DOUBLE
   nChoice := AChoice(2, 1, 9, 9, aFieldNames)
   @ 12, 0 SAY IF(nChoice != 0, aFieldNames[nChoice],;
                   "None selected")
   RETURN

■  This example uses AFields() with an aliased expression to fill
   arrays with the structure of Sales.dbf, open in an unselected work
   area:

   LOCAL aFieldNames, aTypes, aWidths, aDecimals
   USE Sales NEW
   USE Customer NEW
   //
   aFieldNames := Sales->(Array(FCount()))
   aTypes := Sales->(Array(FCount()))
   aWidths := Sales->(Array(FCount()))
   aDecimals := Sales->(Array(FCount()))
   //
   Sales->(AFields(aFieldNames, aTypes, ;
            aWidths, aDecimals))

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

AFill()Harbour implementation


⌃ | ☰

Fill an array with a specified value

Syntax

AFill(<aTarget>, <expValue>,
   [<nStart>], [<nCount>]) → aTarget

Arguments

aTarget is the array to be filled.

expValue is the value to be placed in each array element. It can be an expression of any valid data type.

nStart is the position of the first element to be filled. If this argument is omitted, the default value is one.

nCount is the number of elements to be filled starting with element nStart. If this argument is omitted, elements are filled from the starting element position to the end of the array.

Returns

AFill() returns a reference to aTarget.

Description

AFill() is an array function that fills the specified array with a single value of any data type (including an array, code block, or NIL) by assigning expValue to each array element in the specified range.

Warning! AFill() cannot be used to fill multidimensional arrays. CA-Clipper implements multidimensional arrays by nesting arrays within other arrays. Using AFill() with a multidimensional array will overwrite subarrays used for the other dimensions of the array.

Examples

■  This example, creates a three-element array.  The array is
   then filled with the logical value, (.F.).  Finally, elements in
   positions two and three are assigned the new value of true (.T.):

   LOCAL aLogic[3]
   // Result: aLogic is { NIL, NIL, NIL }

   AFill(aLogic, .F.)
   // Result: aLogic is { .F., .F., .F. }

   AFill(aLogic, .T., 2, 2)
   // Result: aLogic is { .F., .T., .T. }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

AIns()Harbour implementation


⌃ | ☰

Insert a NIL element into an array

Syntax

AIns(<aTarget>, <nPosition>) → aTarget

Arguments

aTarget is the array into which a new element will be inserted.

nPosition is the position at which the new element will be inserted.

Returns

AIns() returns a reference to the target array, aTarget.

Description

AIns() is an array function that inserts a new element into a specified array. The newly inserted element is NIL data type until a new value is assigned to it. After the insertion, the last element in the array is discarded, and all elements after the new element are shifted down one position.

Warning! AIns() must be used carefully with multidimensional arrays. Multidimensional arrays in CA-Clipper are implemented by nesting arrays within other arrays. Using AIns() in a multidimensional array discards the last element in the specified target array which, if it is an array element, will cause one or more dimensions to be lost. To insert a new dimension into an array, first add a new element to the end of the array using AAdd() or ASize() before using AIns().

Examples

■  This example demonstrates the effect of using AIns() on an
   array:

   LOCAL aArray
   aArray := { 1, 2, 3 }      // Result: aArray is
                              // now { 1, 2, 3 }
   AIns(aArray, 2)            // Result: aArray is
                              // now { 1, NIL, 2 }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Alert()Harbour implementation


⌃ | ☰

Display a simple modal dialog box

Syntax

Alert( <cMessage>, [<aOptions>] ) → nChoice

Arguments

cMessage is the message text displayed and centered in the alert box. If the message contains one or more semicolons, the text after the semicolons is centered on succeeding lines in the dialog box.

aOptions defines a list of up to 4 possible responses to the dialog box.

Returns

Alert() returns a numeric value indicating which option was chosen. If the Esc key is pressed, the value returned is zero.

Description

The Alert() function creates a simple modal dialog. It is useful in error handlers and other «pause» functions. The user can respond by moving a highlight bar and pressing the Return or SpaceBar keys, or by pressing the key corresponding to the first letter of the option. If aOptions is not supplied, a single «Ok» option is presented.

Alert() is sensitive to the presence or absence of the CA-Clipper full-screen I/O system. If the full-screen system is not present, Alert() uses standard I/O to display the message and options tty-style (i.e., 80-column, without word wrap, each line ended with carriage return/linefeed).

Examples

■  This example demonstrates use of an alert dialog box.  First,
   the array of options is defined, the Alert() function gets the user's
   selection, and finally, the user's choice is handled with a DO
   CASE...ENDCASE control structure:

   #define AL_SAVE         1
   #define AL_CANCEL      2
   #define AL_CONT         3

   // Define an array of options
   aOptions := {"Save", "Don't Save", "Continue"}

   // Display the dialog box and get the user's selection
   nChoice  := Alert("File has changed...", aOptions)

   // Handle the user's request
   DO CASE
   CASE nChoice == AL_SAVE
      ? "Save"
   CASE nChoice == AL_CANCEL
      ? "Don't Save"
   CASE nChoice == AL_CONT
      ? "Continue"
   OTHERWISE
      ? "Escape"
   ENDCASE
   //
   RETURN

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB.

See also

Alias()Harbour implementation


⌃ | ☰

Return a specified work area alias

Syntax

Alias([<nWorkArea>]) → cAlias

Arguments

nWorkArea is any work area number.

Returns

Alias() returns the alias of the specified work area as a character string in uppercase. If nWorkArea is not specified, the alias of the current work area is returned. If there is no database file in USE for the specified work area, Alias() returns a null string («»).

Description

Alias() is a database function that determines the alias of a specified work area. An alias is the name assigned to a work area when a database file is USEd. The actual name assigned is either the name of the database file, or a name explicitly assigned with the ALIAS clause of the USE command.

Alias() is the inverse of the Select() function. Alias() returns the alias name given the work area number, and Select() returns the work area number given the alias name.

■ This example returns the name of the previously selected work

area:

USE File1 NEW ALIAS Test1 nOldArea := Select() USE File2 NEW ALIAS Test2 ? Alias( nOldArea ) // Returns Test1

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

AllTrim()Harbour implementation


⌃ | ☰

Remove leading and trailing spaces from a character string

Syntax

AllTrim(<cString>) → cTrimString

Arguments

cString is the character expression to be trimmed.

Returns

AllTrim() returns a character string with leading and trailing spaces removed.

Description

AllTrim() is a character function that removes both leading and trailing spaces from a string. It is related to LTrim() and RTrim() which remove leading and trailing spaces, respectively. The inverse of AllTrim(), LTrim(), and RTrim() are the PadC(), PadL(), and PadR() functions which center, left-justify, or right-justify character strings by padding them with fill characters.

Notes

■ Space characters: The AllTrim() function treats carriage

returns, line feeds, and tabs as space characters and removes these as well.

Examples

■  This example creates a string with both leading and trailing
   spaces, and then trims them with AllTrim():

   cString := Space(10) + "string" + Space(10)
   ? Len(cString)                     // Result: 26
   ? Len(AllTrim(cString))            // Result: 6

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

AltD()Harbour implementation


⌃ | ☰

Invoke the CA-Clipper debugger

Syntax

Arguments

nAction defines what action AltD() performs when invoked. The following is a complete list of nAction values and their actions:

AltD() Actions

    Argument     Action

    None         Invokes the debugger if it is enabled

    0            Disables Alt+D

    1            Enables Alt+D

    Other        No action

Returns

AltD() always returns NIL.

Description

AltD() performs differently depending on its argument as shown in the table above. For more information on using the debugger, refer to «CA-Clipper Debugger-CLD.LIB» chapter in the Programming and Utilities Guide. Also refer to the «Debugging Your Applications» chapter in the Workbench User Guide.

Examples

■  This example demonstrates a series of manifest constants that
   can be used as arguments for AltD() before invoking the debugger
   programmatically:

   #define ALTD_DISABLE      0
   #define ALTD_ENABLE      1
   //
   AltD(ALTD_ENABLE)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ANNOUNCE⌃ | ☰

Declare a module identifier

Syntax

Arguments

idModule is a module identifier name.

Description

ANNOUNCE is a declaration statement that defines a module identifier. A linker may use this identifier later to satisfy pending module REQUESTs. ANNOUNCE and REQUEST provide a mechanism for managing application modules (.prg files).

Specify ANNOUNCE statements prior to any executable statements in a program file. A source (.prg) file can only have one module identifier; all subsequent ANNOUNCE declarations produce a compiler warning and will be ignored. Module identifiers must be unique and should not duplicate the name of any procedures or user-defined functions in a source (.prg) file.

Examples

■  This example illustrates the ANNOUNCE declaration:

   ANNOUNCE CustomInit

   INIT PROCEDURE MyInit
      ? "Hypothetical Industries, Inc."
      RETURN

   The above program module, CustomInit, should be compiled with the /N
   option.  Subsequently, the program is addressed in the source code of
   another program module through use of the REQUEST statement,

   REQUEST CustomInit

   which causes the module CustomInit to be linked into the resultant
   executable (.EXE) file.

Platforms

Available on MS-DOS

See also

APPEND BLANKHarbour implementation⌃ | ☰

Add a new record to the current database file

Syntax

Description

APPEND BLANK is a database command that adds a new record to the end of the current database file and then makes it the current record. The new field values are initialized to the empty values for each data type: character fields are assigned with spaces; numeric fields are assigned zero; logical fields are assigned false (.F.); date fields are assigned CToD(«»); and memo fields are left empty.

If operating under a network with the current database file shared, APPEND BLANK attempts to add and then lock a new record. If another user has locked the database file with FLock() or locked LastRec() + 1 with RLock(), NetErr() returns true (.T.). Note that a newly APPENDed record remains locked until you lock another record or perform an UNLOCK. APPEND BLANK does not release an FLock() set by the current user.

Examples

■  This example attempts to add a record to a shared database
   file and uses NetErr() to test whether the operation succeeded:

   USE Sales SHARED NEW
   .
   . <statements>
   .
   APPEND BLANK
   IF !NetErr()
      <update empty record>...
   ELSE
      ? "Append operation failed"
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

APPEND FROMHarbour implementation⌃ | ☰

Import records from a database (.dbf) file or ASCII text file

Syntax

APPEND FROM <xcFile>
   [FIELDS <idField list>]
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
   [SDF | DELIMITED [WITH BLANK | <xcDelimiter>] |
   [VIA <xcDriver>]]

Arguments

FROM xcFile specifies the name of the source file. You can specify xcFile either as a literal file name or as a character expression enclosed in parentheses. If a file extension is not specified, .dbf is the default input file type. If SDF or DELIMITED is specified, the file extension is assumed to be .txt unless otherwise specified.

FIELDS idField list specifies the list of fields to copy from xcFile. The default is all fields.

scope is the portion of the source database file to APPEND FROM. NEXT n APPENDs the first n records. RECORD n APPENDs only record number n from xcFile. The default scope is ALL records in xcFile.

WHILE lCondition specifies the set of records meeting the condition from the first record in the source file until the condition fails.

FOR lCondition specifies the conditional set of records to APPEND FROM within the given scope.

SDF identifies a System Data Format ASCII file. Records and fields are fixed length.

DELIMITED identifies an ASCII text file where character fields are enclosed in double quotation marks (the default delimiter). Note that delimiters are not required and CA-Clipper correctly APPENDs character fields not enclosed in them. Fields and records are variable length.

DELIMITED WITH BLANK identifies an ASCII text file in which fields are separated by one space and character fields are not enclosed in delimiters.

DELIMITED WITH xcDelimiter identifies a delimited ASCII text file where character fields are enclosed using the specified delimiter. You can specify xcDelimiter as a literal character or as a character expression enclosed in parentheses.

See the tables below for more information regarding the format specification requirements for ASCII text files that you want to APPEND using these arguments.

VIA xcDriver specifies the replaceable database driver (RDD) to use to import the desired data. cDriver is the name of the RDD specified as a character expression. If cDriver is specified as a literal value, it must be enclosed in quotes.

If the VIA clause is omitted, APPEND FROM uses the driver in the current work area. If you specify the VIA clause, you must REQUEST the appropriate RDDs to be linked into the application.

Warning! If the DELIMITED WITH clause is specified on a COPY TO or APPEND FROM command line, it must be the last clause specified.

Description

APPEND FROM adds records to the current database file from an ASCII text file or another database file. Only fields with the same names and types are APPENDed. Fields with the same name from both the current database file and xcFile must be the same data type. If they are not, a runtime error occurs when the APPEND FROM command is invoked.

Any date information in xcFile must be in the format yyyymmdd to be properly APPENDed.

In a network environment, APPEND FROM does not require that the current database file be USEed EXCLUSIVEly or locked with FLock() to perform its operation. As each record is added, CA-Clipper automatically arbitrates contention for the new record.

When you invoke APPEND FROM, CA-Clipper attempts to open xcFile as shared and read-only. If access is denied, APPEND FROM terminates with a runtime error. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information. No error is raised if you attempt to open a .dbf file that is already open.

This table shows the format specifications for SDF text files:

SDF Text File Format Specifications

    File Element        Format

    Character fields    Padded with trailing blanks

    Date fields         yyyymmdd

    Logical fields      T or F

    Memo fields         Ignored

    Numeric fields      Padded with leading blanks or zeros

    Field separator     None

    Record separator    Carriage return/linefeed

    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED and DELIMITED WITH xcDelimiter ASCII text files:

DELIMITED Text File Format Specifications

    File Element        Format

    Character fields    May be delimited, with trailing blanks truncated

    Date fields         yyyymmdd

    Logical fields      T or F

    Memo fields         Ignored

    Numeric fields      Leading zeros may be truncated

    Field separator     Comma

    Record separator    Carriage return/linefeed

    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED WITH BLANK ASCII text files:

DELIMITED WITH BLANK Text File Format Specifications

    File Element        Format

    Character fields    Not delimited, trailing blanks may be truncated

    Date fields         yyyymmdd

    Logical fields      T or F

    Memo fields         Ignored

    Numeric fields      Leading zeros may be truncated

    Field separator     Single blank space

    Record separator    Carriage return/linefeed

    End of file marker  1A hex or Chr(26)

Notes

■ Deleted records: If DELETED is OFF, deleted records in

xcFile are APPENDed to the current database file and retain their deleted status. If DELETED is ON, however, none of the deleted xcFile records are APPENDed.

■ Unmatched field widths: If a field in the current database

file is a character type and has a field length greater than the incoming xcFile data, CA-Clipper pads the xcFile data with blanks. If the current field is a character data type and its field length is less than the incoming xcFile data, the xcFile data is truncated to fit. If the current field is a numeric type and the incoming xcFile data has more digits than the current field length, a runtime error occurs.

Examples

■  This example demonstrates an APPEND FROM command using a
   fields list and a FOR condition:

   USE Sales NEW
   APPEND FROM BranchFile FIELDS Branch, Salesman, Amount;
      FOR Branch = 100

■  This example demonstrates how a <scope> can be specified to
   import a particular record from another database file:

   APPEND RECORD 5 FROM Temp

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Array()Harbour implementation


⌃ | ☰

Create an uninitialized array of specified length

Syntax

Array(<nElements> [, <nElements>...]) aArray

Arguments

nElements is the number of elements in the specified dimension. The maximum number of elements in a dimension is 4096. Arrays in CA-Clipper can have an unlimited number of dimensions.

Returns

Array() returns an array of specified dimensions.

Description

Array() is an array function that returns an uninitialized array with the specified number of elements and dimensions. If more than one nElements argument is specified, a multidimensional array is created with the number of dimensions equal to the number of nElements arguments specified. Any nElements that is itself an array creates a nested array.

In CA-Clipper, there are several ways to create an array. You can declare an array using a declaration statement such as LOCAL or STATIC; you can create an array using a PRIVATE or PUBLIC statement; you can assign a literal array to an existing variable; or you can use the Array() function. Array() has the advantage that it can create arrays within expressions or code blocks.

Examples

■  This example creates a one-dimensional array of five elements
   using the Array() function, and then shows the equivalent action by
   assigning a literal array of NIL values:

   aArray := Array(5)
   aArray := { NIL, NIL, NIL, NIL, NIL }

■  This example shows three different statements which create the
   same multidimensional array:

   aArray := Array(3, 2)
   aArray := { {NIL, NIL}, {NIL, NIL}, {NIL, NIL} }
   aArray := { Array(2), Array(2), Array(2) }

■  This example creates a nested, multidimensional array:

   aArray := Array(3, {NIL,NIL})

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Asc()Harbour implementation


⌃ | ☰

Convert a character to its ASCII value

Syntax

Arguments

cExp is the character expression to be converted to a number.

Returns

Asc() returns an integer numeric value in the range of zero to 255, representing the ASCII value of cExp.

Description

Asc() is a character conversion function that returns the ASCII value of the leftmost character in a character string. Asc() is used primarily on expressions requiring numeric calculations on the ASCII value of a character. Chr() and Asc() are inverse functions.

Examples

■  These examples illustrate various results of Asc():

   ? Asc("A")                     // Result: 65
   ? Asc("Apple")                 // Result: 65
   ? Asc("a")                     // Result: 97
   ? Asc("Z") - Asc("A")          // Result: 25
   ? Asc("")                      // Result: 0

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

AScan()Harbour implementation


⌃ | ☰

Scan an array for a value or until a block returns true (.T.)

Syntax

AScan(<aTarget>, <expSearch>,
   [<nStart>], [<nCount>]) → nStoppedAt

Arguments

aTarget is the array to be scanned.

expSearch is either a simple value to scan for, or a code block. If expSearch is a simple value it can be character, date, logical, or numeric type.

nStart is the starting element of the scan. If this argument is not specified, the default starting position is one.

nCount is the number of elements to scan from the starting position. If this argument is not specified, all elements from the starting element to the end of the array are scanned.

Returns

AScan() returns a numeric value representing the array position of the last element scanned. If expSearch is a simple value, AScan() returns the position of the first matching element, or zero if a match is not found. If expSearch is a code block, AScan() returns the position of the element where the block returned true (.T.).

Description

AScan() is an array function that scans an array for a specified value and operates like SEEK when searching for a simple value. The expSearch value is compared to the target array element beginning with the leftmost character in the target element and proceeding until there are no more characters left in expSearch. If there is no match, AScan() proceeds to the next element in the array.

Since AScan() uses the equal operator (=) for comparisons, it is sensitive to the status of EXACT. If EXACT is ON, the target array element must be exactly equal to the result of expSearch to match.

If the expSearch argument is a code block, AScan() scans the aTarget array executing the block for each element accessed. As each element is encountered, AScan() passes the element’s value as an argument to the code block, and then performs an Eval() on the block. The scanning operation stops when the code block returns true (.T.), or AScan() reaches the last element in the array.

Examples

■  This example demonstrates scanning a three-element array using
   simple values and a code block as search criteria.  The code block
   criteria shows how to perform a case-insensitive search:

   aArray := { "Tom", "Mary", "Sue" }
   ? AScan(aArray, "Mary")               // Result: 2
   ? AScan(aArray, "mary")               // Result: 0
   //
   ? AScan(aArray, { |x| Upper(x) ;
         == "MARY" })                    // Result: 2

■  This example demonstrates scanning for multiple instances of a
   search argument after a match is found:

   LOCAL aArray := { "Tom", "Mary", "Sue",;
                      "Mary" }, nStart := 1
   //
   // Get last array element position
   nAtEnd := Len(aArray)
   DO WHILE (nPos := AScan(aArray, "Mary", ;
                nStart)) > 0
      ? nPos, aArray[nPos]
      //
      // Get new starting position and test
      // boundary condition
      IF (nStart := ++nPos) > nAtEnd
         EXIT
      ENDIF
   ENDDO

■  This example scans a two-dimensional array using a code block.
   Note that the parameter aVal in the code block is an array:

   LOCAL aArr:={}
   CLS
   AAdd(aArr,{"one","two"})
   AAdd(aArr,{"three","four"})
   AAdd(aArr,{"five","six"})
   ? AScan(aArr, {|aVal| aVal[2] == "four"})         // Returns 2

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ASize()Harbour implementation


⌃ | ☰

Grow or shrink an array

Syntax

ASize(<aTarget>, <nLength>) → aTarget

Arguments

aTarget is the array to grow or shrink.

nLength is the new size of the array.

Returns

ASize() returns a reference to the target array, aTarget.

Description

ASize() is an array function that changes the actual length of the aTarget array. The array is shortened or lengthened to match the specified length. If the array is shortened, elements at the end of the array are lost. If the array is lengthened, new elements are added to the end of the array and assigned NIL.

ASize() is similar to AAdd() which adds a single new element to the end of an array and optionally assigns a new value at the same time. Note that ASize() is different from AIns() and ADel(), which do not actually change the array’s length.

Note: ASize() only supports single-dimensional arrays.

Examples

■  These examples demonstrate adding new elements and deleting
   existing elements:

   aArray := { 1 }          // Result: aArray is { 1 }
   ASize(aArray, 3)         // Result: aArray is { 1, NIL, NIL }
   ASize(aArray, 1)         // Result: aArray is { 1 }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ASort()Harbour implementation


⌃ | ☰

Sort an array

Syntax

ASort(<aTarget>, [<nStart>],
   [<nCount>], [<bOrder>]) → aTarget

Arguments

aTarget is the array to be sorted.

nStart is the first element of the sort. If not specified, the default starting position is one.

nCount is the number of elements to be sorted. If not specified, all elements in the array beginning with the starting element are sorted.

bOrder is an optional code block used to determine sorting order. If not specified, the default order is ascending.

Returns

ASort() returns a reference to the aTarget array.

Description

ASort() is an array function that sorts all or part of an array containing elements of a single data type. Data types that can be sorted include character, date, logical, and numeric.

If the bOrder argument is not specified, the default order is ascending. Elements with low values are sorted toward the top of the array (first element), while elements with high values are sorted toward the bottom of the array (last element).

If the bOrder block argument is specified, it is used to determine the sorting order. Each time the block is evaluated, two elements from the target array are passed as block parameters. The block must return true (.T.) if the elements are in sorted order. This facility can be used to create a descending or dictionary order sort. See the examples below.

When sorted, character strings are ordered in ASCII sequence; logical values are sorted with false (.F.) as the low value; date values are sorted chronologically; and numeric values are sorted by magnitude.

Notes

ASort() is only guaranteed to produce sorted output (as

defined by the block), not to preserve any existing natural order in the process.

■ Because CA-Clipper implements multidimensional arrays by

nesting subarrays within other arrays, ASort() will not directly sort a multidimensional array. To sort a nested array, you must supply a code block which properly handles the subarrays.

Examples

■  This example creates an array of five unsorted elements, sorts
   the array in ascending order, then sorts the array in descending
   order using a code block:

   aArray := { 3, 5, 1, 2, 4 }
   ASort(aArray)
   // Result: { 1, 2, 3, 4, 5 }

   ASort(aArray,,, { |x, y| x > y })
   // Result: { 5, 4, 3, 2, 1 }


■  This example sorts an array of character strings in ascending
   order, independent of case.  It does this by using a code block that
   converts the elements to uppercase before they are compared:

   aArray := { "Fred", Kate", "ALVIN", "friend" }
   ASort(aArray,,, { |x, y| Upper(x) < Upper(y) })

■  This example sorts a nested array using the second element of
   each subarray:

   aKids := { {"Mary", 14}, {"Joe", 23}, {"Art", 16} }
   aSortKids := ASort(aKids,,, { |x, y| x[2] < y[2] })

   Result:

   { {"Mary", 14}, {"Art", 16}, {"Joe", 23} }

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

At()Harbour implementation


⌃ | ☰

Return the position of a substring within a character string

Syntax

At(<cSearch>, <cTarget>) → nPosition

Arguments

cSearch is the character substring to be searched for.

cTarget is the character string to be searched.

Returns

At() returns the position of the first instance of cSearch within cTarget as an integer numeric value. If cSearch is not found, At() returns zero.

Description

At() is a character function used to determine the position of the first occurrence of a character substring within another string. If you only need to know whether a substring exists within another string, use the $ operator. To find the last instance of a substring within a string, use RAt().

Examples

■  These examples show typical use of At():

   ? At("a", "abcde")                  // Result: 1
   ? At("bcd", "abcde")                // Result: 2
   ? At("a", "bcde")                   // Result: 0

■  This example splits a character string based on the position
   of a comma within the target string:

   cTarget := "Langtree, Lilly"
   ? SubStr(cTarget, 1, At(",", cTarget) - 1)
   // Result: Langtree

   ? SubStr(cTarget, At(",", cTarget) + 2)
   // Result: Lilly

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ATail()Harbour implementation


⌃ | ☰

Return the highest numbered element of an array

Syntax

ATail(<aArray>) → Element

Arguments

aArray is the array.

Returns

ATail() returns either a value or a reference to an array or object. The array is not changed.

Description

ATail() is an array function that returns the highest numbered element of an array. It can be used in applications as shorthand for aArray[Len(aArray)] when you need to obtain the last element of an array.

Examples

■  The following example creates a literal array and returns that
   last element of the array:

   aArray := {"a", "b", "c", "d"}
   ? ATail(aArray)                     // Result: d

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

AVERAGEHarbour implementation⌃ | ☰

Average numeric expressions in the current work area

Syntax

AVERAGE <nExp list> TO <idVar list>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]

Arguments

nExp list is a list of the numeric values to AVERAGE for each record processed.

TO idVar list identifies a list of receiving variables which will contain the average results. Variables that either do not exist or are not visible are created as private variables. idVar list must contain the same number of elements as nExp list.

scope defines the portion of the current database file to AVERAGE. The default scope is ALL.

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

FOR lCondition specifies the conditional set of records to AVERAGE within the given scope.

Description

AVERAGE calculates the average of one or more numeric expressions to variables for a range of records in the current database file. Zero values are counted in the AVERAGE unless explicitly ruled out with a FOR condition.

Examples

■  This example averages a single numeric field using a condition
   to select a subset of records from the database file:

   USE Sales NEW
   AVERAGE Amount TO nAvgAmount FOR Branch = "100"

■  This example finds the average date for a range of dates:

   AVERAGE (SaleDate - CToD("00/00/00")) ;
      TO nAvgDays FOR !Empty(SaleDate)
   dAvgDate := CToD("00/00/00") + nAvgDays

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

BEGIN SEQUENCE⌃ | ☰

Define a sequence of statements for a BREAK

Syntax

BEGIN SEQUENCE
   <statements>...
[BREAK [<exp>]]
   <statements>...
[RECOVER [USING <idVar>]]
   <statements>...
END [SEQUENCE]

Arguments

BREAK exp branches execution to the statement immediately following the nearest RECOVER statement if one is specified or the nearest END SEQUENCE statement. exp is the value returned into the idVar specified in the USING clause of the RECOVER statement.

RECOVER USING idVar defines a recover point in the SEQUENCE construct where control branches after a BREAK statement. If USING idVar clause is specified, idVar receives the value returned by the BREAK statement. In general, this is an error object.

END defines the end point of the SEQUENCE control structure. If no RECOVER statement is specified, control branches to the first statement following the END statement after a BREAK.

Description

BEGIN SEQUENCE...END is a control structure used for exception and runtime error handling. It delimits a block of statements, including invoked procedures and user-defined functions. When a BREAK is encountered anywhere in a block of statements following the BEGIN SEQUENCE statement up to the corresponding RECOVER statement, control branches to the program statement immediately following the RECOVER statement. If a RECOVER statement is not specified, control branches to the statement following the END statement, terminating the SEQUENCE. If control reaches a RECOVER statement without encountering a BREAK, it branches to the statement following the corresponding END.

The RECOVER statement optionally receives a parameter passed by a BREAK statement that is specified with a return value. This is usually an error object, generated and returned by the current error handling block defined by ErrorBlock(). If an error object is returned, it can be sent messages to query information about the error. With this information, a runtime error can be handled within the context of the operation rather than in the current runtime error handler. See the example below.

Within a SEQUENCE construct there are some restrictions on what statements are allowed between the BEGIN SEQUENCE and RECOVER statements. You cannot RETURN, LOOP, or EXIT between a BEGIN SEQUENCE and RECOVER statement. From within the RECOVER statement block, however, you can LOOP, EXIT, BREAK, or RETURN since the SEQUENCE is essentially completed at that point. Using LOOP from within the RECOVER statement block is useful for re-executing the SEQUENCE statement block. See the example below.

SEQUENCE constructs are quite flexible. They can be nested and more than one can be defined in the same procedure or user-defined function. If more than one SEQUENCE construct is specified, each SEQUENCE should delimit one discrete operation.

For more information on error objects, refer to the Error class in this chapter.

Examples

■  This code fragment demonstrates a SEQUENCE construct in which
   the BREAK occurs within the current procedure:

   BEGIN SEQUENCE
      <statements>...
      IF lBreakCond
         BREAK
      ENDIF
   RECOVER
      <recovery statements>...
   END

   <recovery statements>...

■  This example demonstrates an error handler returning an error
   object to the variable specified in the USING clause of the RECOVER
   statement:

       LOCAL objLocal, bLastHandler
       //
       // Save current and set new error handler
       bLastHandler := ErrorBlock({ |objErr| ;
             MyHandler(objErr, .T.) })
       //
       BEGIN SEQUENCE
          .
          . <operation that might fail>
          .
       RECOVER USING objLocal
          //
          // Send messages to objLocal and handle the error
          ? "Error: "
          IF objLocal:genCode != 0
             ?? objLocal:description
          ENDIF
          .
          .
          .
       END
       //
       // Restore previous error handler
       ErrorBlock( bLastHandler )

       FUNCTION MyHandler( objError, lLocalHandler )
          //
          // Handle locally returning the error object
          IF lLocalHandler
             BREAK objError
          ENDIF
          .
          . <other statements to handle the error>
          .
          RETURN NIL

■  This example re-executes a SEQUENCE statement block by LOOPing
   from within the RECOVER statement block:

   DO WHILE .T.
      BEGIN SEQUENCE
         .
         . <operation that may fail>
         .
      RECOVER
         IF PrintRecover()
            LOOP      // Repeat the SEQUENCE statement block
         ENDIF
      END
      EXIT            // Escape from the operation
   ENDDO

Platforms

Available on MS-DOS

See also

Bin2I()Harbour implementation


⌃ | ☰

Convert a 16-bit signed integer to a numeric value

Syntax

Bin2I(<cSignedInt>) → nNumber

Arguments

cSignedInt is a character string in the form of a 16-bit signed integer number—least significant byte first. Only the first two characters are used by the function; all others are ignored.

Returns

Bin2I() returns an integer numeric value.

Description

Bin2I() is a low-level file function that is used with FRead() to convert a two-byte character string formatted as a signed integer to a CA-Clipper numeric data type. This is most useful when you are reading foreign file types and want to read numeric data in its native format.

Examples

■  This example opens a database file using low-level file
   functions and reads the date of last update (bytes 1-3).  The result
   is the same as with LUpdate():

   #include "Fileio.ch"
   //
   nHandle := FOpen("Sales.dbf", FO_READ)
   //
   // Point to byte 1 in the file
   FSeek(nHandle, 1, FS_SET)
   //
   // Read date of last update
   nYear := Bin2I(FReadStr(nHandle, 1) + Chr(0))
   nMonth := Bin2I(FReadStr(nHandle, 1) + Chr(0))
   nDay := Bin2I(FReadStr(nHandle, 1) + Chr(0))
   //
   ? LTrim(Str(nMonth)), LTrim(Str(nDay)), LTrim(Str(nYear))
   FClose(nHandle)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM

See also

Bin2L()Harbour implementation


⌃ | ☰

Convert a 32-bit signed integer to a numeric value

Syntax

Bin2L(<cSignedInt>) → nNumber

Arguments

cSignedInt is a character string in the form of a 32-bit signed integer number—least significant byte first. Only the first four characters are used by the function; all others are ignored.

Returns

Bin2L() returns an integer numeric value.

Description

Bin2L() is a low-level file function that is used with FRead() to convert a four-byte character string formatted as a signed integer to a CA-Clipper numeric data type. This is most useful when you are reading foreign file types and want to read numeric data in its native format.

Examples

■  This example opens a database file using low-level file
   functions and reads the number of records (bytes 4-7).  The result is
   the same as with LastRec():

   #include "Fileio.ch"
   //
   nHandle := FOpen("Sales.dbf", FO_READ)
   // Note:  Sales.dbf contains 84 records
   //
   // Point to byte 4
   FSeek(nHandle, 4, FS_SET)
   //
   // Read the number of records
   cRecords := Space(4)
   FRead(nHandle, @cRecords, 4)
   //
   ? LTrim(Str(Bin2L(cRecords)))         // Result: 84
   FClose(nHandle)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM

See also

Bin2W()Harbour implementation


⌃ | ☰

Convert a 16-bit unsigned integer to a numeric value

Syntax

Bin2W(<cUnsignedInt>) → nNumber

Arguments

cUnsignedInt is a character string in the form of a 16-bit unsigned integer number—least significant byte first. Only the first two characters are used by the function; all others are ignored.

Returns

Bin2W() returns an integer numeric value.

Description

Bin2W() is a low-level file function that is used with FRead() to convert a two-byte character string formatted as an unsigned integer to a CA-Clipper numeric data type. This is most useful when you are reading from a binary file and want to read data in its native format.

Examples

■  This example opens a database file using low-level file
   functions and reads the number of bytes per record (bytes 10-11).
   The result is the same as with RecSize():

   #include "Fileio.ch"
   //
   nHandle := FOpen("Sales.dbf", FO_READ)
   // Note:  The length of a record in Sales.dbf is 124
   //
   // Point to byte 10, the first record size byte
   FSeek(nHandle, 10, FS_SET)
   //
   // Read record size
   cRecSize := Space(2)
   FRead(nHandle, @cRecSize, 2)
   //
   ? LTrim(Str(Bin2W(cRecSize)))            // Result: 124
   FClose(nHandle)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM

See also

BLOBDIRECTEXPORT()


⌃ | ☰

Export the contents of a binary large object (BLOB) pointer to a file

Syntax

BLOBDirectExport(<nPointer>, <cTargetFile>, [<nMode>])
   → lSuccess

Arguments

nPointer is a pointer to the BLOB data. This pointer can be obtained using BLOBDIRECTPUT(), BLOBDIRECTEXPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos).

cTargetFile is the name of the target file where the BLOB data will be written, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.

If cTargetFile does not exist, it is created. If it exists, this function attempts to open the file in exclusive mode and, if successful, the file is written to without warning or error. If access is denied because another process is using the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBDIRECTEXPORT()

nMode is a constant defining the copy mode, as shown in the table below:

Copy Mode Constants

    Constant                 Description

    BLOB_EXPORT_APPEND       Appends to the file

    BLOB_EXPORT_OVERWRITE    Overwrites the file (this is the default)

Returns

BLOBDIRECTEXPORT() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

By default, BLOBDIRECTEXPORT() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  This example extracts an array of pointers from the BLOB
   file's root area, then uses one of the pointers to export a picture
   to a file:

   FUNCTION PUTPIX()
      LOCAL cPixFile
      LOCAL nPointer
      LOCAL aBLOBPtrs


      cPixFile := "picture.gif"

      // Customer database with a picture of
      // each customer stored in a field called Pix
      USE Customer NEW VIA "DBFCDX"

      // Assumes that the program previously
      // stored an array of direct BLOB pointers
      // into the root area of the BLOB file.
      // The picture that we want is assumed to
      // be the second array element.
      aBLOBPtrs := BLOBROOTGET()
      nPointer := aBLOBPtrs[2]

      // Export picture pointed to by nPointer to a file
      IF !BLOBDirectExport(nPointer, cPixFile, ;
         BLOB_EXPORT_OVERWRITE)
            Alert("Export of picture " + cPixFile + ";
               failed!")
      ELSE
         // Code for displaying picture would go here
      ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

BLOBDIRECTGET()


⌃ | ☰

Retrieve data stored in a BLOB file without referencing a specific field

Syntax

BLOBDIRECTGET(<nPointer>,   [<nStart>],   [<nCount>])
    → expBLOB

Arguments

nPointer is a pointer to the BLOB data. This pointer can be obtained using BLOBDIRECTPUT(), BLOBDIRECTIMPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos).

nStart is the starting position in nPointer. If nStart is positive, the starting position is relative to the leftmost character in nPointer. If nStart is negative, it is relative to the rightmost character in nPointer. If nStart is omitted, it is assumed to be 1.

nCount is the number of bytes of data to retrieve beginning at nStart. If nCount is larger than the amount of data stored, excess data is ignored. If omitted, BLOBDIRECTGET() retrieves to the end of the data.

Note: nStart and nCount apply to string data only. They are ignored for any other data types.

Returns

BLOBDIRECTGET() returns the data retrieved from the BLOB file. The data type of the return value depends on the actual data stored. Use ValType() to determine the data type.

Description

BLOBDIRECTGET() retrieves data stored in a BLOB file without the need to reference a particular field in the database file. It is particularly useful when accessing data that is larger than 64 KB (such as memo fields created with the BLOBIMPORT() function).

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  This example illustrates storing setup information in a BLOB
   file, then selectively retrieving the stored information:

   FUNCTION PutSettings(aColors,;
                  aPaths, ;
                  aPassWords)

      LOCAL aSettings

      RDDSETDEFAULT ( "DBFCDX" )
      MEMOSETSUPER ( "DBFCDX" )

      USE Setup NEW via "DBFMEMO"

      aSettings := {}
      AAdd(aSettings, BLOBDIRECTPUT(0, aColors))
      AAdd(aSettings, BLOBDIRECTPUT(0, aPaths))
      AAdd(aSettings, BLOBDIRECTPUT(0, aPassWords))

      BLOBROOTPUT(aSettings)

      CLOSE

   FUNCTION GETCOLORS()
      LOCAL aSettings
      LOCAL aColors

      USE Setup NEW VIA "DBFMEMO"

      aSettings := BLOBROOTGET()
      aColors := BLOBDIRECTGET(aSettings[1])

      CLOSE


      RETURN aColors

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

BLOBDIRECTIMPORT()


⌃ | ☰

Import a file into a BLOB file and return a pointer to the data

Syntax

BLOBDIRECTIMPORT(<nOldPointer>, <cSourceFile>)
    → nNewPointer

Arguments

nOldPointer is a pointer to the BLOB data which will be released after the import. This pointer can be obtained using BLOBDIRECTPUT(), BLOBDIRECTIMPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos). Passing zero (0) disables the release of data.

Important! If specified, BLOBDIRECTIMPORT() releases the space associated with nOldPointer for reuse by other data. Therefore, it is illegal to use nOldPointer with any of the BLOB functions after passing it as an argument to this function. Use the function’s return value to refer to the newly stored data.

cSourceFile is the name of the file from which to read the BLOB data, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.

This function attempts to open cSourceFile in shared mode. If the file does not exist, a runtime error is raised. If the file is successfully opened, the operation proceeds. If access is denied because another process has exclusive use of the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBDIRECTIMPORT()

Note: There are no restrictions on the size of cSourceFile except that you must have enough disk space to make the copy.

Returns

BLOBDIRECTIMPORT() returns a numeric pointer to the BLOB image stored in cSourceFile.

Description

BLOBDIRECTIMPORT() provides a mechanism for copying the contents of a file into a BLOB file. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

BLOBDIRECTIMPORT() is used in conjunction with BLOBDIRECTEXPORT() to transfer data back and forth between external files and BLOB files. You can use BLOBDIRECTIMPORT() with a variety of file types, including graphic images, word processor files, and printer fonts. These two functions are excellent for creating databases for documents, graphics, sounds, etc.

Important! After importing a file with BLOBDIRECTIMPORT(), nNewPointer, the return value, is the only way to access the data from the BLOB file. It is up to you to provide permanent storage for this reference (see example below).

Note: dbFieldInfo(DBS_BLOB_TYPE, nFieldPos) will return «C» (string) for any memo field created using BLOBDIRECTIMPORT().

Examples

■  This example imports a bitmap (.bmp) file to be part of an
   array of startup data.  The data, stored in the root area of the BLOB
   file, could then be used to display the application's startup screen:

   FUNCTION PUTPIX()
      LOCAL cBMPFile
      LOCAL aSettings

      cBMPFile := "logo.bmp"
      aSettings := {}

      // Customer database where startup parameters
      // are stored for convenience
      USE Customer NEW VIA "DBFMEMO"

      // Get default path settings
      AAdd(aSettings, STARTPATHS())

      // Get default color settings
      AAdd(aSettings, DEFAULTCOLORS())

      // Get company logo for display at startup.
      // There is nothing to free because this
      // is the first time importing.
      nPointer := BLOBDIRECTIMPORT(0, cBMPFile)
      AAdd(aSettings, nPointer)

      // Store the settings in the root area of
      // the customer.fpt file

      BLOBROOTPUT(aSettings)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

BLOBDIRECTPUT()


⌃ | ☰

Put data in a BLOB file without referencing a specific field

Syntax

BLOBDIRECTPUT(<nOldPointer>, <uBLOB>) → nNewPointer

Arguments

nOldPointer is a reference to previously stored BLOB data. This reference can be obtained using BLOBDIRECTPUT(), BLOBDIRECTIMPORT(), or dbFieldInfo(DBS_BLOB_POINTER, nFieldPos). If other than zero (0), the data referenced by nOldPointer is replaced by uBLOB; otherwise, uBLOB is added to the current contents of the BLOB file.

Important! If specified, BLOBDIRECTPUT() releases the space associated with nOldPointer for reuse by other data. Therefore, it is illegal to use nOldPointer with any of the BLOB functions after passing it as an argument to this function. Use the function’s return value to refer to the newly stored data.

uBLOB is the data you want to put into the BLOB file. uBLOB can be any CA-Clipper data type except code block or an object.

Returns

BLOBDIRECTPUT() returns a numeric pointer to the uBLOB data.

Description

BLOBDIRECTPUT() stores variable length BLOB data without creating a link with a particular memo field in a database file. After adding data to a BLOB file using BLOBDIRECTPUT(), you should store the function’s return value, as this is the only way to access the data from the BLOB file. It is up to you, the developer, to provide permanent storage for this reference (see BLOBROOTPUT()).

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  This example illustrates storing setup information in a BLOB
   file, then selectively retrieving the stored information:

   FUNCTION PutSettings(aColors,;
      aPaths, aPassWords)

      LOCAL aSettings

      USE Setup NEW VIA "DBFMEMO"

      aSettings := {}
      AAdd(aSettings, BLOBDIRECTPUT(0, aColors))

      AAdd(aSettings, BLOBDIRECTPUT(0, aPaths))
      AAdd(aSettings, BLOBDIRECTPUT(0, aPassWords))

      BLOBROOTPUT(aSettings)

      CLOSE

   FUNCTION GETCOLORS()
      LOCAL aSettings
      LOCAL aColors

      USE Setup NEW VIA "DBFMEMO"

      aSettings := BLOBROOTGET()
      aColors := BLOBDIRECTGET(aSettings[1])

      CLOSE

      RETURN aColors

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

BLOBEXPORT()


⌃ | ☰

Copy the contents of a BLOB, identified by its memo field number, to a file

Syntax

BLOBEXPORT(<nFieldPos>, <cTargetFile>, [<nMode>])
    → lSuccess

Arguments

nFieldPos is the position of the field in the database file structure.

cTargetFile is the name of the target file where the BLOB data will be written, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.

If cTargetFile does not exist, it is created. If it exists, this function attempts to open the file in exclusive mode and, if successful, the file is written to without warning or error. If access is denied because another process is using the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBEXPORT()

nMode is a constant defining the copy mode, as shown in the table below:

Field Information Type Constants

    Constant                 Description

    BLOB_EXPORT_APPEND       Number of decimal places for the field

    BLOB_EXPORT_OVERWRITE    Length of the field

Returns

BLOBEXPORT() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  This example exports the contents of a field that stores a
   picture to a graphic interchange format (.gif) file, so that the file
   can be programmatically displayed:

   FUNCTION SHOWPIX()
      LOCAL cPixFile := "Picture.gif"
      LOCAL nPos

      // Customer database with a picture of each
      // customer stored in a field called Pix
      USE Customer NEW VIA "DBFCDX"
      nPos := FieldPos("Pix")

      // Export the BLOB file's data
      // for the current Pix field
      IF !BLOBEXPORT(nPos, cPixFile,;
         BLOB_EXPORT_OVERWRITE)
            Alert("Export of picture " + cPixFile + ";
               failed!")
      ELSE
         // Code for displaying picture would go here
      ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

BLOBGET()


⌃ | ☰

Get the contents of a BLOB, identified by its memo field number

Syntax

BLOBGet(<nFieldPos>, [<nStart>], [<nCount>]) → uBLOB

Arguments

nFieldPos is the position of the field in the database file structure.

nStart is the starting position in the memo field of the BLOB data. If nStart is positive, the starting position is relative to the leftmost character in nFieldPos. If nStart is negative, it is relative to the rightmost character in nFieldPos. If nStart is omitted, it is assumed to be 1.

nCount is the number of bytes of data to retrieve beginning at nStart. If nCount is larger than the amount of data stored, excess data is ignored. If omitted, BLOBGET() retrieves to the end of the data.

Note: nStart and nCount apply to string data only. They are ignored for any other data types.

Returns

BLOBGET() returns the BLOB data retrieved from the memo field. The data type of the return value depends on the actual data stored. Use ValType() to determine the data type. If the indicated field is not a memo field, BLOBGET() returns NIL.

Description

BLOBGET() is very similar to FieldGet(). However, because string type variables cannot be larger than 64 KB, FieldGet() will raise a runtime error when attempting to retrieve memo fields of this magnitude or greater.

BLOBGET() will also raise an error if you attempt to retrieve a field greater than this magnitude; however, you can retrieve any subset of the BLOB data by using an nCount less than 64 KB.

Note: BLOB data less than 64 KB can be retrieved from a memo field using standard means (for example, referring to the field by name in an expression or using the FieldGet() function).

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  This example imports information from a word processing
   document into a field, then uses BLOBGET() to extract the first 25
   characters of the field:

   FUNCTION GETFIRST25()
      LOCAL nPos
      LOCAL cStr

      USE customer NEW VIA "DBFCDX"

      // Field that contains word processor
      // documentation
      nPos := FieldPos("WP_DOC")

      // Import a file (can be larger than 64 KB), then
      // obtain the first 25 characters to show to the
      // user
      IF BLOBImport(nPos, "c:applicationtemp.doc")
         cStr := BLOBGet(nPos, 1, 25)
      ELSE
         cStr := "Error: could not import file!"
      ENDIF

   CLOSE

   RETURN cStr

Platforms

Available on MS-DOS

See also

BLOBIMPORT()


⌃ | ☰

Read the contents of a file as a BLOB, identified by a memo field number

Syntax

BLOBImport(<nFieldPos>, <cSourceFile>) → lSuccess

Arguments

nFieldPos is the position of the field in the database file structure.

cSourceFile is the name of the file from which to read the BLOB data, including an optional drive, directory, and extension. See SETDEFAULT() and SETPATH() for file searching and creation rules. No default extension is assumed.

This function attempts to open cSourceFile in shared mode. If the file does not exist, a runtime error is raised. If the file is successfully opened, the operation proceeds. If access is denied because another process has exclusive use of the file, for example, NetErr() is set to true (.T.). Concurrency control:and BLOBIMPORT()

Note: There are no restrictions on the size of cSourceFile except that you must have enough disk space to make the copy.

Returns

BLOBIMPORT() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

BLOBIMPORT() provides a mechanism for copying the contents of a file into a memo field as BLOB data. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

BLOBIMPORT() is used in conjunction with BLOBEXPORT() to transfer BLOB data back and forth between files and memo fields. You can use BLOBIMPORT() with a variety of file types, including graphic images, word processor files, and printer fonts. These two functions are excellent for creating databases for documents, graphics, sounds, etc.

Note: dbFieldInfo(DBS_BLOB_TYPE, nFieldPos) will return «C» (string) for any memo field created using BLOBIMPORT().

Examples

■  This example imports information from a word processing
   document into a field, and then uses BLOBGET() to extract the first
   25 characters of the field:

   FUNCTION POPULATE()
      USE customer NEW VIA "DBFCDX"

      // Construct unique file name based on last
      // name and id
      DO WHILE .NOT. Eof()
         GetPix("Pix", SubStr(LastName, 1, 4) + CustID)
         Customer->dbSkip()
      ENDDO
   FUNCTION GetPix(cPixField, cPixFile)
      LOCAL nPos

      nPos := FieldPos(cPixField)

      // Import the picture file into indicated field
      IF !BLOBImport(nPos, cPixFile)
         Alert("Import of picture " + cPixFile + ";
         failed!")
      ENDIF

Platforms

Available on MS-DOS

See also

BLOBROOTGET()


⌃ | ☰

Retrieve the data from the root area of a BLOB file

Syntax

Returns

BLOBROOTGET() returns the data retrieved from the root of the BLOB file. The data type of the return value depends on the actual data stored. Use ValType() or USUALTYPE() to determine the data type. Note that BLOBROOTGET() returns NIL if the root reference has never been written to with BLOBROOTPUT().

Description

BLOBROOTGET() allows the retrieval of a BLOB from the root of a BLOB file in a work area. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Note: Because the root data does not reference a particular record in the database file, the dbRLock() will not protect this root storage reference. Therefore, if the database file is opened in shared mode, you should use BLOBROOTLOCK() before calling BLOBROOTGET().

Examples

■  This example uses BLOBROOTGET() to read system settings from a
   BLOB file into an array, and then demonstrates how to allow the user
   to modify the settings and restore them in the BLOB file:

   FUNCTION UPDATESETTINGS()
      LOCAL aSettings

      USE customer NEW SHARED VIA "DBFCDX"

      IF BLOBROOTLOCK()
         // Get any existing settings
         aSettings := BLOBROOTGET()

         IF Empty(aSettings)
            // This function would populate aSettings
            // with default data
            aSettings := GETDEFAULTSETTINGS()
         ENDIF

         // This function would allow the user to
         // modify the settings.
         IF ModifySettings(aSettings)
            // Finally, store the settings
            BLOBRootPut(aSettings)
         ENDIF
         BLOBROOTUNLOCK()
      ELSE
         aSettings := {}
         Alert("Could not obtain a lock on the root;
            area")
      ENDIF

      CLOSE

      RETURN aSettings

Platforms

Available on MS-DOS

See also

BLOBROOTLOCK()


⌃ | ☰

Obtain a lock on the root area of a BLOB file

Syntax

BLOBROOTLOCK() → lSuccess

Returns

BLOBROOTLOCK() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

Use BLOBROOTLOCK() when accessing the database file in shared mode to obtain a lock on the root area of a BLOB file for reading from or writing to the root area.

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  This example illustrates how to properly lock and unlock the
   root area of a BLOB file for a database file opened in shared mode:

   FUNCTION GETSETTINGS()
   LOCAL aCustSettings

   // Open a customer file in shared mode
   USE customer NEW SHARED DBFCDX

   IF BLOBROOTLOCK()
      aCustSettings := BLOBROOTGET()
      BLOBROOTUNLOCK()
   ELSE
      Alert("Could not obtain root lock of Customer;
         file")
   ENDIF

   CLOSE

   RETURN aCustSettings

Platforms

Available on MS-DOS

See also

BLOBROOTPUT()


⌃ | ☰

Store data in the root area of a BLOB file

Syntax

BLOBRootPut(<uBLOB>) → lSuccess

Arguments

uBLOB is the data you want to put into the BLOB file’s root area. uBLOB can be any CA-Clipper usual data type except code block and object.

Returns

BLOBROOTPUT() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

BLOBROOTPUT() allows the storage of one—and only one—piece of data to a BLOB file’s root area (there is no size limitation on this one piece of data). After storing the new data, BLOBROOTPUT() releases the space associated with any data previously stored in the BLOB file’s root area.

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Note: Because the root data does not reference a particular record in the database file, the dbRLock() will not protect this root storage reference. Therefore, if the database file is opened in shared mode, you should use BLOBROOTLOCK() before calling BLOBROOTPUT().

Examples

■  This example uses BLOBROOTPUT() to store system settings to a
   BLOB file after modification:

   FUNCTION UPDATESETTINGS()
      LOCAL aSettings

      USE customer NEW SHARED VIA "DBFCDX"

      IF BLOBROOTLOCK()
         // Get any existing settings
         aSettings := BLOBROOTGET()

         IF Empty(aSettings)
            // This function would populate aSettings
            // with default data
            aSettings := GETDEFAULTSETTINGS()
         ENDIF

         // This function would allow the user to
         // modify the settings.
         IF ModifySettings(aSettings)
            // Finally, store the settings
            BLOBRootPut(aSettings)
         ENDIF
         BLOBROOTUNLOCK()
      ELSE
         aSettings := {}

         Alert("Could not obtain a lock on the root;
            area")
      ENDIF

      CLOSE

      RETURN aSettings

Platforms

Available on MS-DOS

See also

BLOBROOTUNLOCK()


⌃ | ☰

Release the lock on a BLOB file’s root area

Syntax

Description

Use BLOBROOTUNLOCK() to release a lock previously obtained using BLOBROOTLOCK().

By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Note: The only functions that require the use of BLOBROOTLOCK() or BLOBROOTUNLOCK() are BLOBROOTGET() and BLOBROOTPUT().

Examples

■  This example illustrates how to properly lock and unlock the
   root area of a BLOB file for a database file opened in shared mode:

   FUNCTION GETSETTINGS()
      LOCAL aCustSettings

      // Open a customer file in shared mode
      USE customer NEW SHARED VIA DBFCDX

      IF BLOBROOTLOCK()
         aCustSettings := BLOBROOTGET()
         BLOBROOTUNLOCK()
      ELSE
         Alert("Could not obtain root lock of Customer;
            file")
      ENDIF

      CLOSE

      RETURN aCustSettings

Platforms

Available on MS-DOS

See also

Bof()Harbour implementation


⌃ | ☰

Determine when beginning of file is encountered

Syntax

Returns

Bof() returns true (.T.) after an attempt to SKIP backward beyond the first logical record in a database file; otherwise, it returns false (.F.). If there is no database file open in the current work area, Bof() returns false (.F.). If the current database file contains no records, Bof() returns true (.T.).

Description

Bof() is a database function used to test for a boundary condition when you are moving the record pointer backward through a database file using the SKIP command. A simple usage example is a descending order record list with an ascending order index file. A more sophisticated example is a screen paging routine that pages forward or backward through the current database file based on the key the user presses. When the user attempts to page backward, you would use Bof() to test for a beginning of file condition before using the SKIP command to move the record pointer and repaint the screen.

Once Bof() is set to true (.T.), it retains its value until there is another attempt to move the record pointer.

By default, Bof() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression (see example below).

The SKIP command is the only record movement command that can set Bof() to true (.T.).

Examples

■  This example demonstrates Bof() by attempting to move the
   record pointer before the first record:

   USE Sales NEW
   ? RecNo(), Bof()               // Result: 1 .F.
   SKIP -1
   ? RecNo(), Bof()               // Result: 1 .T.

■  This example uses aliased expressions to query the value of
   Bof() in unselected work areas:

   USE Sales NEW
   USE Customer NEW
   USE Invoices NEW

   ? Sales->(Bof()), Customer->(Bof())

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Break()Harbour implementation


⌃ | ☰

Branch out of a BEGIN SEQUENCE…END construct

Syntax

Arguments

exp is the value passed to the RECOVER clause, if any. Note that exp is not optional. NIL may be specified if there is no break value.

Returns

Break() always returns NIL.

Description

The Break() function is identical in functionality to the BREAK statement. The function must be executed during a SEQUENCE. Break() has the advantage that, as an expression, it can be executed from a code block.

Examples

■  This example illustrates exiting a SEQUENCE from a code block:

   bSave := ErrorBlock( {|x| Break(x)} )

   BEGIN SEQUENCE
      .
      .
      .
   RECOVER USING objError
      .
      .
      .
   END

   ErrorBlock(bSave)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Browse()*Harbour implementation


⌃ | ☰

Browse records within a window

Syntax

Browse([<nTop>], [<nLeft>],
   [<nBottom>], [<nRight>]) lSuccess

Arguments

nTop, nLeft, nBottom, and nRight define the window coordinates. If not specified, the default window coordinates are 1, 0 to MaxRow(), and MaxCol().

Returns

Browse() returns false (.F.) if there is no database file in use; otherwise, it returns true (.T.).

Description

Browse() is a user interface function that invokes a general purpose table-oriented browser and editor for records in the current work area. For a list of the navigation keys which are used by Browse(), refer to the dbEdit() function. Note that Browse() is a compatibility function. dbEdit() should be used in its place. For a more complicated Browse(), TBrowse() should be used.

Notes

■ Status line: Browse() supports a status line in the upper

right corner of the browse window indicating one of the following:

Browse() Status Line Messages

       Message   Meaning

       <new>     Append mode

       <bof>     Top of file

       <delete>  Current record is deleted

       Record    Record number display

Browse() has the following three modes:

— Browsing: This is the default mode of Browse(). Pressing any

dbEdit() navigation key moves the highlight to a new column or row.

— Field edit: Pressing Return on any field enters field edit

using a GET. Pressing Return terminates the edit mode, saving the changes. Esc terminates without saving changes. Since the field edit mode uses GET, all navigation and editing keys are READ keys.

— Append: GOing BOTTOM with Ctrl+PgDn and then pressing Down

arrow enters append mode with the indicating message «new» on the status line. A new blank record is then inserted. Pressing Up arrow terminates the append mode, saving the new record if data has been entered. If no data has been entered, the new record is not saved.

Examples

■  This is an example of browsing a file:

   USE File1 NEW
   Browse()

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/BROWSE.PRG

See also

CALL*Harbour implementation⌃ | ☰

Execute a C or Assembler procedure

Syntax

CALL <idProcedure> [WITH <exp list>]

Arguments

idProcedure is the name of the external procedure to CALL.

WITH exp list is an optional list of up to seven expressions of any data type to pass to the external procedure.

Description

CALL executes a separately compiled or assembled procedure. The procedure must be defined as FAR and end with a FAR return instruction. Place parameters on the stack using the C parameter passing convention. Each parameter consists of a FAR (four-byte) pointer to the actual parameter value. When necessary you may use the Word() function to pass a two-byte binary value in the WITH expression. The DX:BX and ES:BX registers also contain a copy of the first four bytes of parameter information.

The procedure must preserve the BP, SS, SI, DI, ES, and DS registers as well as clear the direction flag.

CALL is a compatibility command and therefore not recommended. It is superseded by the Extend system which provides functions for passing data to and from CA-Clipper.

Notes

■ Character strings: Pass a character argument as a FAR pointer

to a null-terminated string (a string with a 00 hex byte at the end).

■ Numeric values: Pass each numeric argument as a FAR pointer

to an eight-byte IEEE floating point value. To pass a parameter as an integer, use the Word() function. The Word() function converts the numeric value to a two-byte binary integer, and passes the integer value directly rather than through a pointer. Note that Word() will not work for values outside of the ▒32,767 range since these values cannot be accurately represented as two-byte integers.

■ Date values: Pass each date argument as a FAR pointer to a

four-byte (long) integer containing a Julian day number.

■ Logical values: Pass each logical argument as a FAR pointer

to a two-byte binary integer containing zero for false (.F.) and one for true (.T.) .

■ Compiling and linking: CALLed programs must conform to the

following rules:

— Procedures must be in INTEL 8086 relocatable object file

format with the .OBJ file extension.

— Procedures must follow the C calling and parameter passing

conventions.

— Procedures must be available to the linker at link time, along

with the library of the source compiler. You will need runtime support for any language other than assembly language. See your compiler manual for further information.

■ Screen position: When using a CALL statement to access a C or

Assembler routine, the cursor is set to the current screen position within the C or Assembler routine.

■ Microsoft C: Microsoft C versions 5.0 and above place a

leading underscore on function names when they are compiled. To call them, therefore, you must CALL _function.

■ dBASE III PLUS: To convert a dBASE III PLUS load module to a

CA-Clipper-compatible module, add the following statements to your .asm file:

PUBLIC proc

and

push ds mov ds, dx

Warning! Modifying the parameter values may produce incorrect or unexpected results and, therefore, is strongly discouraged.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CANCEL*Harbour implementation⌃ | ☰

Terminate program processing

Syntax

Description

CANCEL and QUIT both terminate the current program, closing all open files, and returning control to the operating system. You can use either command from anywhere in a CA-Clipper program system. A RETURN executed at the highest level procedure performs the same action. Note that CANCEL is a compatibility command. QUIT should be used in its place.

Notes

■ Return code: When a CA-Clipper program terminates, the return

code is set to 1 if the process ends with a fatal error. If the process ends normally, the return code is set to 0 or the last ErrorLevel() set in the program.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CDoW()Harbour implementation


⌃ | ☰

Convert a date value to a character day of the week

Syntax

Arguments

dExp is the date value to convert.

Returns

CDoW() returns the name of the day of the week as a character string. The first letter is uppercase and the rest of the string is lowercase. For a null date value, CDoW() returns a null string («»).

Description

CDoW() is a date conversion function used in formatting date displays for reports, labels, and screens.

Examples

■  These examples illustrate CDoW():

   ? Date()                      // Result: 09/01/90
   ? CDoW(Date())                // Result: Friday
   ? CDoW(Date() + 7)            // Result: Friday
   ? CDoW(CToD("06/12/90"))      // Result: Tuesday

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CheckBox class⌃ | ☰

Create check boxes, which are controls that can be toggled on or off by a user

Description

Check boxes present a choice to the user which can be either on or off. When a check box is clicked, its state is toggled (as indicated by an X in the box) between checked (on) and unchecked (off).

The CheckBox class has been designed to be easily integrated into the standard CA-Clipper GET/READ system in addition to providing the necessary functionality to be utilized on its own.

Methods link

CheckBox() Create a new CheckBox object


CheckBox(nRow, nColumn,

[,cCaption]) → oCheckBox

Arguments

nRow is a numeric value that indicates the screen row of the check box.

nColumn is a numeric value that indicates the screen column of the check box.

nCaption is an optional character string that describes the check box on the screen. If omitted, the default is an empty string.

Returns

Returns a CheckBox object when all of the required arguments are present; otherwise, CheckBox() returns NIL.

Exported Instance Variables


bitmaps An array of bitmap files to be displayed


bitmaps (Assignable)

Contains an array of exactly two elements that indicates the bitmap files to be displayed. The first element indicates the file name of the bitmap to be displayed when the check box is selected. The second element indicates the file name of the bitmap to be displayed when the check box is not selected.

Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.

CA-Clipper will search for the file name first, and if it is not found, then search in the bitmap library. If no file is found either on disk or in the library, no bitmap will be displayed.

If this instance variable is not used, and the application is running in graphic mode, the files CHECK_F.BMU and CHECK_E.BMU will be used for the selected bitmap and unselected bitmap, respectively.

This instance variable only affects applications running in graphic mode and is ignored in text mode.

buffer Logical value indicating checked or unchecked


buffer

Contains a logical value that indicates whether the check box is checked or unchecked. A value of true (.T.) indicates that it is checked and a value of false (.F.) indicates that it is not checked.

capCol Numeric value indicating screen column


capCol (Assignable)

Contains a numeric value that indicates the screen column where the check box’s caption is displayed.

capRow Numeric value indicating screen row


capRow (Assignable)

Contains a numeric value that indicates the screen row where the check box’s caption is displayed.

caption Character string describing the check box


caption (Assignable)

Contains an optional character string that concisely describes the check box on the screen. If omitted, the default is an empty string.

When present, the & character specifies that the character immediately following it in the caption is the check box’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to the check box. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the CheckBox object. CheckBox:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a CheckBox object and retrieved later.

col Numeric value indicating screen column


col (Assignable)

Contains a numeric value that indicates the screen column where the check box is displayed.

colorSpec Character string indicating color attributes


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the check box’s display() method. The string must contain four color specifiers.

Note: In graphic mode, colorSpec positions 1 and 2 have no affect and are ignored.

CheckBox Color Attributes

       Position        Applies To                  Default Value from System

       in colorSpec                                Color setting

       1               The check box when it does  Unselected

                       not have input focus

       2               The check box when it has   Enhanced

                       input focus

       3               The check box’s caption     Standard

       4               The check box caption’s     Background

                       accelerator key

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are those listed in the drop-down list box of the Workbench Properties window for that item.

fBlock Code block evaluated at each input focus change


fBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the CheckBox object receives or loses input focus. The code block takes no implicit arguments. Use CheckBox:hasFocus to determine if the check box is receiving or losing input focus. A value of true (.T.) indicates that it is receiving input focus; otherwise, a value of false (.F.) indicates that it is losing input focus.

This code block is included in the CheckBox class to provide a method of indicating when an input focus change event has occurred. The name «fBlock» refers to focus block.

hasFocus Logical value indicating the input focus


hasFocus

Contains a logical value that indicates whether the CheckBox object has input focus. CheckBox:hasFocus contains true (.T.) if it has input focus; otherwise, it contains false (.F.).

message Character string describing check box


message (Assignable)

Contains a character string that describes the check box. It is displayed on the screen’s status bar line.

row Numeric value indicating screen row


row (Assignable)

Contains a numeric value that indicates the screen row where the check box is displayed.

sBlock Code block evaluated at every state change


sBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the CheckBox object’s state changes. The code block takes no implicit arguments. Use the buffer instance variable to determine if the check box is being checked or unchecked. A value of true (.T.) indicates that it is being checked; otherwise, a value of false (.F.) indicates that it is being unchecked.

This code block is included in the CheckBox class to provide a method of indicating when a state change event has occurred. The name «sBlock» refers to state block.

style Character string indicating delimiter characters


style (Assignable)

Contains a character string that indicates the delimiter characters that are used by the check box’s display() method. The string must contain four characters. The first is the left delimiter. Its default value is the left square bracket ([) character. The second is the checked indicator. Its default value is the square root character. The third is the unchecked indicator. Its default is the space character (» «). The fourth character is the right delimiter. Its default value is the right square bracket (]) character.

Note: The style instance variable is ignored in graphic mode.

typeOut Logical value false (.F.)


typeOut

Contains the logical value false (.F.). CheckBox:typeOut never changes. It is not used by the CheckBox object and is only provided for compatibility with the other GUI control classes.

display() Shows a check box and caption on the screen


oCheckBox:display() → self

display() is a method of the CheckBox class that is used for showing a check box and its caption on the screen. display() uses the values of the following instance variables to correctly show the check box in its current context in addition to providing maximum flexibility in the manner a check box appears on the screen: buffer, caption, capCol, capRow, col, colorSpec, hasFocus, row, and style.

HitTest() Indicates position of mouse cursor relative to check box


oCheckBox:hitTest(nMouseRow, nMouseCol)

→ nHitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the relationship of the mouse cursor with the check box. HitTest() is a method of the CheckBox class that is used for determining if the mouse cursor is within the region of the screen that the check box or its caption occupies.

Applicable Hit Test Return Values

       Value     Constant    Description

       0         HTNOWHERE   The mouse cursor is not within the region of

                             the screen that the check box occupies

       -1025     HTCAPTION   The mouse cursor is on the check box’s caption

       -2049     HTCLIENT    The mouse cursor is on the check box

Button.ch contains manifest constants for the HitTest() return value.

killFocus() Takes input focus away from the CheckBox object


oCheckBox:killFocus() → self

killFocus() is a method of the CheckBox class that is used for taking input focus away from a CheckBox object. Upon receiving this message, the CheckBox object redisplays itself and, if present, evaluates the code block within its fBlock variable.

This message is meaningful only when the CheckBox object has input focus.

Select() Determines whether check box should be checked


oCheckBox:select([lNewState]) → self

lNewState is a logical value that indicates whether the check box should be checked or not. Set to true (.T.) to check the box or false to uncheck the box. If omitted, the check box state will toggle to its opposing state.

Select() is a method of the CheckBox class that is used for changing the state of a check box. Its state is typically changed when the space bar is pressed or the mouse’s left button is pressed when its cursor is within the check box’s region of the screen.

setFocus() Gives input focus to the CheckBox object


oCheckBox:setFocus() → self

setFocus() is a method of the CheckBox class that is used for giving focus to a CheckBox object. Upon receiving this message, the CheckBox object redisplays itself and if present, evaluates the code block within its fBlock variable.

This message is meaningful only when the CheckBox object does not have input focus.

Examples

■  This example creates and integrates a check box within a Get
   List and activates it by performing a READ:

   STORE SPACE (25) TO Name
   STORE .T. TO Married
   STORE SPACE (19) TO Phone

   CLS

   @    5,10 SAY "Customer Name: " GET Name
   @  7,10 SAY "Married?:     " GET Married CHECKBOX
   @  9,10 SAY "Home Phone:    " GET Phone

   READ

   ? ALLTRIM (Name) + " IS " + IIF(Married,"","NOT") + "Married."
   WAIT

Platforms

Available on MS-DOS

Chr()Harbour implementation


⌃ | ☰

Convert an ASCII code to a character value

Syntax

Arguments

nCode is an ASCII code in the range of zero to 255.

Returns

Chr() returns a single character value whose ASCII code is specified by nCode.

Description

Chr() is a numeric conversion function that converts an ASCII code to a character. It is the inverse of Asc(). Chr() serves a number of common tasks including:

■ Sending control codes and graphics characters to the screen or

printer

■ Ringing the bell

■ Converting Inkey() return values to characters

■ Stuffing the keyboard buffer

Notes

■ The null character: Chr(0) has a length of one (1) and is

treated like any other character. This lets you send it to any device or file, including a database file.

Examples

■  These examples illustrate Chr() with various arguments:

   ? Chr(72)                    // Result: H
   ? Chr(Asc("A") + 32)         // Result: a
   ? Chr(7)                     // Result: bell sounds

■  These lines of code show the difference between a null string
   and the null character:

   ? Len("")                   // Result: 0
   ? Len(Chr(0))               // Result: 1

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CLEAR ALL*Harbour implementation⌃ | ☰

Close files and release public and private variables

Syntax

Description

CLEAR ALL releases all public and private variables, closes all open databases and related files in all active work areas, and SELECTs work area 1. Related files are index, alternate, and memo files. CLEAR ALL, however, does not release local or static variables.

CLEAR ALL is a compatibility command and therefore not recommended. Its usage in CA-Clipper is superseded by the command or function that performs the specific action you need. You can close files associated with work areas with one of the various forms of the CLOSE command. You can release private and public variables using the RELEASE command although explicitly releasing variables is discouraged in most instances. For more information on the scope and lifetime of variables, refer to the «Basic Concepts» chapter in the Programming and Utilities Guide.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CLEAR GETSHarbour implementation⌃ | ☰

Release Get objects from the current GetList array

Syntax

Description

CLEAR GETS explicitly releases all Get objects in the current and visible GetList array, and terminates the calling READ, releasing any remaining objects in the calling READ, if executed within a SET KEY procedure or a user-defined function invoked by a VALID clause. CLEAR GETS releases Get objects by assigning an empty array to the variable GetList. GetList is the name of the variable used to hold an array of Get objects for subsequent READ commands. There are two other mechanisms that automatically release Get objects: CLEAR specified without the SCREEN clause, and READ specified without the SAVE clause.

CLEAR GETS has two basic uses. First, it can be used to terminate a READ from a SET KEY procedure or VALID user-defined function. Second, it can be used to delete Get objects from the GetList array when you have not executed a READ or you have saved the Get objects by using READ SAVE.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CLEAR MEMORYHarbour implementation⌃ | ☰

Release all public and private variables

Syntax

Description

CLEAR MEMORY deletes both public and private memory variables from the memory variable table. It operates in contrast to RELEASE ALL, which does not actually delete public and private memory variables but assigns NIL to those whose scope is the current procedure. CLEAR MEMORY is the only way to delete all public memory variables from current memory. Local and static variables, however, are unaffected by CLEAR MEMORY.

For more information on variables, refer to the Variables section of the «Basic Concepts» chapter in the Programming and Utilities Guide.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CLEAR SCREENHarbour implementation⌃ | ☰

Clear the screen and return the cursor home

Syntax

Arguments

SCREEN suppresses the automatic releasing of Get objects from the current and visible GetList array when the screen is CLEARed.

Description

CLEAR is a full-screen command that erases the screen, releases pending GETs, and positions the cursor at row and column zero. If the SCREEN clause is specified, Get objects are not released.

CLS is a synonym for CLEAR SCREEN.

Notes

SET KEY and VALID: If you are editing GETs, executing a CLEAR

within a SET KEY procedure or within a VALID user-defined function will abort the active READ when control returns. To clear the screen without CLEARing GETs, use either the CLEAR SCREEN or CLS commands.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CLEAR TYPEAHEADHarbour implementation⌃ | ☰

Empty the keyboard buffer

Syntax

Description

CLEAR TYPEAHEAD is a keyboard command that clears all pending keys from the CA-Clipper keyboard buffer. This is useful in user interface procedures or user-defined functions to guarantee that keys processed from the keyboard buffer are appropriate to the current activity and not pending from a previous activity. User functions called by AChoice() and dbEdit() are especially sensitive to such keys.

Note that both the SET TYPEAHEAD and KEYBOARD commands also clear the keyboard buffer.

Examples

■  This example empties the keyboard buffer before invoking
   dbEdit(), guaranteeing that any pending keys will not be executed:

   CLEAR TYPEAHEAD
   dbEdit()

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CLOSEHarbour implementation⌃ | ☰

Close a specific set of files

Syntax

CLOSE [<idAlias> | ALL | ALTERNATE | DATABASES |
   FORMAT | INDEXES]

Arguments

idAlias specifies the work area where all files are to be closed.

ALL closes alternate, database, and index files in all work areas, releasing all active filters, relations, and format definitions.

ALTERNATE closes the currently open alternate file, performing the same action as SET ALTERNATE TO with no argument.

DATABASES closes all open databases, memo and associated index files in all work areas, and releases all active filters and relations. It does not, however, have any effect on the active format.

FORMAT releases the current format, performing the same action as SET FORMAT TO with no argument.

INDEXES closes all index files open in the current work area.

Description

CLOSE is a general purpose command that closes various types of CA-Clipper files depending on the specified option. CLOSE with no option closes the current database and associated files, the same as USE with no arguments.

In CA-Clipper, a number of other commands also close files including:

QUIT

■ CANCEL*

RETURN from the highest level procedure

CLEAR ALL*

USE with no argument

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CMonth()Harbour implementation


⌃ | ☰

Convert a date to a character month name

Syntax

Arguments

dDate is the date value to convert.

Returns

CMonth() returns the name of the month as a character string from a date value with the first letter uppercase and the rest of the string lowercase. For a null date value, CMonth() returns a null string («»).

Description

CMonth() is a date conversion function useful for creating formatted date strings that can be used in reports, labels, or screens.

Examples

■  These examples illustrate CMonth():

   ? CMonth(Date())                     // Result: September
   ? CMonth(Date() + 45)                // Result: October
   ? CMonth(CToD("12/01/94"))           // Result: December
   ? SubStr(CMonth(Date()), 1, 3) +;
      Str(Day(Date()))                  // Result: Sep 1

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Col()Harbour implementation


⌃ | ☰

Return the screen cursor column position

Syntax

Returns

Col() returns an integer numeric value. The range of the return value is zero to MaxCol().

Description

Col() is a screen function that returns the current column position of the cursor. The value of Col() changes whenever the cursor position changes on the screen. Both console and full-screen commands can change the cursor position. In addition, Col() is automatically set to zero whenever a CLEAR, CLEAR SCREEN, or CLS command is executed.

Use Col() to position the cursor to a column relative to the current column. It is generally used in combination with Row() and all variations of the @ command. In particular, use Col() and Row() to create screen position-independent procedures or functions that pass the upper-left row and column as parameters.

If DEVICE is SET TO PRINTER, all the output of @...SAY commands is directed to the printer and PRow() and PCol() are updated instead of Row() and Col(). Use these functions when you need to determine the position of the printhead.

Examples

■  This example displays a Customer name beginning at column 10.
   The customer's account status is then displayed to the right of the
   last character of the customer name using Col():

USE Sales NEW

   CLS
   @ 1, 10 SAY "Customer Name: " + Trim(Customer)
   @ Row(), Col() + 1 SAY "Account status: " + Status

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ColorSelect()Harbour implementation


⌃ | ☰

Activate attribute in current color settings

Syntax

ColorSelect(<nColorIndex>) → NIL

Arguments

nColorIndex is a number corresponding to the ordinal positions in the current list of color attributes, as set by SetColor().

Returns

Always returns NIL.

Description

ColorSelect() activates the specified color pair from the current list of color attributes (established by SetColor()). Manifest constants for nColorIndex are defined in color.ch.

Color.ch constants

    Constant          Value

    CLR_STANDARD      0

    CLR_ENHANCED      1

    CLR_BORDER        2

    CLR_BACKGROUND    3

    CLR_UNSELECTED    4

ColorSelect() does not alter the current SET Color setting.

This table describes the scope of the CA-Clipper color settings affected by SetColor():

Color settings

    Setting        Scope

    Standard       All screen output commands and functions

    Enhanced       GETs and selection highlights

    Border         Screen border (not supported on EGA and VGA monitors)

    Background     Not supported

    Unselected     Unselected GETs

Examples

■  This example demonstrates use of ColorSelect() with the
   color.ch manifest constants:

   USE Sales NEW
   ? SetColor()                   // displays "W/B,N/B,W/N,W/N,W/N"
                                  // in white on blue

   ColorSelect(CLR_ENHANCED)      // enhanced is active color pair
   ? "I'm black and blue"         // displayed in black on blue
   ColorSelect(CLR_STANDARD)      // restore standard color

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is color.ch.

See also

COMMITHarbour implementation⌃ | ☰

Perform a solid-disk write for all active work areas

Syntax

Description

COMMIT is a database command that flushes CA-Clipper buffers and performs a solid-disk write for all work areas with open database and index files. The solid-disk write capability is available under DOS version 3.3 and above. Under DOS 3.2 or less, COMMIT flushes CA-Clipper buffers to DOS.

In a network environment, issuing a GO TO RecNo() or a SKIP0 will flush CA-Clipper’s database and index buffers, but only a COMMIT will flush the buffers and perform a solid-disk write. Thus to insure updates are visible to other processes, you must issue a COMMIT after all database update commands (e.g., APPEND, REPLACE). To insure data integrity, COMMIT should be issued before an UNLOCK operation. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information on update visibility.

Notes

COMMIT uses DOS interrupt 21h function 68h to perform the

solid-disk write. It is up to the network operating system to properly implement this request. Check with the network vendor to see if this is supported.

Examples

■  In this example, COMMIT forces a write to disk after a series
   of memory variables are assigned to field variables:

   USE Sales EXCLUSIVE NEW
   MEMVAR->Name := Sales->Name
   MEMVAR->Amount := Sales->Amount
   //
   @ 10, 10 GET MEMVAR->Name
   @ 11, 10 GET MEMVAR->Amount
   READ
   //
   IF Updated()
      APPEND BLANK
      REPLACE Sales->Name WITH MEMVAR->Name
      REPLACE Sales->Amount WITH MEMVAR->Amount
      COMMIT
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CONTINUEHarbour implementation⌃ | ☰

Resume a pending LOCATE

Syntax

Description

CONTINUE is a database command that searches from the current record position for the next record meeting the most recent LOCATE condition executed in the current work area. It terminates when a match is found or end of file is encountered. If CONTINUE is successful, the matching record becomes the current record and Found() returns true (.T.); if unsuccessful, Found() returns false (.F.).

Each work area may have an active LOCATE condition. In CA-Clipper, a LOCATE condition remains pending until a new LOCATE condition is specified. No other commands release the condition.

Notes

■ Scope and WHILE condition: Note that the scope and WHILE

condition of the initial LOCATE are ignored; only the FOR condition is used with CONTINUE. If you are using a LOCATE with a WHILE condition and want to continue the search for a matching record, use SKIP and then repeat the original LOCATE statement adding REST as the scope.

Examples

■  This example scans records in Sales.dbf for a particular
   salesman and displays a running total sales amounts:

   LOCAL nRunTotal := 0
   USE Sales NEW
   LOCATE FOR Sales->Salesman = "1002"
   DO WHILE Found()
      ? Sales->Salesname, nRunTotal += Sales->Amount
      CONTINUE
   ENDDO

■  This example demonstrates how to continue if the pending
   LOCATE scope contains a WHILE condition:

   LOCAL nRunTotal := 0
   USE Sales INDEX Salesman NEW
   SEEK "1002"
   LOCATE REST WHILE Sales->Salesman = "1002";
         FOR Sales->Amount > 5000
   DO WHILE Found()
      ? Sales->Salesname, nRunTotal += Sales->Amount
      SKIP
      LOCATE REST WHILE Sales->Salesman = "1002";
         FOR Sales->Amount > 5000
   ENDDO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

COPY FILEHarbour implementation⌃ | ☰

Copy a file to a new file or to a device

Syntax

COPY FILE <xcSourceFile> TO <xcTargetFile>|<xcDevice>

Arguments

xcSourceFile is the name of the source file to copy including the extension.

xcTargetFile is the name of the target file including the extension.

Both arguments can be specified as literal file names or as character expressions enclosed in parentheses. COPY FILE supplies no default extensions.

xcDevice is the name of the device where all subsequent output will be sent. You can specify a device name as a literal character string or a character expression enclosed in parentheses. Additionally, a device can be either local or network. If you COPY TO a non-existing device, you create a file with the name of the device. When specifying device names, do not use a trailing colon.

Description

COPY FILE is a file command that copies files to and from the CA-Clipper default drive and directory unless you specify a drive and/or path. If the xcTargetFile exists, it is overwritten without warning or error.

Examples

■  This example copies a file to a new file and then tests for
   the existence of the new file:

   COPY FILE Test.prg TO Real.prg
   ? FILE("Real.prg")                  // Result: .T.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

COPY STRUCTUREHarbour implementation⌃ | ☰

Copy the current .dbf structure to a new database (.dbf) file

Syntax

COPY STRUCTURE [FIELDS <idField list>]
   TO <xcDatabase>

Arguments

FIELDS idField list defines the set of fields to copy to the new database structure in the order specified. The default is all fields.

TO xcDatabase is the name of the target database file and can be specified either as a literal database file name or as a character expression enclosed in parentheses. The default extension is .dbf unless another is specified.

Description

COPY STRUCTURE is a database command that creates an empty database file with field definitions from the current database file. If xcDatabase exists, it is overwritten.

COPY STRUCTURE creates empty structures that can be used to archive records from the current database file or to create a temporary database file for data entry.

Examples

■  In this example, COPY STRUCTURE creates a temporary file.
   After the user enters data into the temporary file, the master
   database file is updated with the new information:

   USE Sales NEW
   COPY STRUCTURE TO Temp
   USE Temp NEW
   lMore := .T.
   DO WHILE lMore
      APPEND BLANK
      @ 10, 10 GET Temp->Salesman
      @ 11, 11 GET Temp->Amount
      READ
      IF Updated()
         SELECT Sales
         APPEND BLANK
         REPLACE Sales->Salesman WITH Temp->Salesman
         REPLACE Sales->Amount WITH Temp->Amount
         SELECT Temp
         ZAP
      ELSE
         lMore := .F.
      ENDIF
   ENDDO
   CLOSE DATABASES

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

COPY STRUCTURE EXTENDEDHarbour implementation⌃ | ☰

Copy field definitions to a .dbf file

Syntax

COPY STRUCTURE EXTENDED
   TO <xcExtendedDatabase>

Arguments

TO xcExtendedDatabase is the name of the target structure extended database file. This argument can be specified either as a literal database file name or as a character expression enclosed in parentheses.

Description

COPY STRUCTURE EXTENDED creates a database file whose contents is the structure of the current database file with a record for the definition of each field. The structure extended database file has the following structure:

Structure of an Extended File

    Field   Name           Type         Length    Decimals

    1       Field_name     Character    10

    2       Field_type     Character    1

    3       Field_len      Numeric      3         0

    4       Field_dec      Numeric      4         0

Used in application programs, COPY STRUCTURE EXTENDED permits you to create or modify the structure of a database file programmatically. To create a new database file from the structure extended file, use CREATE FROM. If you need an empty structure extended file, use CREATE.

Notes

■ Character field lengths greater than 255: In CA-Clipper, the

maximum character field length is 64K. For compatibility reasons, field lengths greater than 255 are represented as a combination of the Field_dec and Field_len fields. After COPYing STRUCTURE EXTENDED, you can use the following formula to determine the length of any character field:

nFieldLen := IF(Field_type = «C» .AND. ;

Field_dec != 0, Field_dec * 256 + ; Field_len, Field_len)

Examples

■  This example creates Struc.dbf from Sales.dbf as a structure
   extended file and then lists the contents of Struc.dbf to illustrate
   the typical layout of field definitions:

   USE Sales NEW
   COPY STRUCTURE EXTENDED TO Struc
   USE Struc NEW
   LIST Field_name, Field_type, Field_len, Field_dec

   Result:

   1 BRANCH        C      3      0
   2 SALESMAN      C      4      0
   3 CUSTOMER      C      4      0
   4 PRODUCT       C     25      0
   5 AMOUNT        N      8      2
   6 NOTES         C      0    125
   // Field length is 32,000 characters

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

COPY TOHarbour implementation⌃ | ☰

Export records to a new database (.dbf) file or ASCII text file

Syntax

COPY [FIELDS <idField list>] TO <xcFile>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
   [SDF | DELIMITED [WITH BLANK | <xcDelimiter>] |
   [VIA <xcDriver>]]

Arguments

FIELDS idField list specifies the list of fields to copy to the target file. The default is all fields.

TO xcFile specifies the name of the target file. The file name can be specified either as a literal file name or as a character expression enclosed in parentheses. If SDF or DELIMITED is specified, .txt is the default extension. Otherwise, .dbf is the default extension.

scope defines the portion of the current database file to COPY. The default is ALL records.

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

FOR lCondition specifies the conditional set of records to copy within the given scope.

SDF specifies the output file type as a System Data Format ASCII text file. Records and fields are fixed length.

DELIMITED specifies the output file type as a delimited ASCII text file where character fields are enclosed in double quotation marks (the default delimiter). Records and fields are variable length.

DELIMITED WITH BLANK identifies an ASCII text file in which fields are separated by one space and character fields have no delimiters.

DELIMITED WITH xcDelimiter identifies a delimited ASCII text file where character fields are enclosed using the specified delimiter. xcDelimiter can be specified either as a literal character or as a character expression enclosed in parentheses.

See the tables below for more information regarding the format specifications for ASCII text files created using these arguments.

VIA xcDriver specifies the replaceable database driver (RDD) to use to create the resulting copy. cDriver is name of the RDD specified as a character expression. If cDriver is specified as a literal value, it must be enclosed in quotes.

If the VIA clause is omitted, COPY TO uses the driver in the current work area. If you specify the VIA clause, you must REQUEST the appropriate RDDs to be linked into the application.

Note: If the DELIMITED WITH clause is specified on a COPY or APPEND command, it must be the last clause specified.

Description

COPY TO is a database command that copies all or part of the current database file to a new file. Records contained in the active database file are copied unless limited by a scope, a FOR|WHILE clause, or a filter.

If DELETED is OFF, deleted records in the source file are copied to xcFile where they retain their deleted status. If DELETED is ON, however, no deleted records are copied. Similarly, if a FILTER has been SET, invisible records are not copied.

Records are copied in controlling index order if there is an index open in the current work area and SET ORDER is not zero. Otherwise, records are copied in natural order.

In a network environment, CA-Clipper opens the target database file EXCLUSIVEly before the COPY TO operation begins. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

This table shows the format specifications for SDF text files:

SDF Text File Format Specifications

    File Element        Format

    Character fields    Padded with trailing blanks

    Date fields         yyyymmdd

    Logical fields      T or F

    Memo fields         Ignored

    Numeric fields      Padded with leading blanks for zeros

    Field separator     None

    Record separator    Carriage return/linefeed

    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED and DELIMITED WITH xcDelimiter ASCII text files:

DELIMITED Text File Format Specifications

    File Element        Format

    Character fields    Delimited, with trailing blanks truncated

    Date fields         yyyymmdd

    Logical fields      T or F

    Memo fields         Ignored

    Numeric fields      Leading zeros truncated

    Field separator     Comma

    Record separator    Carriage return/linefeed

    End of file marker  1A hex or Chr(26)

This table shows the format specifications for DELIMITED WITH BLANK ASCII text files:

DELIMITED WITH BLANK Text File Format Specifications

    File Element        Format

    Character fields    Not delimited, trailing blanks truncated

    Date fields         yyyymmdd

    Logical fields      T or F

    Memo fields         Ignored

    Numeric fields      Leading zeros truncated

    Field separator     Single blank space

    Record separator    Carriage return/linefeed

    End of file marker  1A hex or Chr(26)

Examples

■  This example demonstrates copying to another database file:

   USE Sales NEW
   COPY TO Temp

■  This example demonstrates the layout of a DELIMITED file:

   COPY NEXT 1 TO Temp DELIMITED
   TYPE Temp.txt

   Result:

   "Character",12.00,19890801,T

■  This example demonstrates the layout of an SDF file with four
   fields, one for each data type:

   USE Testdata NEW
   COPY NEXT 1 TO Temp SDF
   TYPE Temp.txt

   Result:

   Character     12.0019890801T

■  This example demonstrates the layout of a DELIMITED file WITH
   a different delimiter:

   COPY NEXT 1 TO Temp DELIMITED WITH '
   TYPE Temp.txt

   Result:

   'Character',12.00,19890801,T

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

COUNTHarbour implementation⌃ | ☰

Tally records to a variable

Syntax

COUNT TO <idVar>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]

Arguments

TO idVar identifies the variable that holds the COUNT result. A variable that either does not exist or is invisible is created as a private variable whose scope is the current procedure.

scope is the portion of the current database file to COUNT. The default is ALL records.

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

FOR lCondition specifies the conditional set of records to COUNT within the given scope.

Description

COUNT tallies the number of records from the current work area that match the specified record scope and conditions. The result is then placed in the specified variable. idVar can be a variable of any storage class including a field.

Examples

■  This example demonstrates a COUNT of Branches in Sales.dbf:

   USE Sales NEW
   COUNT TO nBranchCnt FOR Branch = 100
   ? nBranchCnt                           // Result: 4

■  This example tallies the number of records in Sales.dbf whose
   Branch has the value of 100 and assigns the result to the Count field
   in Branch.dbf for branch 100:

   USE Branch INDEX Branch NEW
   SEEK 100
   USE Sales INDEX SalesBranch NEW
   SEEK 100
   COUNT TO Branch->Count WHILE Branch = 100

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CREATEHarbour implementation⌃ | ☰

Create an empty structure extended (.dbf) file

Syntax

CREATE <xcExtendedDatabase>

Arguments

xcExtendedDatabase is the name of the empty structure extended database file. This argument can be specified either as a literal database file name or as a character expression enclosed in parentheses. If no extension is specified, .dbf is the default extension.

Description

CREATE produces an empty structure extended database file with the following structure:

Structure of an Extended File

    Field   Name           Type        Length    Decimals

    1       Field_name     Character   10

    2       Field_type     Character   1

    3       Field_len      Numeric     3         0

    4       Field_dec      Numeric     4         0

Like COPY STRUCTURE EXTENDED, CREATE can be used in conjunction with CREATE FROM to form a new database file. Unlike COPY STRUCTURE EXTENDED, CREATE produces an empty database file and does not require the presence of another database file to create it.

xcExtendedDatabase is automatically opened in the current work area after it is created.

Examples

■  This example creates a new structure extended file, places the
   definition of one field into it, and then CREATEs a new database file
   FROM the extended structure:

   CREATE TempStru
   APPEND BLANK
   REPLACE Field_name WITH "Name",;
      Field_type WITH "C",;
      Field_len WITH 25,;
      Field_dec WITH 0
   CLOSE
   CREATE NewFile FROM TempStru

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CREATE FROMHarbour implementation⌃ | ☰

Create a new .dbf file from a structure extended file

Syntax

CREATE <xcDatabase> FROM <xcExtendedDatabase> [NEW]
   [ALIAS <xcAlias>] [VIA <cDriver>]

Arguments

xcDatabase is the name of the new database file to create from the structure extended file.

xcExtendedDatabase is the name of a structure extended file to use as the structure definition for the new database file.

Both of these arguments can be specified either as literal database file names or as character expressions enclosed in parentheses. If an extension is not specified, the default is .dbf.

NEW opens xcDatabase in the next available work area making it the current work area. If this clause is not specified, xcDatabase is opened in the current work area.

ALIAS xcAlias is the name to associate with the work area when xcDatabase is opened. You may specify the alias name as a literal name or as a character expression enclosed in parentheses. A valid xcAlias may be any legal identifier (i.e., it must begin with an alphabetic character and may contain numeric or alphabetic characters and the underscore). Within a single application, CA-Clipper will not accept duplicate aliases. If this clause is not specified, the alias defaults to the database file name.

VIA cDriver specifies the replaceable database driver (RDD) to use to process the current work area. cDriver is the name of the RDD specified as a character expression. If you specify cDriver as a literal value, you must enclose it in quotes.

Description

CREATE FROM produces a new database file with the field definitions taken from the contents of a structure extended file. To qualify as a structure extended file, a database file must contain the following four fields:

Structure of an Extended File

    Field   Name           Type        Length    Decimals

    1       Field_name     Character   10

    2       Field_type     Character   1

    3       Field_len      Numeric     3         0

    4       Field_dec      Numeric     4         0

xcDatabase is automatically opened in the current work area after it is created.

Notes

■ Data dictionaries: For data dictionary applications, you can

have any number of other fields within the structure extended file to describe the extended field attributes. You may, for example, want to have fields to describe such field attributes as a description, key flag, label, color, picture, and a validation expression for the VALID clause. When you CREATE FROM, CA-Clipper creates the new database file from the required fields only, ignoring all other fields in the extended structure. Moreover, CA-Clipper is not sensitive to the order of the required fields.

■ Character field lengths greater than 255: There is one method

for creating a character field with a length greater than 255 digits:

— Specify the field length using both the Field_len and

Field_dec fields according to the following formulation:

FIELD->Field_len := nFieldLength % 256 FIELD->Field_dec := INT(nFieldLength / 256)

Examples

■  This example is a procedure that simulates an interactive
   CREATE utility:

   CreateDatabase("NewFile")
   RETURN

   FUNCTION CreateDatabase( cNewDbf )
      CREATE TmpExt          // Create empty structure extended
      USE TmpExt
      lMore := .T.
      DO WHILE lMore         // Input new field definitions
         APPEND BLANK
         CLEAR
         @ 5, 0 SAY "Name.....: " GET Field_name
         @ 6, 0 SAY "Type.....: " GET Field_type
         @ 7, 0 SAY "Length...: " GET Field_len
         @ 8, 0 SAY "Decimals.: " GET Field_dec
         READ
         lMore := (!Empty(Field_name))
      ENDDO

      // Remove all blank records
      DELETE ALL FOR Empty(Field_name)
      PACK
      CLOSE

      // Create new database file
      CREATE (cNewDbf) FROM TmpExt
      ERASE TmpExt.dbf
      RETURN NIL

■  This example creates a new definition in a structure extended
   file for a character field with a length of 4000 characters:

   APPEND BLANK
   REPLACE Field_name WITH "Notes",;
      Field_type WITH "C",;
      Field_len  WITH 4000 % 256,;
      Field_dec  WITH INT(4000 / 256)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CToD()Harbour implementation


⌃ | ☰

Convert a date string to a date value

Syntax

Arguments

cDate is a character string consisting of numbers representing the month, day, and year separated by any character other than a number. The month, day, and year digits must be specified in accordance with the SET DATE format. If the century digits are not specified, the century is determined by the rules of SET EPOCH.

Returns

CToD() returns a date value. If cDate is not a valid date, CToD() returns an empty date.

Description

CToD() is a character conversion function that converts a character string to a date. To initialize an empty date for date entry, specify cDate as a null string («»), Space(8), or » / / «.

CToD() is used whenever you need a literal date value. Some examples are:

■ Initializing a variable to a date value

■ Specifying a literal date string as an argument of a RANGE

clause of @...GET

■ Specifying a literal date string in order to perform date

arithmetic

■ Comparing the result of a date expression to a literal date

string

REPLACEing a date field with a literal date string

CToD() is the inverse of DToC() which converts a date value to a character string in the format specified by SET DATE and SET CENTURY. DToS() also converts a date value to a character string in the form yyyymmdd.

Examples

■  This example uses CToD() to initialize two date variables,
   using one as a GET and the other for RANGE validation:

   SET CENTURY ON
   dBegin := CToD("01-26-1876")
   dCurrent := CToD("")
   @ 10, 10 SAY "Enter date:" GET dCurrent ;
         RANGE dBegin, Date()
   READ

■  This example uses CToD() to create a date value within a FOR
   condition:

   USE Inventory NEW
   REPLACE ALL Inventory->Price WITH ;
      Inventory->Price * 1.1 FOR ;
      Inventory->InvDate < CToD("10/10/90")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CurDir()Harbour implementation


⌃ | ☰

Return the current DOS directory

Syntax

CurDir([<cDrivespec>]) → cDirectory

Arguments

cDrivespec specifies the letter of the disk drive to query. If not specified, the default is the current DOS drive.

Returns

CurDir() returns the current DOS directory of the drive specified by cDrivespec as a character string without either leading or trailing backslash () characters.

If an error occurs, or the current directory of the specified drive is the root directory, CurDir() returns a null string («»).

Description

CurDir() is an environment function that gives you the name of the current DOS directory, ignoring the SET DEFAULT and SET PATH settings.

Examples

■  These examples illustrate various CurDir() results:

   ? CurDir("E:")     // Result: null string--root directory
   ? CurDir("C")      // Result: CLIP53SOURCE
   ? CurDir("C:")     // Result: CLIP53SOURCE
   ? CurDir()         // Result: null string--root directory
   ? CurDir("A")      // Result: null string--drive not ready

■  This example changes the current DOS directory to a new value
   if it does not match a specified directory:

   IF CurDir("C:") != "CLIP53SOURCE"
      RUN CD CLIP53SOURCE
   ENDIF

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM

See also

dbAppend()Harbour implementation


⌃ | ☰

Append a new record to the database open in the current work area

Syntax

dbAppend([<lReleaseRecLocks>]) → NIL

Arguments

lReleaseRecLocks is a logical data type that if true (.T.), clears all pending record locks, then appends the next record. If lReleaseRecLocks is false (.F.), all pending record locks are maintained and the new record is added to the end of the Lock List. The default value of lReleaseRecLocks is true (.T.).

Returns

dbAppend() always returns NIL.

Description

dbAppend() is a database function that lets you add records to the current database. The enhancement to this function lets you maintain multiple record locks during an append.

dbAppend() without a parameter as in earlier versions of CA-Clipper, clears all pending record locks prior to an append. This is the same as dbAppend(.T.).

Examples

■  This example appends a blank record to the database, Sales,
   without releasing the record locks in the current Lock List, and then
   checks for a network error:

   USE Sales NEW
   SET INDEX TO Sales
   dbAppend(.F.)
   IF NetErr()
      ? "A network error has occurred!"
   ENDIF

Platforms

Available on MS-DOS

See also

dbClearFilter()Harbour implementation


⌃ | ☰

Clear a filter condition

Syntax

Returns

dbClearFilter() always returns NIL.

Description

dbClearFilter() clears the logical filter condition, if any, for the current work area.

dbClearFilter() performs the same function as the standard SET FILTER command with no expression specified. For more information, refer to the SET FILTER command.

Notes

■ Logical records: dbClearFilter() affects the logical

visibility of records in the current work area. For more information, refer to dbSetFilter() and the SET FILTER command.

Examples

■  The following example sets a filter, lists data as filtered,
   and then clears the filter:

   USE Employee NEW
   dbSetFilter( {|| Age < 40}, "Age < 40" )
   LIST Employee->Name
   dbClearFilter()

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbClearIndex()


⌃ | ☰

Close all indexes for the current work area

Syntax

Returns

dbClearIndex() always returns NIL.

Description

dbClearIndex() closes any active indexes for the current work area. Any pending index updates are written and the index files are closed.

dbClearIndex() performs the same function as the standard SET INDEX command with no indexes specified. For more information, refer to the SET INDEX command.

Examples

■  The following example clears index files if any are set:

   cFirst := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "FIRSTNAM" )
   dbSetIndex( "LASTNAME" )
   //
   IF IndexOrd() > 0               // is there an index?
      dbClearIndex()               // clear index files
   ELSE
      COPY TO FILE TEMP SDF      // copy to SDF in natural
   ENDIF                           // order

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbClearRelation()Harbour implementation


⌃ | ☰

Clear active relations

Syntax

Returns

dbClearRelation() always returns NIL.

Description

dbClearRelation() clears any active relations for the current work area.

dbClearRelation() performs the same function as the standard SET RELATION TO command with no clauses specified. For more information, refer to the SET RELATION command.

Examples

■  The following example sets a relation, lists data, and then
   clears the relation:

   USE Employee NEW
   USE Department NEW INDEX Dept
   //
   SELECT Employee
   dbSetRelation("Department", ;
      {|| Employee->Dept}, "Employee->Dept")
   LIST Employee->Name, Department->Name
   dbClearRelation()

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbCloseAll()Harbour implementation


⌃ | ☰

Close all occupied work areas

Syntax

Returns

dbCloseAll() always returns NIL.

Description

dbCloseAll() releases all occupied work areas from use. It is equivalent to calling dbCloseArea() on every occupied work area. dbCloseAll() has the same effect as the standard CLOSE DATABASES command. For more information, refer to the USE and CLOSE commands.

Examples

■  The following example closes all work areas:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //

   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() )
         IF RLock()
            Sales->( dbRecall() )
            ? "Record deleted: ", Sales( Deleted() )
         ENDIF
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
   dbCloseAll()                  // close all work areas

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbCloseArea()Harbour implementation


⌃ | ☰

Close a work area

Syntax

Returns

dbCloseArea() always returns NIL.

Description

dbCloseArea() releases the current work area from use. Pending updates are written, pending locks are released, and any resources associated with the work area are closed or released. dbCloseArea() is equivalent to the standard CLOSE command or the USE command with no clauses. For more information, refer to the USE and CLOSE commands.

Examples

■  The following example closes a work area via an alias
   reference:

   cLast := "Winston"
   //
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //
   IF ( Sales->(dbSeek(cLast)) )

      IF Sales->( Deleted() ) .AND. Sales->( RLock() )
         Sales->( dbRecall() )
         ? "Record deleted: ", Sales( Deleted() )
      ENDIF
   ELSE
      ? "Not found"
      Colls->( dbCloseArea() )
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbCommit()Harbour implementation


⌃ | ☰

Flush pending updates

Syntax

Returns

dbCommit() always returns NIL.

Description

dbCommit() causes all updates to the current work area to be written to disk. All updated database and index buffers are written to DOS and a DOS COMMIT request is issued for the database (.dbf) file and any index files associated with the work area.

dbCommit() performs the same function as the standard COMMIT command except that it operates only on the current work area. For more information, refer to the COMMIT command.

Notes

■ Network environment: dbCommit() makes database updates visible

to other processes. To insure data integrity, issue dbCommit() before an UNLOCK operation. For more information, refer to the «Network Programming» chapter in the Programming and Utilities Guide.

dbCommit() uses DOS interrupt 21h function 68h to perform the

solid-disk write. It is up to the network operating system to properly implement this request. Check with the network vendor to see if this is supported.

Examples

■  In this example, COMMIT is used to force a write to disk after
   a series of memory variables are assigned to field variables:

   USE Sales EXCLUSIVE NEW
   MEMVAR->Name := Sales->Name

   MEMVAR->Amount := Sales->Amount
   //
   @ 10, 10 GET MEMVAR->Name
   @ 11, 10 GET MEMVAR->Amount
   READ
   //
   IF Updated()
      APPEND BLANK
      REPLACE Sales->Name WITH MEMVAR->Name
      REPLACE Sales->Amount WITH MEMVAR->Amount
      Sales->( dbCommit() )
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbCommitAll()Harbour implementation


⌃ | ☰

Flush pending updates in all work areas

Syntax

Returns

dbCommitAll() always returns NIL.

Description

dbCommitAll() causes all pending updates to all work areas to be written to disk. It is equivalent to calling dbCommit() for every occupied work area.

For more information, refer to dbCommit() and the COMMIT command.

Notes

dbCommitAll() uses DOS interrupt 21h function 68h to perform

the solid-disk write. It is up to the network operating system to properly implement this request. Check with the network vendor to see if this is supported.

Examples

■  The following example writes all pending updates to disk:

   cLast := "Winston"
   //
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //

   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )

   dbSelectArea( "Sales" )      // select "Sales" work area

   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() ) .AND. Sales( RLock() )
         Sales->( dbRecall() )
         ? "Deleted record has been recalled."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF
   //
   // processing done, write updates to disk and close
   dbCommitAll()
   dbCloseAll()
   QUIT

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbCreate()Harbour implementation


⌃ | ☰

Create a database file from a database structure array

Syntax

dbCreate(<cDatabase>, <aStruct>
   [<cDriver>]) → NIL

Arguments

cDatabase is the name of the new database file, with an optional drive and directory, specified as a character string. If specified without an extension, .dbf is assumed.

aStruct is an array that contains the structure of cDatabase as a series of subarrays, one per field. Each subarray contains the definition of each field’s attributes and has the following structure:

Field Definition Subarray

    Position     Metasymbol     Dbstruct.ch

    1            cName          DBS_NAME

    2            cType          DBS_TYPE

    3            nLength        DBS_LEN

    4            nDecimals      DBS_DEC

cDriver specifies the replaceable database driver (RDD) to use to process the current work area. cDriver is the name of the RDD specified as a character expression. If you specify cDriver as a literal value, you must enclose it in quotes.

Returns

dbCreate() always returns NIL.

Description

dbCreate() is a database function that creates a database file from an array containing the structure of the file. You may create the array programmatically or by using dbStruct(). dbCreate() is similar to the CREATE FROM command which creates a new database file structure from a structure extended file. Use CREATE or COPY STRUCTURE EXTENDED commands to create a structure extended file.

Before using dbCreate(), you must first create the aStruct array and fill it with the field definition arrays according to the structure in Field Definition Subarray table (above). There are some specific rules for creating a field definition array, including:

■ Specify all field attributes with a value of the proper data

type for the attribute. The decimals attribute must be specified— even for non-numeric fields. If the field does not have a decimals attribute, specify zero.

■ Specify the type attribute using the first letter of the data

type as a minimum. Use longer and more descriptive terms for readability. For example, both «C» and «Character» can be specified as the type attribute for character fields.

■ In CA-Clipper, character fields contain up to 64,000

characters. Unlike the CREATE FROM command, dbCreate() does not use the decimals attribute to specify the high-order part of the field length. Specify the field length directly, regardless of its magnitude.

To make references to the various elements of the field definition subarray more readable, the header file called dbstruct.ch is supplied. It contains the #defines to assign a name to the array position for each field attribute. It is located in CLIP53INCLUDE.

Notes

■ Duplicate field names: dbCreate() does not check for duplicate

field names. Therefore, be careful not to use the same field name twice.

EG_ARG error: dbCreate() generates an EG_ARG error if the

filename is NIL.

Examples

■  This example creates an empty array and then adds field
   definition subarrays using the AAdd() function before creating
   People.dbf.  You might use this technique to add field definitions to
   your structure array dynamically:

   aDbf := {}
   AAdd(aDbf, { "Name", "C", 25, 0 })
   AAdd(aDbf, { "Address", "C", 1024, 0 })
   AAdd(aDbf, { "Phone", "N", 13, 0 })
   //
   dbCreate("People", aDbf)

■  This example performs the same types of actions but declares
   the structure array as a two-dimensional array, and then uses
   subscript addressing to specify the field definitions.  It will be
   created using the DBFMDX RDD:

   #include "Dbstruct.ch"
   //
   LOCAL aDbf[1][4]
   aDbf[1][ DBS_NAME ] := "Name"
   aDbf[1][ DBS_TYPE ] := "Character"
   aDbf[1][ DBS_LEN ]  := 25
   aDbf[1][ DBS_DEC ]  := 0
   //
   dbCreate("Name", aDbf, "DBFMDX")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is dbstruct.ch.

See also

dbCreateIndex()Harbour implementation


⌃ | ☰

Create an index file

Syntax

dbCreateIndex(<cIndexName>, <cKeyExpr>,
   [<bKeyExpr>], [<lUnique>]) → NIL

Arguments

cIndexName is a character value that specifies the file name of the index file to be created.

cKeyExpr is a character value that expresses the index key expression in textual form.

bKeyExpr is a code block that expresses the index key expression in executable form.

lUnique is an optional logical value that specifies whether a unique index is to be created. If lUnique is omitted, the current global _SET_UNIQUE setting is used.

Returns

dbCreateIndex() always returns NIL.

Description

dbCreateIndex() creates an index for the database (.dbf) file associated with the current work area. If the work area has active indexes, they are closed. After the new index is created, it becomes the controlling index for the work area and is positioned to the first logical record.

dbCreateIndex() performs the same function as the standard INDEX command. For more information, refer to the INDEX command.

Notes

■ Side effects: dbCreateIndex() is guaranteed to create an index

that, when made active, will impose the specified logical order on the database. The key expression is not necessarily evaluated at any particular time, by any particular means, or on any particular record or series of records. If the key expression relies on information external to the database file or work area, the effect is unpredictable. If the key expression changes the state of the work area (e.g., by moving to a different record or changing the contents of a record), the effect is unpredictable.

■ Evaluation context: When the key expression is evaluated, the

associated work area is automatically selected as the current work area before the evaluation; the previously selected work area is automatically restored afterward.

■ Network environment: dbCreateIndex() creates the new index for

the exclusive use of the current process.

■ Illegal expression: If cKeyExpr evaluates to an illegal

expression, the code block will always evaluate to end-of-file (EOF).

Examples

■  This example creates an index file, Name, indexed on the Name
   field:

   USE Employees NEW
   dbCreateIndex( "Name", "Name", { || Name })

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbDelete()Harbour implementation


⌃ | ☰

Mark a record for deletion

Syntax

Returns

dbDelete() always returns NIL.

Description

dbDelete() marks the current record as deleted. Records marked for deletion can be filtered using SET DELETED or removed from the file using the PACK command.

dbDelete() performs the same function as the standard DELETE command with a scope of the current record. For more information, refer to the DELETE command.

Notes

■ Logical records: If the global _SET_DELETED status is true

(.T.), deleted records are not logically visible. That is, database operations which operate on logical records will not consider records marked for deletion. Note, however, that if _SET_DELETED is true (.T.) when the current record is marked for deletion, the record remains visible until it is no longer the current record.

■ Network environment: For a shared database on a network,

dbDelete() requires the current record to be locked. For more information, refer to the «Network Programming» chapter of the Programming and Utilities Guide.

Examples

■  The following example deletes a record after a successful
   record lock:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( RLock() )
         Sales->( dbDelete() )
         ? "Record deleted: ", Sales->( Deleted() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbEdit()Harbour implementation


⌃ | ☰

Browse records in a table layout

Syntax

dbEdit([<nTop>], [<nLeft>],
   [<nBottom>], <nRight>],
   [<acColumns>],
   [<cUserFunction>],
   [<acColumnSayPictures> | <cColumnSayPicture>],
   [<acColumnHeaders> | <cColumnHeader>],
   [<acHeadingSeparators> | <cHeadingSeparator>],
   [<acColumnSeparators> | <cColumnSeparator>],
   [<acFootingSeparators> | <cFootingSeparator>],
   [<acColumnFootings> | <cColumnFooting>]) → NIL

Arguments

nTop, nLeft, nBottom, and nRight define the upper-left and lower-right coordinates of the dbEdit() window. Row values can range from zero to MaxRow() and column positions can range from zero to MaxCol(). If not specified, the default coordinates are 0, 0, MaxRow(), and MaxCol().

acColumns is an array of character expressions containing database field names or expressions to use as column values for each row displayed. If this argument is not specified, dbEdit() displays all fields in the current work area as columns.

cUserFunction is the name of a user-defined function that executes when an unrecognizable key is pressed or there are no keys pending in the keyboard buffer. Specify the function name as a character expression without parentheses or arguments. Note that the behavior of dbEdit() is affected by the presence of this argument. Refer to the discussion below for more information.

acColumnSayPictures is a parallel array of picture clauses to format each column. Specifying cColumnSayPicture instead of an array displays all columns with the same format. Refer to Transform() or @...SAY for more information on pictures.

acColumnHeaders is a parallel array of character expressions that define the headings for each column. Specifying cColumnHeader gives the same heading for all columns. To display a multi-line heading, embed a semicolon in the heading expression where you want the string to break. If not specified, column headings are taken from the acColumns array or the field names in the current work area, if the acColumns argument is not specified.

acHeadingSeparators is a parallel array of character expressions that define the characters used to draw horizontal lines separating column headings from the field display area. Specifying cHeadingSeparator instead of an array uses the same heading separator for all columns. If this argument is not specified, the default separator is a double graphics line.

acColumnSeparators is a parallel array of character expressions that define the characters used to draw vertical lines separating the columns. Specifying cColumnSeparator instead of an array uses the same separator for all columns. If this argument is not specified, the default separator is a single graphics line.

acFootingSeparators is a parallel array of character expressions that define the characters used to draw horizontal lines separating column footings from the field display area. Specifying cFootingSeparator instead of an array uses the same footing separator for all columns. If this argument is not specified, there is no footing separator.

acColumnFootings is a parallel array of character expressions that define footings for each column. Specifying cColumnFooting instead of an array gives the same footing for all columns. To display a multi- line footing, embed a semicolon in the footing expression where you want the string to break. If this argument is not specified, there are no column footings.

Returns

dbEdit() always returns NIL.

Description

dbEdit() is a user interface and compatibility function that displays records from one or more work areas in a table form. The dbEdit() window display is a grid of cells divided into columns and rows. Columns correspond to database fields and rows correspond to database records. Each column is defined by an element of the acColumns array. The display width of each column is determined by the evaluation of the column expression in acColumns array or the column picture specified in the acColumnSayPictures array.

All cursor movement keys are handled within dbEdit(), including Page up, Page down, Home, End, the four arrow keys, and all Ctrl key combinations that produce cursor movement. The navigation keys that dbEdit() responds to when a user function argument is not specified are listed in the Active Keys table below:

dbEdit() Active Keys

    Key                 Action

    Up arrow            Up one row

    Down arrow          Down one row

    Left arrow          Column left

    Right arrow         Column right

    Ctrl+Left arrow     Pan left one column

    Ctrl+Right arrow    Pan right one column

    Home                Leftmost current screen column

    End                 Rightmost current screen column

    Ctrl+Home           Leftmost column

    Ctrl+End            Rightmost column

    PgUp                Previous screen

    PgDn                Next screen

    Ctrl+PgUp           First row of current column

    Ctrl+PgDn           Last row of current column

    Return              Terminate dbEdit()

    Esc                 Terminate dbEdit()

When the user function argument (cUserFunction) is specified, all keys indicated in the Active Keys table are active with the exception of Esc and Return. When dbEdit() calls the user function, it automatically passes two arguments:

■ The current mode passed as a numeric value

■ The index of the current column in acColumns passed as a

numeric value

The mode parameter indicates the current state of dbEdit() depending on the last key executed. The possible mode values are listed in the dbEdit() Modes table below:

dbEdit() Modes

    Status  Dbedit.ch      Description

    0       DE_IDLE        Idle, any cursor movement keystrokes have been

                           handled and no keystrokes are pending

    1       DE_HITTOP      Attempt to cursor past top of file

    2       DE_HITBOTTOM   Attempt to cursor past bottom of file

    3       DE_EMPTY       No records in work area

    4       DE_EXCEPT      Key exception

The index parameter points to the position of the current column definition in the acColumns array. If acColumns is not specified, the index parameter points to the position of the field in the current database structure. Access the field name using Field().

A user-defined function must return a value that indicates to dbEdit() the action to perform. The User Function Return Values table below lists the possible return values and the corresponding actions:

dbEdit() User Function Return Values

    Value   Dbedit.ch      Description

    0       DE_ABORT       Abort dbEdit()

    1       DE_CONT        Continue dbEdit()

    2       DE_REFRESH     Force reread/repaint and continue; after repaint,

                           process keys and go to idle

A number of instances affect calls to the user function:

■ A key exception occurs. This happens when dbEdit() fetches a

keystroke that it does not recognize from the keyboard. Any pending keys remain in the keyboard buffer until fetched within the user function or until dbEdit() continues.

dbEdit() enters the idle mode (i.e., all pending keys have

been processed). This happens when the keyboard is empty or after a screen refresh. In this instance, there is one call to the user function and then dbEdit() waits for a key.

■ Beginning or end of file is encountered. This is the same as

idle. All executable keys are performed, and there is one call to the user function with the appropriate status message.

Note that when dbEdit() is first executed, all keys pending in the keyboard buffer are executed and then dbEdit() enters the idle mode with a user function call. If no keys are pending, the idle mode is immediate.

The user function should handle all modes and status messages received from dbEdit().

A user-defined function must ensure that the dbEdit() status is equivalent to DE_EXCEPT (4); otherwise, the value of LastKey() is meaningless and a Return value of DE_REFRESH (2) will place the application into an endless loop. For example:

FUNCTION DBEditFunc ( nMode, nColumnPos )

LOCAL RetVal := DE_CONT

IF ( nMode == DE_EXCEPT )

IF ( LastKey() == K_F5 )

RetVal := DE_REFRESH

ENDIF

ENDIF RETURN( RetVal )

dbEdit() is fully re-entrant, which means you can make nested calls to it. Using this feature, you can have multiple browse windows on the screen at the same time.

dbEdit() is a compatibility function and, therefore, no longer recommended as a programmable browse facility. As such, it is superseded by the TBrowse object class. For more information, refer to TBrowse class in this chapter.

Examples

■  This example demonstrates a generic call to dbEdit():

   USE Names NEW
   dbEdit()

■  This example demonstrates calling dbEdit() with a user
   function:

   #include "dbedit.ch"
   #include "inkey.ch"

   // Array must be visible to other user-defined programs in
   // program

   STATIC acColumns := {}

   PROCEDURE Main()

      USE Names NEW
      INDEX ON Names->Lastname + Names->FirstName TO Names

      CLS

      acColumns := { "LastName", "FirstName" }

      dbEdit( 5, 5, 20, 70, acColumns, "UserFunc" )

   RETURN


   FUNCTION UserFunc( nMode, nCol )
      LOCAL nKey := LastKey()
      LOCAL nRetVal := DE_CONT         // Default return value

      DO CASE
      CASE nMode == DE_IDLE
         nRetVal := IdleFunc()
      CASE nMode == DE_HITTOP
         Tone( 100, 3 )
      CASE nMode == DE_HITBOTTOM
         Tone( 100, 3 )
         nRetVal := AppendFunc( nKey )
      CASE nMode == DE_EMPTY
         nRetVal := EmptyFunc()
      CASE nMode == DE_EXCEPT
         nRetVal := ExceptFunc( nKey, nCol )
      OTHERWISE
         Tone( 100, 3 )
      ENDCASE

   RETURN nRetVal

   FUNCTION AppendFunc( nKey )
      LOCAL nRetVal := DE_CONT         // Default return value

      IF nKey == K_DOWN                  // If DOWN ARROW
         APPEND BLANK                  // Append blank record
   // Note: The appended record will appear at the top of the
   //       dbEdit() screen when the database file is indexed.

         nRetVal := DE_REFRESH         // Refresh screen
      ENDIF


   RETURN nRetVal

   FUNCTION ExceptFunc( nKey, nCol )
      LOCAL nRetVal := DE_CONT         // Default return value

      DO CASE
      CASE nKey == K_ESC                  // If ESCAPE
         nRetVal := DE_ABORT               // Exit
      CASE nKey == K_RETURN               // If RETURN
         nRetVal := EditFunc( nCol )      // Function to edit
                                          // field

      // Toggle DELETED status
      CASE nKey == K_DEL .AND. LastRec() != 0  // DELETE pressed
         IF Deleted()
            RECALL
         ELSE
            DELETE
         ENDIF
      OTHERWISE
            Tone( 100, 1 )
      ENDCASE

   RETURN nRetVal


   FUNCTION EditFunc( nCol )
      LOCAL cIndexVal         // Value of current key expression
      LOCAL nRetVal            // Return value
      LOCAL nField            // Position of current field
      LOCAL cFieldVal         // Value of current field
      LOCAL nCursSave         // Preserve state of cursor

      // This will return an error if no index is open
      cIndexVal := &( IndexKey(0) )

      nField := FieldPos( acColumns[nCol] )

      IF nField != 0
         nCursSave := SetCursor()         // Save state of cursor
         SetCursor(1)                     // Change cursor shape
         cFieldVal := FieldGet( nField )         // Save contents
                                                // of field
         @ Row(), Col() GET cFieldVal            // GET new value
         READ
         FieldPut( nField, cFieldVal )            // REPLACE with
                                                // new value
         SetCursor( nCursSave )                  // Restore cursor
                                                // shape
      ENDIF


      IF cIndexVal != &( IndexKey(0) )         // If key expression

                                             // changed
         nRequest := DE_REFRESH               // Refresh screen
      ELSE                                    // Otherwise
         nRequest := DE_CONT                  // Continue
      ENDIF

   RETURN nRequest

   FUNCTION IdleFunc()
      // Idle routine
   RETURN DE_CONT

   FUNCTION EmptyFunc()
      // Empty Records routine
   RETURN DE_CONT

Platforms

Available on MS-DOS

File

See also

dbEval()Harbour implementation


⌃ | ☰

Evaluate a code block for each record matching a scope and condition

Syntax

dbEval(<bBlock>,
   [<bForCondition>],
   [<bWhileCondition>],
   [<nNextRecords>],
   [<nRecord>],
   [<lRest>]) → NIL

Arguments

bBlock is a code block to execute for each record processed.

bForCondition is an optional condition specified as a code block that is evaluated for each record in the scope. It provides the same functionality as the FOR clause of record processing commands.

bWhileCondition is an optional condition specified as a code block that is evaluated for each record from the current record until the condition returns false (.F.). It provides the same functionality as the WHILE clause of record processing commands.

nNextRecords is an optional number that specifies the number of records to process starting with the current record. It is the same as the NEXT clause.

nRecord is an optional record number to process. If this argument is specified, bBlock will be evaluated for the specified record. This argument is the same as the RECORD clause.

lRest is an optional logical value that determines whether the scope of dbEval() is all records, or, starting with the current record, all records to the end of file. This argument corresponds to the REST and ALL clauses of record processing commands. If true (.T.) , the scope is REST; otherwise, the scope is ALL records. If lRest is not specified the scope defaults to ALL.

Returns

dbEval() always returns NIL.

Description

dbEval() is a database function that evaluates a single block for each record within the current work area that matches a specified scope and/or condition. On each iteration, dbEval() evaluates the specified block. All records within the scope or matching the condition are processed until the end of file is reached.

By default, dbEval() 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.

dbEval() is similar to AEval() which applies a block to each element in an array. Like AEval(), dbEval() can be used as a primitive for the construction of user-defined commands that process database files. In fact, many of the standard CA-Clipper database processing commands are created using dbEval().

Refer to the Code Blocks section in the «Basic Concepts» chapter of the Programming and Utilities Guide for more information on the syntax and theory of code blocks; and refer also to the Database System section in the same chapter for information on record scoping and conditions. Also refer to the CA-Clipper standard header file, std.ch, found in CLIP53INCLUDE for examples of CA-Clipper database command definitions that use dbEval().

Examples

■  This example uses dbEval() to implement Count(), a user-
   defined function that counts the number of records in a work area
   matching a specified scope.  The scope is passed as an array to
   Count().  To make the example more interesting, there is a user-
   defined command to create the scope array, thereby allowing you to
   specify the scope in a familiar form.  Additionally, there is a set
   of manifest constants that define the attributes of the scope object.

   // Scope command definition
   #command CREATE SCOPE <aScope> [FOR <for>] ;
      [WHILE <while>] [NEXT <next>] [RECORD <rec>] ;
      [<rest:REST>] [ALL];
   =>;
      <aScope> := { <{for}>, <{while}>, <next>, ;
         <rec>, <.rest.> }
   //

   // Scope attribute constants
   #define FOR_COND      1
   #define WHILE_COND    2
   #define NEXT_SCOPE    3
   #define REC_SCOPE     4
   #define REST_SCOPE    5
   //
   // Create a scope and count records using it
   LOCAL mySet, myCount
   USE Customer NEW
   CREATE SCOPE mySet FOR Customer = "Smith" WHILE ;
             Zip > "90000"
   myCount := Count( mySet )
   RETURN

   FUNCTION Count( aScope )
      LOCAL nCount := 0
      dbEval( {|| nCount++},;
         aScope[ FOR_COND ],;
         aScope[ WHILE_COND ],;
         aScope[ NEXT_SCOPE ],;
         aScope[ REC_SCOPE ],;
         aScope[ REST_SCOPE ];
      )
      RETURN nCount

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB

See also

dbFieldInfo()Harbour implementation


⌃ | ☰

Return and optionally change information about a field

Syntax

dbFieldInfo(<nInfoType>,
   <nFieldPos>,
   [<expNewSetting>]) → uCurrentSetting

Arguments

nInfoType determines the type of information as specified by the constants below. Note, however, that not all constants are supported for all RDDs, nor are all constants supported by all field types. These constants are defined in the dbstruct.ch header file, which must be included (#include) in your application.

Field Information Type Constants

    Constant            Description

    DBS_BLOB_LEN        Returns the storage length of the data in a BLOB

                        (memo) file.

    DBS_BLOB_OFFSET     Returns the file offset of the data in a BLOB (memo)

                        file.

    DBS_BLOB_POINTER    Returns a numeric pointer to the data in a blob

                        file. This pointer can be used with BLOBDirectGet(),

                        BLOBDirectImport(), etc.

    DBS_BLOB_TYPE       Returns the data type of a BLOB (memo) field. This

                        is more efficient than using Type() or ValType()

                        since the data itself does not have to be retrieved

                        from the BLOB file in order to determine the type.

    DBS_DEC             Number of decimal places for the field.

    DBS_LEN             Length of the field.

    DBS_NAME            Name of the field.

    DBS_TYPE            Data type of the field.

nFieldPos is the position of the field in the database file structure.

expNewSetting is reserved for CA-Clipper future use. It can be omitted or specified as NIL.

Returns

dbFieldInfo() returns the current setting.

Description

dbFieldInfo() retrieves information about the state of a field. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

The field information that is available is defined by the RDD.

To support RDDs for other database models (such as dictionary-based databases) that store more information about each field or column, the CA-Clipper 5.3 RDD API has been enhanced. The dbFieldInfo() is designed to allow for additional nInfoType values that can be defined by third- party RDD developers.

Examples

■  The following example uses dbFieldInfo() to retrieve field
   information:

   #include dbstruct.ch

   QOut(dbFieldInfo(DBS_NAME, 1))         // Same as FieldName(1)

   FUNCTION DBOUTSTRUCT()
      LOCAL aStruct := {}
      LOCAL nFcount, i

      nFcount := FCount()
      FOR i := 1 TO nFcount
         AAdd(aStruct, {FieldName(i), ;
                           dbFieldInfo(DBS_TYPE, i), ;
                           dbFieldInfo(DBS_LEN, i),  ;
                           dbFieldInfo(DBS_DEC, i)})
      NEXT
      RETURN aStruct

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is dbstruct.ch.

See also

dbFileGet()Harbour implementation


⌃ | ☰

Insert the contents of a field into a file

Syntax

dbFileGet(<nFieldPos>, <cTargetFile>, <nMode>)
   → lSuccess

Arguments

nFieldPos is the position of the field in the database file structure.

cTargetFile is the name of the file where the field data will be written, including an optional drive, directory and extension. See SetDefault() and SetPath() for file searching and creation rules. No default extension is assumed.

If cTargetFile does not exist, it is created. If it exists, this function attempts to open the file in exclusive mode and if successful, the file is written to without warning or error. If access is denied because, for example, another proess is using the file, NetErr() is set to TRUE.

nMode is a constant defining the copy mode, as shown in the table below:

dbFileGet() Constants

    Constant            Description

    FILEGET_APPEND      Appends to the file.

    FILEGET_OVERWRITE   Overwrites the file.  This is the default.

Returns

dbFileGet() returns true (.T.) if successful; otherwise it returns false (.F.).

Description

dbFileGet() provides a mechanism for copying the contents of a field into a file. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

dbFileGet() is used in conjunction with dbFilePut() to transfer data back and forth between files and database fields.

Examples

■  This example exports the contents of a field that stores a
   picture to a .GIF file, so that the file can be programmatically
   displayed:

   FUNCTION ShowPix()
      LOCAL cPixFile := "picture.gif"
      LOCAL nPos

      // Customer database with a picture of each
      // customer stored in a field called "Pix"
      USE customer NEW VIA "DBFCDX"
      nPos := FieldPos("Pix")

      // Export the file's data for the current Pix field
      IF ! dbFileGet(nPos, cPixFile, FILEGET_OVERWRITE )
         Alert("Export of picture " + cPixFile +
         " failed!")

      ELSE
         // Code for displaying picture would go here
      ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header is dbinfo.ch

See also

dbFilePut()Harbour implementation


⌃ | ☰

Insert the contents of a file into a field

Syntax

dbFilePut(<nFieldPos>, <cSourceFile>)
   → lSuccess

Arguments

nFieldPos is the position of the field in the database file structure.

cSourceFile is the name of the file containing the data to insert into the specified field, including an optional drive, directory and extension. See SetDefault() and SetPath() for file searching rules. No default extension is assumed.

This function attempts to open cSourceFile in shared mode. If the file does not exist, a runtime error is raised. If the file is successfully opened, the operation proceeds. If access is denied because, for example, another process has exclusive use of the file, NetErr() is set to true (.T.).

Note: There are no restrictions on the size of cSourceFile except that you must have enough disk space to make the copy.

Returns

dbFilePut() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

dbFilePut() provides a mechanism for copying the contents of a file into a field. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

dbFilePut() is used in conjunction with dbFileGet() to transfer data back and forth between files and database fields. You can use dbFilePut() with a variety of field types, including graphics images, word processor files, and printer fonts. These two functions are excellent for creating databases of documents, graphics, sounds, etc.

Note: DBFieldInfo ( DBS_BLOB_TYPE, nFieldPos ) will return «C» (string) for any memo field created using dbFilePut().

Examples

■  This example imports information from a word processing
   document into a field, then uses BLOBGet() to extract the first 25
   characters of the field:

   FUNCTION Populate()
      USE customer NEW VIA "DBFCDX"
      DO WHILE .NOT. Eof()
         GetPix( "Pix", SubStr(LastName, 1, 4) + CustID)
         Customer->dbSkip()
      ENDDO

   FUNCTION GetPix(cPixField, cPixFile)
      LOCAL nPos
      nPos := FieldPos(cPixField)

      // Import the picture field into the indicated field
      IF ! dbFilePut(nPos, cPixFile)
         Alert("Import of picture " + cPixFile + ;
               " failed!")
      ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB

See also

dbFilter()Harbour implementation


⌃ | ☰

Return the current filter expression as a character string

Syntax

Returns

dbFilter() returns the filter condition defined in the current work area as a character string. If no FILTER has been SET, dbFilter() returns a null string («»).

Description

dbFilter() is a database function used to save and re-execute an active filter by returning the filter expression as a character string that can be later recompiled and executed using the macro operator (&). This function operates like the dbRelation() and dbRSelect() functions which save and re-execute the linking expression of a relation within a work area.

Since each work area can have an active filter, dbFilter() can return the filter expression of any work area. This is done by referring to dbFilter() within an aliased expression as demonstrated below.

Notes

■ Declared variables: A character string returned by dbFilter()

may not operate correctly when recompiled and executed using the macro operator (&) if the original filter expression contained references to local or static variables, or otherwise depended on compile-time declarations.

Examples

■  This example opens two database files, sets two filters, and
   then displays the filter expressions for both work areas:

   USE Customer INDEX Customer NEW
   SET FILTER TO Last = "Smith"
   USE Invoices INDEX Invoices NEW
   SET FILTER TO CustId = "Smi001"
   SELECT Customer
   //
   ? dbFilter()                      // Result: Last = "Smith"
   ? Invoices->(dbFilter())      // Result: Custid = "Smi001"

■  This user-defined function, CreateQry(), uses dbFilter() to
   create a memory file containing the current filter expression in the
   private variable cFilter:

   FUNCTION CreateQry( cQryName )
      PRIVATE cFilter := dbFilter()
      SAVE ALL LIKE cFilter TO (cQryName + ".qwy")
      RETURN NIL

■  You can later RESTORE a query file with this user-defined
   function, SetFilter():

   FUNCTION SetFilter()
   PARAMETER cQryName
      RESTORE FROM &cQryName..qwy ADDITIVE
      SET FILTER TO &cFilter.
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbGoBottom()Harbour implementation


⌃ | ☰

Move to the last logical record

Syntax

Returns

dbGoBottom() always returns NIL.

Description

dbGoBottom() moves to the last logical record in the current work area.

dbGoBottom() performs the same function as the standard GO BOTTOM command. For more information, refer to the GO command.

Notes

■ Logical records: dbGoBottom() operates on logical records. If

there is an active index, dbGoBottom() moves to the last record in indexed order. If a filter is set, only records which meet the filter condition are considered.

■ Controlling order: If more than one index is active in the

work area, the 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. This function will not affect the locked status of any record.

Examples

■  The following example uses dbGoBottom() to position the record
   pointer on the last logical record:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   Sales->( dbGoBottom() )
   IF ( Sales->Last == "Winston" )
      IF RLock()
         Sales->( dbDelete() )
         ? "Record deleted: ", Sales->( Deleted() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   END

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbGoto()Harbour implementation


⌃ | ☰

Position record pointer to a specific identity

Syntax

dbGoto(<xIdentity>) → NIL

Arguments

xIdentity is a unique value guaranteed by the structure of the data file to reference a specific item in a data source (database). In a Xbase data structure (.dbf) xIdentity is the record number. In other data formats, xIdentity is the unique primary key value. xIdentity could be an array offset or virtual memory handle if the data set is in memory instead of on disk.

Returns

dbGoto() always returns NIL.

Description

dbGoto() is a database function that positions the record pointer in the current work area at the specified xIdentity. In an Xbase data structure, this identity is the record number because every record, even an empty record, has a record number. In non-Xbase data structures, identity may be defined as something other than record number.

Examples

■  This example saves the current record number, searches for a
   key, and then restores the record pointer to the saved position:

   FUNCTION KeyExists( xKeyExpr )

      LOCAL nSavRecord := RecNo()      // Save the current record
                                       // pointer position
      LOCAL lFound

      SEEK xKeyExpr
      IF ( lFound := Found() )
      .
      .< statements >
      .
      ENDIF

      dbGoto( nSavRecord )               // Restore the record
                                       // pointer position
      RETURN ( lFound )

Platforms

Available on MS-DOS

See also

dbGoTop()Harbour implementation


⌃ | ☰

Move to the first logical record

Syntax

Returns

dbGoTop() always returns NIL.

Description

dbGoTop() moves to the first logical record in the current work area.

dbGoTop() performs the same function as the standard GO TOP command. For more information, refer to the GO TOP command.

Notes

■ Logical records: dbGoTop() operates on logical records. If

there is an active index, dbGoTop() moves to the first record in indexed order. If a filter is set, only records which meet the filter condition are considered.

■ Controlling order: If more than one index is active in the

work area, the 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. This function will not affect the locked status of any record.

Examples

■  This example demonstrates the typical use of dbGoTop():

   dbGoTop()
   WHILE ( !Eof() )
      ? FIELD->Name
      dbSkip()
   END

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbInfo()Harbour implementation


⌃ | ☰

Return and optionally change information about a database file opened in a work area

Syntax

dbInfo(<nInfoType>, [<expNewSetting>])
   → uCurrentSetting

Arguments

nInfoType determines the type of information, as specified by the constants below. Note, however, that not all constants are supported for all RDDs. These constants are defined in the dbinfo.ch header file, which must be included (#include) in your application.

File Information Type Constants

    Constant                 Description

    DBI_ALIAS                Alias name of the work area as a string.

    DBI_BLOB_DIRECT_LEN      Returns the storage length of a data item in a

                             BLOB file.  <expNewSetting> must specify a

                             valid BLOB pointer obtained from

                             dbFieldInfo(DBS_BLOB_POINTER, <nFieldpos>),

                             BLOBDirectPut() or BLOBDirectImport().

    DBI_BLOB_DIRECT_TYPE     Returns the data type of a data item in a BLOB

                             file. <expNewSetting> must specify a valid BLOB

                             pointer obtained from

                             DbFieldInfo (DBS_BLOB_POINTER, <nFieldpos>),

                             BLOBDirectPut(), or BLOBDirectImport().

    DBI_BLOB_INTEGRITY       Tests a BLOB file for the integrity of its

                             internal tables and returns a logical value

                             indicating the success, true (.T.) or failure,

                             false (.F.) of the integrity check.  If the

                             integrity check fails, you can run

                             dbInfo(DBI_BLOB_RECOVER) which will

                             automatically correct the BLOB file’s tables.

                             Checking a BLOB file’s integrity is a disk

                             intensive operation and should only be

                             performed when the file’s integrity is in

                             question.

    DBI_BLOB_OFFSET          Returns the file offset of a data item in a

                             BLOB file. <expNewSetting> must specify a valid

                             BLOB pointer obtained from

                             dbFieldInfo(DBS_BLOB_POINTER, <nFieldpos>),

                             BLOBDirectPut(), or BLOBDirectImport().

    DBI_BLOB_RECOVER         Recovers a damaged BLOB file by correcting its

                             internal tables. You should run this function

                             only is dbInfo(DBI_BLOB_INTEGRITY) returns

                             false (.F.). Note that this function can only

                             correct the BLOB file’s internal tables, it

                             cannot restore any data that may have become

                             corrupted.

    DBI_BOF                  Logical value indicating the work area’s

                             beginning of file status (see Bof()).

    DBI_CANPUTREC            Logical value indicating whether the work area

                             supports putting records.

    DBI_CHILDCOUNT           Number of relations set from this work area.

    DBI_DB_VERSION           String containing version information of the

                             host RDD.  If the optional <expNewSetting>

                             parameter is provided, and it is one (1), the

                             result is a more detailed version of the

                             version being returned.

    DBI_DBFILTER             Filter expression as a string (see dbFilter()).

    DBI_EOF                  Logical value indicating the work area’s end of

                             file status (see Eof()).

    DBI_FCOUNT               Number of fields (see FCount()).

    DBI_FILEHANDLE           Integer representing the DOS file handle for

                             this database file.

    DBI_FOUND                Logical value indicating the success or failure

                             of the last seek operation in the work area

                             (see Found()).

    DBI_FCOUNT               Number of fields (see FCount()).

    DBI_FULLPATH             Returns the full path name of the opened

                             database file.

    DBI_GETDELIMITER         Default delimiter.

    DBI_GETHEADERSIZE        Header size of the file (see Header()).

    DBI_GETLOCKARRAY         Array of locked records.

    DBI_GETRECSIZE           Record size of the file (see RecSize()).

    DBI_ISDBF                Logical value indicating whether the RDD

                             provides support for the .dbf file format.

    DBI_ISFLOCK              File lock status.

    DBI_LASTUPDATE           Last date on which the file was updated (see

                             LUpdate()).

    DBI_LOCKCOUNT            Number of locked records.

    DBI_LOCKOFFSET           Current locking offset as a numeric value.

    DBI_MEMOBLOCKSIZE        Block size for the memo file associated with

                             this database.

    DBI_MEMOEXT              Default extension for the memo file associated

                             with this database.

    DBI_MEMOHANDLE           Integer representing the DOS file handle for

                             the memo file associated with this database

                             file.

    DBI_RDD_VERSION          String containing version information of the

                             RDD for this database.  If the optional

                             <expNewSetting> parameter is provided, and it

                             is one (1), the result is a more detailed

                             version of the version being returned.

    DBI_SETDELIMITER         Default delimiter.

    DBI_SHARED               Shared flag value.

    DBI_TABLEEXT             Database file extension.

    DBI_VALIDBUFFER          Logical value indicating whether the current

                             buffer is valid.

Important! DBI_USER is a constant that returns the minimum value that third-party RDD developers can use for defining new nInfoType parameters. Values less than DBI_USER are reserved for Computer Associates development.

expNewSetting is reserved for RDDs that allow the file information to be changed, in addition to being retrieved. None of the RDDs supplied with CA-Clipper support this argument. It can be omitted or specified as NIL.

Returns

dbInfo() returns the current setting if expNewSetting is not specified, . If expNewSetting is specified, the previous setting is returned.

Description

dbInfo() retrieves information about a database file. By default, this function operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  The following examples return work area information:

   #include dbinfo.ch

   ? dbInfo(DBI_GETHEADERSIZE)         // Same as Header()
   ? dbInfo(DBI_LASTUPDATE)            // Same as LUpdate()
   ? dbInfo(DBI_GETRECSIZE)            // Same as RecSize()
   ? dbInfo(DBI_FILEHANDLE)            // DOS file handle for
                                       // the current database
                                       // file

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is dbinfo.ch.

dbOrderInfo()Harbour implementation


⌃ | ☰

Return and optionally change information about orders and index files

Syntax

dbOrderInfo(<nInfoType>,   [<cIndexFile>],
   [<cOrder> | <nPosition>],
   [<expNewSetting>]) → uCurrentSetting

Arguments

nInfoType determines the type of information as specified by the constants below. Note, however, that not all constants are supported for all RDDs. These constants are defined in the dbinfo.ch header file, which must be included (#include) in your application.

Order/Index Information Type Constants

    Constant                      Description

    DBOI_CONDITION                For condition of the specified order as a

                                  string.

    DBOI_CUSTOM                   Logical flag indicating whether the

                                  specified order is custom-built (for RDDs

                                  that support custom-built orders).  Note

                                  that although you can turn the custom-

                                  built flag on for a standard order by

                                  specifying true (.T.) for the <uNewSetting>

                                  argument, you cannot turn a custom-built

                                  order into a standard order.  Specifying

                                  false (.F.) for <uNewSetting> is the same

                                  as not specifying the argument at all—

                                  both return the current setting.

    DBOI_EXPRESSION               Order key expression of the specified

                                  order as a string.

    DBOI_FILEHANDLE               Handle of the specified index file as a

                                  number.

    DBOI_HPLOCKING                Logical flag indicating whether the

                                  specified index file uses the high

                                  performance index locking schema.

    DBOI_INDEXEXT (DBOI_BAGEXT)   Default index file extension as a string.

    DBOI_INDEXNAME (DBOI_BAGNAME) Name of the specified index file as a

                                  string.

    DBOI_ISCOND                   Logical flag that determines whether the

                                  specified order was defined using a FOR

                                  condition.

    DBOI_ISDESC                   Logical flag that determines if the

                                  specified order is descending.  For

                                  drivers that support dynamically setting

                                  the descending flag at runtime, specify

                                  the new value as a logical, using

                                  dbOrderInfo(DBOI_ISDESC, [<cIndexFile>],

                                  [<cOrder> | <nPosition>], <lNewSetting>).

                                  The current setting is returned before it

                                  is changed.

    DBOI_KEYADD                   Logical flag indicating whether a key has

                                  been successfully added to the specified

                                  custom-built order.

    DBOI_KEYCOUNT                 Number of keys in the specified order.

    DBOI_KEYDEC                   Number of decimals in the key of the

                                  specified order.

    DBOI_KEYDELETE                Logical flag indicating whether a key has

                                  been successfully deleted from the

                                  specified custom-built order.

    DBOI_KEYGOTO                  Logical flag indicating whether the record

                                  pointer has been successfully moved to a

                                  record specified by its logical record

                                  number in the controlling order.

    DBOI_KEYSINCLUDED             Number of keys included in the specified

                                  order so far.  This is primarily useful

                                  for conditional orders.  It can be used

                                  during the status display process (with

                                  the EVAL clause of the INDEX command).

    DBOI_KEYSIZE                  Size of the key in the specified order as

                                  a number.

    DBOI_KEYTYPE                  Data type of the key in the specified

                                  order as a string.

    DBOI_KEYVAL                   Key value of the current record from the

                                  controlling order.

    DBOI_LOCKOFFSET               Locking offset for the specified index

                                  file as a numeric value.

    DBOI_NAME                     Name of the specified order as a string.

    DBOI_NUMBER                   Numeric position of the specified order in

                                  the order list.

    DBOI_ORDERCOUNT               Number of orders in the specified index

                                  file.

    DBOI_POSITION                 Logical record number of the current

                                  record within the specified order.

    DBOI_RECNO                    Physical record number of the current

                                  record within the specified order.

    DBOI_SCOPEBOTTOM              Bottom boundary of the scope (as a number)

                                  for the specified order.

    DBOI_SCOPEBOTTOMCLEAR         Clears the bottom boundary of the scope

                                  for the specified order.

    DBOI_SCOPETOP                 Top boundary of the scope (as a number)

                                  for the specified order.

    DBOI_SCOPETOPCLEAR            Clears the top boundary of the scope for

                                  the specified order.

    DBOI_SETCODEBLOCK             Key for the specified order as a code

                                  block.

    DBOI_SKIPUNIQUE               Logical flag indicating whether the record

                                  pointer has been successfully moved to the

                                  next or previous unique key in the

                                  controlling order.

    DBOI_UNIQUE                   Logical flag indicating whether the

                                  specified order has the unique attribute

                                  set.

Important! DBOI_USER is a constant that returns the minimum value that third-party RDD developers can use for defining new nInfoType parameters. Values less than DBOI_USER are reserved for Computer Associates development.

cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.

cOrder | nPosition is the name of the order about which you want to obtain information or a number representing its position in the order list. For single-order index files, the order name is the eight-letter index file name. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. Invalid values are ignored. If no index file or order is specified, the controlling order is assumed.

expNewSetting is reserved for RDDs that allow the file information to be changed, in addition to being retrieved. None of the RDDs supplied with CA-Clipper support this argument. It can be omitted or specified as NIL.

Returns

If expNewSetting is not specified, dbOrderInfo() returns the current setting. If expNewSetting is specified, the previous setting is returned.

Description

dbOrderInfo() retrieves information about the orders and index files. By default, dbOrderInfo() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression.

Examples

■  This example uses DBOI_NAME to save the current controlling
   order.  After changing to a new controlling order, it uses the saved
   value to restore the original order:

   #include dbinfo.ch

   USE Customer INDEX Name, Serial NEW
   cOrder := dbOrderInfo(DBOI_NAME)               // Name
   Customer->dbSetOrder("Serial")
   ? dbOrderInfo(DBOI_NAME)                     // Serial
   Customer->dbSetOrder(cOrder)
   ? dbOrderInfo(DBOI_NAME)                     // Name

■  This example uses aliased expressions to return the default
   index file extension (using DBOI_INDEXEXT) in two different work
   areas:

   #include dbinfo.ch

   USE Sales INDEX All_Sales VIA "DBFCDX" NEW
   USE Customer INDEX Name, Serial VIA "DBFNTX" NEW
   ? Sales->dbOrderInfo(DBOI_INDEXEXT)                  // .CDX
   ? Customer->dbOrderInfo(DBOI_INDEXEXT)               // .NTX

■  In this example, dbOrderInfo(DBOI_INDEXEXT) checks for the
   existence of the Customer index file independent of the RDD linked
   into the current work area:

   #include dbinfo.ch

   USE Customer NEW
   IF !FILE( "Customer" + dbOrderInfo(DBOI_INDEXEXT))
            Customer->dbCreateIndex("Customer", "CustName",;
                                          {||Customer->CustName} )
   ENDIF

■  This example accesses the key expression of several orders
   from the same index file:

   #include dbinfo.ch

   USE Customer INDEX All_Cust VIA "DBFMDX" NEW
   Customer->dbSetOrder("Serial")
   ? dbOrderInfo(DBOI_EXPRESSION,, "Name")
   // Result: key expression for name order
   ? dbOrderInfo(DBOI_EXPRESSION,, "Serial")
   // Result: key expression for serial order

■  This example uses dbOrderInfo() as part of a TOTAL ON key
   expression.  Since dbOrderInfo() returns the expression as a string,
   it is specified using a macro expression to force evaluation of the
   key expression:

   #include dbinfo.ch

   USE Sales INDEX Salesman NEW
   TOTAL ON &(dbOrderInfo(DBOI_EXPRESSION)) ;
      FIELDS SaleAmount TO Summary

■  In this example, All_Cust.mdx contains three orders named
   CuAcct, CuName, CuZip.  The DBOI_INDEXNAME constant is used to
   display the name of the index file using one of its orders:

   #include dbinfo.ch

   USE Customer VIA "DBFNTX" NEW
   Customer->dbSetIndex("All_Cust")
   ? dbOrderInfo(DBOI_INDEXNAME,, "CuName")
   // Returns: All_Cust

■  The following example searches for CuName in the order list:

   #include dbinfo.ch

   USE Customer VIA "DBFNTX" NEW
   Customer->dbSetIndex("CuAcct")
   Customer->dbSetIndex("CuName")
   Customer->dbSetIndex("CuZip")
   ? dbOrderInfo(DBOI_NUMBER,, "CuName")            // 2

■  This example retrieves the FOR condition from an order:

   #include dbinfo.ch

   USE Customer NEW
   INDEX ON Customer->Acct TO Customer ;
      FOR Customer->Acct > "AZZZZZ"
   ? dbOrderInfo(DBOI_CONDITION,, "Customer")
   // Returns: Customer->Acct > "AZZZZZ"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is dbinfo.ch.

See also

dbRecall()Harbour implementation


⌃ | ☰

Reinstate a record marked for deletion

Syntax

Returns

dbRecall() always returns NIL.

Description

dbRecall() causes the current record to be reinstated if it is marked for deletion.

dbRecall() performs the same function as the RECALL command. For more information, refer to the DELETE and RECALL commands.

Notes

■ Logical records: Reinstating a deleted record affects the

record’s logical visibility if the global _SET_DELETED status is true (.T.). For more information, refer to the dbDelete() function and the DELETE and RECALL commands.

■ Network environment: For a shared database on a network,

dbRecall() requires the current record to be locked. For more information, refer to the «Network Programming» chapter in the Programming and Utilities Guide.

Examples

■  The following example recalls a record if it is deleted and
   attempts to lock the record if successful:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() )
         IF Sales( RLock() )
            Sales( dbRecall() )
            ? "Record recalled"
         ELSE
            "Unable to lock record..."
         ENDIF
      ENDIF
   ELSE
      ? "Not found"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbRecordInfo()Harbour implementation


⌃ | ☰

Return and optionally change information about a record

Syntax

dbRecordInfo(<nInfoType>,
   [<nRecord>],
   [<expNewSetting>]) → uCurrentSetting

Arguments

nInfoType determines the type of information, as specified by the constants below. Note, however, that not all constants are supported for all RDDs. These constants are defined in the dbinfo.ch header file, which must be included (#include) in your application.

Record Information Type Constants

    Constant       Description

    DBRI_DEL       Deleted flag status of the record

    DBRI_LOCK      Locked flag status of the record

    DBRI_SIZE      Length of the record

    DBRI_RECNO     Position of the record

    DBRI_UPDAT     Updated flag status of the record

Important! DBI_USER is a constant that returns the minimum value that third-party RDD developers can use for defining new nInfoType parameters. Values less than DBI_USER are reserved for Computer Associates development.

nRecord is the record to obtain information. If omitted, the current record is used.

expNewSetting is reserved for RDDs that allow the file information to be changed, in addition to being retrieved. None of the RDDs supplied with CA-Clipper support this argument. It can be omitted or specified as NIL.

Returns

If expNewSetting is not specified, dbRecordInfo() returns the current setting. If expNewSetting is specified, the previous setting is returned.

Description

dbRecordInfo() retrieves information about the state of a record (row). The type of information is specified by the nInfoType parameter. By default, this function operates on the currently selected record.

dbRecordInfo() is designed to allow for additional nInfoType values that can be defined by third-party RDD developers.

Examples

■  The following example uses dbRecordInfo() to retrieve field
   information:

   #include "Dbinfo.ch"

   dbRecordInfo(DBRI_SIZE)               // Same as RecSize()

   dbRecordInfo(DBRI_LOCK, 200)         // Is record 200 locked?

   dbRecordInfo(DBRI_DEL, 201)         // Is record 201 locked?

   dbRecordInfo(DBRI_UPDAT)            // Is the current record
                                       // updated?

   dbRecordInfo(DBRI_RECNO, 230)         // On which position is

                                       // record 230?
                                       // If no orders are active,
                                       // the position is 230;
                                       // otherwise, the relative
                                       // position within the order
                                       // will be returned.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is dbinfo.ch.

See also

dbReindex()


⌃ | ☰

Recreate all active indexes for the current work area

Syntax

Returns

dbReindex() always returns NIL.

Description

dbReindex() rebuilds all active indexes associated with the current work area. After the indexes are recreated, the work area is moved to the first logical record in the controlling order.

dbReindex() performs the same function as the standard REINDEX command. For more information, refer to the REINDEX command.

Examples

■  The following example reindexes the work area:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF RLock()
         DELETE FOR Sales->LastName == "Winston"
         Sales->( dbReindex() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbRelation()Harbour implementation


⌃ | ☰

Return the linking expression of a specified relation

Syntax

dbRelation(<nRelation>) → cLinkExp

Arguments

nRelation is the position of the desired relation in the list of current work area relations. The relations are numbered according to the order in which they were defined with SET RELATION.

Returns

dbRelation() returns a character string containing the linking expression of the relation specified by nRelation. If there is no RELATION SET for nRelation, dbRelation() returns a null string («»).

Description

dbRelation() is a database function used with dbRSelect() to determine the linking expression and work area of an existing relation created with the SET RELATION command.

dbRelation() returns the linking expression defined by the TO clause. dbRSelect() returns the work area linked as defined by the INTO clause.

By default, dbRelation() 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 (see example below).

Notes

■ Declared variables: A character string returned by

dbRelation() may not operate correctly when recompiled and executed using the macro operator (&) if the original expression contained references to local or static variables, or otherwise depends on compile-time declarations.

Examples

■  This example opens three database files, sets two child
   relations from the parent work area, and then displays the linking
   expression to the second child work area:

   USE Invoices INDEX Invoices NEW
   USE BackOrder INDEX BackOrder NEW
   USE Customer INDEX Customer NEW
   SET RELATION TO CustNum INTO Invoices, OrderNum ;
         INTO BackOrder
   //
   ? dbRelation(2)                  // Result: OrderNum

■  Later you can query the same linking expression from an
   unselected work area by using an aliased expression like this:

   USE Archive NEW
   ? Customer->(dbRelation(2))   // Result: OrderNum

■  This example is a user-defined function, Relation(), that
   returns the results of both dbRelation() and dbRSelect() as an array:

   FUNCTION Relation( nRelation )
      RETURN { dbRelation(nRelation), ;
            Alias(dbRSelect(nRelation)) }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbRLock()Harbour implementation


⌃ | ☰

Lock the record at the current or specified identity

Syntax

dbRLock([<xIdentity>]) → lSuccess

Arguments

xIdentity is a unique value guaranteed by the structure of the data file to reference a specific item in a data source (database). In a .dbf xIdentity is the record number. In other data formats, xIdentity is the unique primary key value.

Returns

dbRLock() returns lSuccess, a logical data type that is true (.T.) if successful, false (.F.) if unsuccessful.

Description

dbRLock() is a database function that locks the record identified by the value xIdentity. In Xbase, xIdentity is the record number.

If you do not specify xIdentity, all record locks are released and the current record is locked. If you specify xIdentity, dbRLock() attempts to lock it and, if successful, adds it to the locked record list.

Examples

■  This example shows two different methods for locking multiple
   records:

FUNCTION dbRLockRange( nLo, nHi )

         LOCAL nRec
         FOR nRec := nLo TO nHi

            IF ! dbRLock( nRec )
               dbRUnlock()      // Failed - unlock everything
            ENDIF
         NEXT
      RETURN dbRLockList()      // Return array of actual locks

   FUNCTION dbRLockArray( aList )

         LOCAL nElement, nLen, lRet
         lRet := .T.
         nLen := Len( aList )
         FOR nElement := 1 TO nLen
            IF ! dbRLock( aList[ nElement ] )
               dbRUnlock()      // Failed - unlock everything
               lRet := .F.
            ENDIF
         NEXT
      RETURN dbRLockList()

Platforms

Available on MS-DOS

See also

dbRLockList()Harbour implementation


⌃ | ☰

Return an array of the current lock list

Syntax

dbRLockList() → aRecordLocks

Returns

dbRLockList() returns an array of the locked records in the current or aliased work area.

Description

dbRLockList() is a database function that returns a one-dimensional array that contains the identities of record locks active in the selected work area.

Examples

ROCEDURE PrintCurLocks()

OCAL aList
OCAL nSize
OCAL nCount

List := dbRLockList()
Size := Len( aList )

 "Currently locked records: "
OR nCount := 1 TO nSize
  ?? aList[ nCount ]
  ?? Space( 1 )

   NEXT
   ?

   RETURN

Platforms

Available on MS-DOS

See also

dbRSelect()Harbour implementation


⌃ | ☰

Return the target work area number of a relation

Syntax

dbRSelect(<nRelation>) → nWorkArea

Arguments

nRelation is the position of the desired relation in the list of current work area relations. The relations are numbered according to the order in which they were defined with SET RELATION.

Returns

dbRSelect() returns the work area number of the relation specified by nRelation as an integer numeric value. If there is no RELATION SET for nRelation, dbRSelect() returns zero.

Description

dbRSelect() is a database function used in combination with dbRelation() to determine the work area and linking expression of an existing relation created with the SET RELATION command. dbRSelect() returns the work area defined by the INTO clause. dbRelation() returns the linking expression defined by the TO clause. To determine the alias of the relation instead of the work area number, use the expression Alias(dbRSelect(nRelation)).

By default, dbRSelect() 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 (see example below).

Examples

■  This example opens three database files, sets two child
   relations from the parent work area, and then displays the linking
   expression to the second child work area, as well as the target work
   area of the relation:

   USE Invoices INDEX Invoices NEW
   USE BackOrder INDEX BackOrder NEW
   USE Customer INDEX Customer NEW
   SET RELATION TO CustNum INTO Customer, ;
         OrderNum INTO BackOrder
   //
   ? dbRelation(2), dbRSelect(2)         // Result: OrderNum 3

   ? Alias(dbRSelect(2))               // Result: BACKORDER

■  Later, you can query the same information from an unselected
   work area by using an aliased expression:

   USE Archive NEW
   ? Customer->(dbRelation(2))      // Result: OrderNum
   ? Customer->(dbRSelect(2))         // Result: 3

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbRUnlock()Harbour implementation


⌃ | ☰

Release all or specified record locks

Syntax

dbRUnlock([<xIdentity>]) → NIL

Arguments

xIdentity is a unique value guaranteed by the structure of the data file to reference a specific item in a data source (database). In a .dbf xIdentity is the record number. In other data formats, xIdentity is the unique primary key value.

Returns

dbRUnlock() always returns NIL.

Description

dbRUnlock() is a database function that releases the lock on xIdentity and removes it from the Lock List. If xIdentity is not specified, all record locks are released.

Examples

PROCEDURE dbRUnlockRange( nLo, nHi )

   LOCAL nCounter

   // Unlock the records in the range from nLo to nHi
   FOR nCounter := nLo TO nHi
      dbRUnlock( nCounter )
   NEXT

   RETURN

Platforms

Available on MS-DOS

See also

dbSeek()Harbour implementation


⌃ | ☰

Move to the record having the specified key value

Syntax

dbSeek(<expKey>, [<lSoftSeek>], [<lLast>]) → lFound

Arguments

expKey is a value of any type that specifies the key value associated with the desired record.

lSoftSeek is an optional logical value that specifies whether a soft seek is to be performed. This determines how the work area is positioned if the specified key value is not found (see below). If lSoftSeek is omitted, the current global _SET_SOFTSEEK setting is used.

lLast is specified as true (.T.) to seek the last occurrence of the specified key value. False (.F.), the default, seeks the first occurrence.

Note: This parameter is only supported for specific RDDs. DBFNTX is NOT one of them.

Returns

dbSeek() returns true (.T.) if the specified key value was found; otherwise, it returns false (.F.).

Description

dbSeek() moves to the first logical record whose key value is equal to expKey. If such a record is found, it becomes the current record and dbSeek() returns true (.T.); otherwise, it returns false (.F.). the positioning of the work area is as follows: for a normal (not soft) seek, the work area is positioned to LastRec() + 1 and Eof() returns true (.T.); for a soft seek, the work area is positioned to the first record whose key value is greater than the specified key value. If no such record exists, the work area is positioned to LastRec() + 1 and Eof() returns true (.T.).

For a work area with no active indexes, dbSeek() has no effect.

dbSeek() performs the same function as the standard SEEK command. For more information, refer to the SEEK command.

Notes

■ Logical records: dbSeek() operates on logical records which

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 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. This function will not affect the locked status of any record.

Examples

■  In this example, dbSeek() moves the pointer to the record in
   the database, Employee, in which the value in FIELD "cName" matches
   the entered value of cName:

   ACCEPT "Employee name: " TO cName
   IF ( Employee->(dbSeek(cName)) )
      Employee->(VIEWRECORD())
   ELSE
      ? "Not found"
   END

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbSelectArea()Harbour implementation


⌃ | ☰

Change the current work area

Syntax

dbSelectArea(<nArea> | <cAlias>) → NIL

Arguments

nArea is a numeric value between zero and 250, inclusive, that specifies the work area being selected.

cAlias is a character value that specifies the alias of a currently occupied work area being selected.

Returns

dbSelectArea() always returns NIL.

Description

dbSelectArea() causes the specified work area to become the current work area. All subsequent database operations will apply to this work area unless another work area is explicitly specified for an operation. dbSelectArea() performs the same function as the standard SELECT command. For more information, refer to the SELECT command.

Notes

■ Selecting zero: Selecting work area zero causes the lowest

numbered unoccupied work area to become the current work area.

■ Aliased expressions: The alias operator (->) can temporarily

select a work area while an expression is evaluated and automatically restore the previously selected work area afterward. For more information, refer to the alias operator (->).

Examples

■  The following example selects a work area via the alias name:

   cLast := "Winston"
   dbUseArea( .T., "DBFNTX", "Sales", "Sales", .T. )
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   dbUseArea( .T., "DBFNTX", "Colls", "Colls", .T. )
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( Deleted() ) .AND. Sales->( RLock() )
         Sales->( dbRecall() )
         ? "Deleted record has been recalled."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbSetDriver()Harbour implementation


⌃ | ☰

Return the default database driver and optionally set a new driver

Syntax

dbSetDriver([<cDriver>]) → cCurrentDriver

Arguments

cDriver is an optional character value that specifies the name of the database driver that should be used to activate and manage new work areas when no driver is explicitly specified.

Returns

dbSetDriver() returns the name of the current default driver.

Description

dbSetDriver() sets the database driver to be used when activating new work areas without specifying a driver. If the specified driver is not available to the application, the call has no effect. dbSetDriver() returns the name of the current default driver, if any.

Examples

■  This example makes the "DBFNDX" driver the default driver.  If
   the driver is unavailable, a message is issued:

   dbSetDriver("DBFNDX")
   IF ( dbSetDriver() <> "DBFNDX" )
      ? "DBFNDX driver not available"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbSetFilter()Harbour implementation


⌃ | ☰

Set a filter condition

Syntax

dbSetFilter(<bCondition>, [<cCondition>]) → NIL

Arguments

bCondition is a code block that expresses the filter condition in executable form.

cCondition stores the filter condition as a character string for later retrieval by the dbFilter() function. If you omit this optional parameter, the dbFilter() function will return an empty string for the work area.

Returns

dbSetFilter() always returns NIL.

Description

dbSetFilter() sets a logical filter condition for the current work area. When a filter is set, records which do not meet the filter condition are not logically visible. That is, database operations which act on logical records will not consider these records.

The filter expression supplied to dbSetFilter() evaluates to true (.T.) if the current record meets the filter condition; otherwise, it should evaluate to false (.F.).

The filter expression may be a code block (bCondition) or both a code block and equivalent text (cCondition). If both versions are supplied, they must express the same condition. If the text version is omitted, dbFilter() will return an empty string for the work area.

dbSetFilter() performs the same function as the standard SET FILTER command. For more information, refer to the SET FILTER command.

Notes

■ Logical records: dbSetFilter() affects the logical visibility

of records (see above).

■ Side effects: Setting a filter condition is only guaranteed to

restrict visibility of certain records as described above. The filter expression is not necessarily evaluated at any particular time, by any particular means, or on any particular record or series of records. If the filter expression relies on information external to the database file or work area, the effect is unpredictable. If the filter expression changes the state of the work area (e.g., by moving to a different record or changing the contents of a record), the effect is unpredictable.

■ Evaluation context: When the filter expression is evaluated,

the associated work area is automatically selected as the current work area before the evaluation; the previously selected work area is automatically restored afterward.

Examples

■  This example limits data access to records in which the Age
   field value is less than 40:

   USE Employee NEW
   dbSetFilter( {|| Age < 40}, "Age < 40" )
   dbGoTop()

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbSetIndex()


⌃ | ☰

Empty orders from an order bag into the order list

Syntax

dbSetIndex(<cOrderBagName>) → NIL

Arguments

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.

Returns

dbSetIndex() always returns NIL.

Description

dbSetIndex() is a database function that adds the contents of an order bag into the order list of the current work area. Any orders already associated with the work area continue to be active. If the newly opened order bag is the only order associated with the work area, it becomes the controlling order; otherwise, the controlling order remains unchanged. If the order bag contains more than one order, and there are no other orders associated with the work area, the first order in the new order bag becomes the controlling order.

Note: dbSetIndex() does not close all currently open index files.

dbSetIndex() is a compatibility command and therefore is not recommended. It is superseded by the ordListAdd() function.

Examples

USE Customer NEW
dbSetIndex( "Cust01" )         // Open the index Cust01
                              // in the current work area
dbSetIndex( "Cust02" )         // Open the index Cust02
                              // leaving Cust01 open

Platforms

Available on MS-DOS

See also

dbSetOrder()Harbour implementation


⌃ | ☰

Set the controlling order

Syntax

dbSetOrder(<nOrderNum>) → NIL

Arguments

nOrderNum is a numeric value that specifies which of the active indexes is to be the controlling index.

Returns

dbSetOrder() always returns NIL.

Description

dbSetOrder() controls which of the current work area’s active indexes is the controlling index. The controlling index is the index which determines the logical order of records in the work area.

Active indexes are numbered from 1 to the number of active indexes, based on the order in which the indexes were opened. nOrderNum specifies the number of the desired index.

dbSetOrder() performs the same function as the standard SET ORDER command. For more information, refer to the SET ORDER command.

Notes

■ Setting order to zero: Setting order to zero causes the work

area to be accessed in natural (record number) order. Only the logical order of the records is affected; any open indexes continue to be active and are properly maintained.

Examples

■  This example sets the second named index, Age, as the
   controlling index:

   USE Employee NEW
   SET INDEX TO Name, Age
   dbSetOrder(2)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbSetRelation()Harbour implementation


⌃ | ☰

Relate two work areas

Syntax

dbSetRelation(<nArea> | <cAlias>, <bExpr>, <cExpr>)
   → NIL

Arguments

nArea is a numeric value that specifies the work area number of the child work area.

cAlias is a character value that specifies the alias of the child work area.

bExpr is a code block that expresses the relational expression in executable form.

cExpr is a character value that expresses the relational expression in textual form.

Returns

dbSetRelation() always returns NIL.

Description

dbSetRelation() relates the work area specified by nArea or cAlias (the child work area) to the current work area (the parent work area). Any existing relations remain active.

Relating work areas synchronizes the child work area with the parent work area. This is achieved by automatically repositioning the child work area whenever the parent work area moves to a new record. If there is an active index in the child work area, moving the parent work area causes an automatic SEEK operation in the child work area; the seek key is based on the expression specified by bExpr and/or cExpr. If the child work area has no active index, moving the parent work area causes an automatic GOTO in the child work area; the record number for the GOTO is based on the expression specified by bExpr and/or cExpr.

The relational expression may be a code block (bExpr) or both a code block and equivalent text (cExpr). If both versions are supplied, they must be equivalent. If the text version is omitted, dbRelation() will return an empty string for the relation.

dbSetRelation() performs the same function as the standard SET RELATION command with the ADDITIVE clause. For more information, refer to the SET RELATION command.

Notes

■ Side effects: dbSetRelation() is only guaranteed to

synchronize the work areas as described above. The relational expression is not necessarily evaluated at any particular time, by any particular means, or on any particular record or series of records. If the relational expression relies on information external to the parent work area or its associated database file, the effect is unpredictable. If the expression changes the state of either work area (e.g., by moving to a different record or changing the contents of a record), the effect is unpredictable.

■ Evaluation context: When the relational expression is

evaluated, the parent work area is automatically selected as the current work area before the evaluation; the previously selected work area is automatically restored afterward.

■ Soft seeking: Seek operations that occur as part of relational

positioning are never soft seeks. If a relational movement is unsuccessful, the child work area is positioned to LastRec() + 1, its Found() status returns false (.F.), and its Eof() status returns true (.T.).

Examples

■  This example demonstrates a typical use of the dbSetRelation()
   function:

   USE Employee NEW
   USE Department NEW INDEX Dept
   SELECT Employee
   dbSetRelation("Department", {|| Employee->Dept},;
                   "Employee->Dept")
   LIST Employee->Name, Department->Name

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbSkip()Harbour implementation


⌃ | ☰

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

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbStruct()Harbour implementation


⌃ | ☰

Create an array containing the structure of a database file

Syntax

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 CLIP53INCLUDE 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])} )

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is dbstruct.ch.

See also

dbUnlock()Harbour implementation


⌃ | ☰

Release all locks for the current work area

Syntax

Returns

dbUnlock() always returns NIL.

Description

dbUnlock() releases any record or file locks obtained by the current process for the current work area. dbUnlock() is only meaningful on a shared database in a network environment.

dbUnlock() performs the same function as the standard UNLOCK command. For more information, refer to the UNLOCK command.

Notes

■ Network environment: Releasing locks may cause updates to the

database to become visible to other processes. For more information, refer to the «Network Programming» chapter in the Programming and Utilities Guide.

Examples

■  The following example illustrates a basic use of the
   dbUnlock() function:

   cLast := "Winston"
   USE Sales SHARED NEW VIA "DBFNTX"
   dbSetIndex( "LASTNAME" )
   //
   IF ( Sales->(dbSeek(cLast)) )
      IF Sales->( RLock() )
         Sales->( dbDelete() )

         ? "Record deleted: ", Sales( Deleted() )
         Sales->( dbUnlock() )
      ELSE
         ? "Unable to lock record..."
      ENDIF
   ELSE
      ? "Not found"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbUnlockAll()Harbour implementation


⌃ | ☰

Release all locks for all work areas

Syntax

Returns

dbUnlockAll() always returns NIL.

Description

dbUnlockAll() releases any record or file locks obtained by the current process for any work area. dbUnlockAll() is only meaningful on a shared database in a network environment. It is equivalent to calling dbUnlock() on every occupied work area.

dbUnlockAll() performs the same function as the UNLOCK ALL command. For more information, refer to the UNLOCK ALL command.

Examples

■  The following example marks a record for deletion if an
   RLock() attempt is successful, then clears all locks in all work
   areas:

   cLast := "Winston"
   USE Sales SHARED NEW VIA "DBFNTX"
   dbSetIndex( "SALEFNAM" )
   dbSetIndex( "SALELNAM" )
   //
   USE Colls SHARED NEW VIA "DBFNTX"
   dbSetIndex( "COLLFNAM" )
   dbSetIndex( "COLLLNAM" )
   //
   dbSelectArea( "Sales" )      // select "Sales" work area
   //
   IF ( Colls->(dbSeek(cLast)) )
      IF Colls->( Deleted() )
         ? "Record deleted: ", Colls->( Deleted() )

         IF Colls->( RLock() )
            Colls->( dbRecall() )
            ? "Record recalled..."
         ENDIF
      ENDIF
   ELSE
      ? "Not found"
      dbUnlockAll()            // remove all locks in
   ENDIF                        // all work areas

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbUseArea()Harbour implementation


⌃ | ☰

Use a database file in a work area

Syntax

dbUseArea( [<lNewArea>], [<cDriver>], <cName>, [<xcAlias>],
  [<lShared>], [<lReadonly>]) → NIL

Arguments

lNewArea is an optional logical value. A value of true (.T.) selects the lowest numbered unoccupied work area as the current work area before the use operation. If lNewArea is false (.F.) or omitted, the current work area is used; if the work area is occupied, it is closed first.

cDriver is an optional character value. If present, it specifies the name of the database driver which will service the work area. If cDriver is omitted, the current default driver is used (see note below).

cName specifies the name of the database (.dbf) file to be opened.

xcAlias is an optional character value. If present, it specifies the alias to be associated with the work area. The alias must constitute a valid CA-Clipper identifier. A valid xcAlias may be any legal identifier (i.e., it must begin with an alphabetic character and may contain numeric or alphabetic characters and the underscore). Within a single application, CA-Clipper will not accept duplicate aliases. If xcAlias is omitted, a default alias is constructed from cName.

lShared is an optional logical value. If present, it specifies whether the database (.dbf) file should be accessible to other processes on a network. A value of true (.T.) specifies that other processes should be allowed access; a value of false (.F.) specifies that the current process is to have exclusive access. If lShared is omitted, the current global _SET_EXCLUSIVE setting determines whether shared access is allowed.

lReadonly is an optional logical value that specifies whether updates to the work area are prohibited. A value of true (.T.) prohibits updates; a value of false (.F.) permits updates. A value of true (.T.) also permits read-only access to the specified database (.dbf) file. If lReadonly is omitted, the default value is false (.F.).

Returns

dbUseArea() always returns NIL.

Description

dbUseArea() associates the specified database (.dbf) file with the current work area. It performs the same function as the standard USE command. For more information, refer to the USE command.

Notes

■ Current driver: If no driver is specified in the call to

dbUseArea() the default driver is used. If more than one driver is available to the application, the default driver is the driver specified in the most recent call to dbSetDriver(). If dbSetDriver() has not been called, the DBFNTX driver is used. If the default driver is undetermined, DBFNTX will be used.

Examples

■  This example is a typical use of the dbUseArea() function:

   dbUseArea(.T., "DBFNDX", "Employees")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Date()Harbour implementation


⌃ | ☰

Return the system date as a date value

Syntax

Returns

Date() returns the system date as a date value.

Description

Date() is a date function that provides a means of initializing memory variables to the current date, comparing other date values to the current date, and performing date arithmetic relative to the current date.

The display format for dates is controlled by the SET DATE command. The default format is mm/dd/yy.

Examples

■  These examples show the Date() function used in various ways:

   ? Date()                 // Result: 09/01/90
   ? Date() + 30            // Result: 10/01/90
   ? Date() - 30            // Result: 08/02/90
   dDate := Date()
   ? CMonth(dDate)          // Result: September

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Day()Harbour implementation


⌃ | ☰

Return the day of the month as a numeric value

Syntax

Arguments

dDate is a date value to convert.

Returns

Day() returns a number in the range of zero to 31 as an integer numeric value. If the month is February, leap years are considered. If the date argument is February 29 and the year is not a leap year, Day() returns zero. If the date argument is empty, Day() returns zero.

Description

Day() is a date conversion function used to convert a date value to the day of a month. This function is used in combination with CMonth() and Year() to format dates. In addition, it is often used in various date calculations.

Examples

■  These examples show the Day() function used several ways:

   ? Date()                             // Result: 09/01/90
   ? Day(Date())                        // Result: 1
   ? Day(Date()) + 1                    // Result: 2
   ? Day(CToD("12/01/94"))              // Result: 1

■  This example uses Day() in combination with CMonth() and
   Year() to format a date value:

   ? CMonth(Date()) + Str(Day(Date())) +;
      "," + Str(Year(Date()))      // Result: June 15, 1990

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Dbf()*Harbour implementation


⌃ | ☰

Return current alias name

Syntax

Returns

Dbf() returns the alias of the current work area as a character string. If there is no active database file in the current work area, Dbf() returns a null string («»).

Description

Dbf() is a compatibility function that replicates the Dbf() function in dBASE III PLUS. CA-Clipper implements it by invoking the Alias() function without an argument.

Dbf() is a compatibility function and, therefore, no longer recommended. It is superseded entirely by the Alias() function.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/DBF.PRG

See also

Deleted()Harbour implementation


⌃ | ☰

Return the deleted status of the current record

Syntax

Returns

Deleted() returns true (.T.) if the current record is marked for deletion; otherwise, it returns false (.F.). If there is no database file in USE in the current work area, Deleted() returns false (.F.).

Description

Deleted() is a database function that determines if the current record in the active work area is marked for deletion. Since each work area with an open database file can have a current record, each work area has its own Deleted() value.

By default, Deleted() 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 (see example below).

In applications, Deleted() is generally used to query the deleted status as a part of record processing conditions, or to display the deleted status as a part of screens and reports.

Examples

■  This example uses Deleted() in the current and in an
   unselected work area:

   USE Customer NEW
   USE Sales NEW
   ? Deleted()                     // Result: .F.
   DELETE
   ? Deleted()                     // Result: .T.
   ? Customer->(Deleted())         // Result: .F.

■  This example uses Deleted() to display a record's deleted
   status in screens and reports:

   @ 1, 65 SAY IF(Deleted(), "Inactive", "Active")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Descend()Harbour implementation


⌃ | ☰

Create a descending index key value

Syntax

Descend(<exp>) → ValueInverted

Arguments

exp is any valid expression of character, date, logical, or numeric type. Memo type is treated in the same way as character type.

Returns

Descend() returns an inverted expression of the same data type as the exp, except for dates which return a numeric value. A Descend() of Chr(0) always returns Chr(0).

Description

Descend() is a conversion function that returns the inverted form of the specified expression to be used with INDEX to create descending order indexes. Specify that part of the index expression you want to be descending as the Descend() argument. To subsequently perform a lookup with SEEK, specify Descend() in the search expression.

Notes

■ The preferred way to create a descending index is to use the

DESCENDing clause of the INDEX command. Using DESCENDING is the same as specifying the Descend() function, but without the performance penalty during index updates. If you create a DESCENDING index, you will not need to use the Descend() function during a SEEK. DESCENDING is an attribute of the index (.ntx) file, where it is stored and used for REINDEXing purposes.

Examples

■  This example uses Descend() in an INDEX expression to create a
   descending order date index:

   USE Sales NEW
   INDEX ON Descend(OrdDate) TO SalesDate

   Later, use Descend() to SEEK on the descending index:

   SEEK Descend(dFindDate)

■  This example illustrates how to create a descending order
   index using more than one data type.  Here, the key is created using
   the concatenation of date and character fields after the appropriate
   type conversion has taken place.  This example uses Str() instead of
   DToS(), since Descend() of a date returns a numeric value:

   USE Sales NEW
   INDEX ON Str(Descend(SaleDate)) + Salesman TO LastSale

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

FIND*, INDEX, SEEK

DevOut()Harbour implementation


⌃ | ☰

Write a value to the current device

Syntax

DevOut(<exp>, [<cColorString>]) → NIL

Arguments

exp is the value to display.

cColorString is an optional argument that defines the display color of exp. If the current DEVICE setting is SCREEN, the output is displayed in the specified color.

If not specified, exp is displayed as the standard color of the current system color as defined by SetColor(). cColorString is a character expression containing the standard color setting. If you want to specify a literal color setting, enclose it in quote marks.

Returns

DevOut() always returns NIL.

Description

DevOut() is a full-screen display function that writes the value of a single expression to the current device at the current cursor or printhead position. Use DevOut() with DevPos() in std.ch to implement the @...SAY command.

Examples

■  This example shows the relationship between the DevOut()
   function and the @...SAY command:

   DevPos(10, 10)
   DevOut("Hello there", "BG+/B"))
   //
   @ 10, 10 SAY "Hello there" COLOR "BG+/B"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DevOutPict()Harbour implementation


⌃ | ☰

Write a value to the current device using a picture clause

Syntax

DevOutPict(<exp>, <cPicture>, [<cColorString>])
   → NIL

Arguments

exp is the value to display.

cPicture defines the formatting control for the display of exp. The picture specified here is the same as one used with @...SAY or TRANSFORM and can include both templates and functions.

cColorString is an optional argument that defines the display color of exp. If the current DEVICE is SCREEN, output displays in the specified color.

If not specified, exp displays as the standard color of the current system color as defined by SetColor(). cColorString is a character expression containing the standard color setting. If you want to specify a literal color setting, it must be enclosed in quote marks.

Returns

DevOutPict() always returns NIL.

Description

DevOutPict() is a full-screen display function that writes the value of a single expression to the current device at the current cursor or printhead position. DevOutPict() is used in combination with DevPos() in std.ch to implement the @...SAY command used with a PICTURE clause.

Examples

■  This example shows the relationship between the DevOutPict()
   function and the @...SAY command:

   DevPos(10, 10)
   DevOutPict("Hello there", "@!", "BG+/B"))
   //
   @ 10, 10 SAY "Hello there" PICTURE "@!" COLOR "BG+/B"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DevPos()Harbour implementation


⌃ | ☰

Move the cursor or printhead to a new position depending on the current device

Syntax

DevPos(<nRow>, <nCol>) → NIL

Arguments

nRow and nCol are the new row and column positions of the cursor or printhead.

Returns

DevPos() always returns NIL.

Description

DevPos() is an environment function that moves the screen or printhead depending on the current DEVICE. If DEVICE is SET to SCREEN, DevPos() behaves like SetPos(), moves the cursor to the specified location, and updates Row() and Col() with the new cursor position.

If DEVICE is SET to PRINTER, DevPos() moves the printhead instead. It does this by sending the number of linefeed and/or formfeed characters to the printer, and advancing the printhead to the new position. If the current SET MARGIN value is greater than zero, it is added to nCol. The printhead is then advanced to the specified nRow and nCol position and PRow() and PCol() are updated. If either nRow or nCol are less than the current PRow() and PCol() values, the printhead is moved according to the following special rules:

■ If nRow is less than PRow(), an automatic EJECT (Chr(12)) is

sent to the printer followed by the number of linefeed characters (Chr(10)) required to position the printhead on nRow of the following page.

■ If nCol including the current SET MARGIN value is less than

PCol(), a carriage return character (Chr(13)) and the number of space characters required to position the printhead at nCol are sent to the printer.

To circumvent these rules, use SetPRC() to reset PRow() and PCol() to new values before using DevPos(). See the SetPRC() discussion for more information.

If the printer is redirected to a file using the SET PRINTER command, DevPos() updates the file instead of the printer.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DECLARE*⌃ | ☰

Create and initialize private memory variables and arrays

Syntax

DECLARE <identifier> [[:= <initializer>], ... ]

Arguments

identifier is the name of a private variable or array to create. If the identifier is followed by square brackets ([ ]), it is created as an array. If the identifier is an array, the syntax for specifying the number of elements for each dimension is either array[nElements, nElements2,…] or array[nElements][nElements2]… The maximum number of elements per dimension is 4096.

initializer is the optional assignment of a value to a new private variable. An initializer expression for a private variable consists of the inline assignment operator (:=) followed by any valid CA-Clipper expression, including a literal array. If no explicit initializer is specified, the variable is given an initial value of NIL. In the case of an array, each element is NIL. Array identifiers, cannot be given values with an initializer.

DECLARE can create and, optionally, initialize a list of variable arrays, if definitions are separated by commas.

Description

DECLARE is a compatibility statement that is a synonym for the PRIVATE statement. Its general use is not recommended. PRIVATE should be used in all instances.

Platforms

Available on MS-DOS

See also

DELETEHarbour implementation⌃ | ☰

Mark records for deletion

Syntax

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

Arguments

scope is the portion of the current database file to DELETE. If a scope is not specified, DELETE acts only on the current record. If a conditional clause is specified, the default becomes ALL records.

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

FOR lCondition specifies the conditional set of records to DELETE within the given scope.

Description

DELETE is a database command that tags records so they can be filtered with SET DELETED ON, queried with Deleted(), or physically removed from the database file with PACK. In addition, display commands such as LIST and DISPLAY identify deleted records with an asterisk (*) character. Once records are deleted, you can reinstate them by using RECALL. If you want to remove all records from a database file, use ZAP instead of DELETE ALL and PACK.

Any deleted record can be recalled as long as the PACK or ZAP command has not been issued. Once the PACK or ZAP command has been issued, the deleted data cannot be retrieved.

In a network environment, DELETE requires the current record be locked with RLock() if you are deleting a single record. If you are deleting several records, the current database file must be locked with FLock() or USEed EXCLUSIVEly. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Notes

DELETE with SET DELETED ON: If the current record is deleted

with SET DELETED ON, it will be visible until the record pointer is moved.

Examples

■  This example demonstrates use of the FOR clause to mark a set
   of records for deletion:

   USE Sales INDEX Salesman NEW
   DELETE ALL FOR Inactive

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DELETE FILEHarbour implementation⌃ | ☰

Remove a file from disk

Syntax

DELETE FILE | ERASE <xcFile>

Arguments

xcFile is the name of the file to be deleted from disk and can be specified either as a literal file name or as a character expression enclosed in parentheses. You must specify the file name, including the extension, and it may optionally be preceded by a drive and/or path specification.

Description

DELETE FILE, a synonym for ERASE, is a file command that removes the specified file from disk. SET DEFAULT and SET PATH do not affect DELETE FILE. The file is deleted from disk only if found in the current DOS directory or in the directory explicitly specified as part of the file name.

Warning! Files must be CLOSEd before deleting them. Otherwise, either a sharing violation or a date corruption on the drive may occur.

Examples

■  This example removes a specified file from disk then tests to
   see if the file was in fact removed:

   ? FILE("Temp.dbf")               // Result: .T.
   DELETE FILE Temp.dbf
   ? FILE("Temp.dbf")               // Result: .F.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DELETE TAGHarbour implementation⌃ | ☰

Delete a tag

Syntax

DELETE TAG <cOrderName> [IN <xcOrderBagName>]
   [, <cOrderName> [IN xcOrderBagName] list>]

Arguments

cOrderName is a character string that represents the order name.

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

cOrderName ...list is an optional list of order and order bag name pairs, separated by commas. Any reference to cOrderName that results in either a null string («») or spaces is ignored. You can specify each order as a literal expression or as a character expression enclosed in parentheses. If you specify no extension for the order bag name, the current database driver supplies a default extension.

Description

This command removes an order from an order bag in the current or specified work area. If you do not specify an xcOrderBagName, all orders bags are searched in the current or specified work area. The first occurrence of cOrderName is deleted. A runtime recoverable error is raised if the order is not found.

If cOrderName is the active order, the database in the current or specified work area reverts to its identity order (natural or entry) and SET FILTER scoping.

A runtime error is raised if xcOrderBagName does not exist or if it exists but does not contain cOrderName.

The active RDD determines the order capacity of an order bag. The default DBFNTX and the DBFNDX drivers only support single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBFMDX drivers).

Examples

USE Customer VIA "DBFCDX" NEW
SET INDEX TO Customer

// Delete the Orders (Tags) Cust01 and Cust02 that
// exist in the index file Customer
DELETE TAG Cust01 IN Customer
DELETE TAG Cust02 IN Customer

// or
// DELETE TAG Cust01 IN Customer, Cust02 IN Customer

Platforms

Available on MS-DOS

See also

DirChange()Harbour implementation


⌃ | ☰

Change the current DOS directory

Syntax

DirChange(<cDir>) → nSuccess

Arguments

cDir is the name of the directory to change to, including the drive.

Returns

DirChange() returns 0 if successful; -1 if there is an argument error. Otherwise, DirChange() returns the DOS error code.

Description

DirChange() changes the current DOS directory. This function may also be used to determine whether or not a directory exists.

Examples

■  The following example attempts to change to the "c:dos"
   directory.  If it is unsuccessful, an error message is displayed.

   nResult :=  DirChange("c:dos")

   IF nResult != 0
      ? "Cannot change directory. "
      DO CASE
         CASE nResult == 3
            ?? "Directory does not exist."
         CASE nResult == 5
            ?? "Access to directory denied."
      END
      BREAK
   ENDIF

  You may also use something like this:

   DirChange( "....test" )

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

Directory()Harbour implementation


⌃ | ☰

Create an array of directory and file information

Syntax

Directory(<cDirSpec>, [<cAttributes>]) → aDirectory

Arguments

cDirSpec identifies the drive, directory and file specification for the directory search. Wildcards are allowed in the file specification. If cDirSpec is omitted, the default value is *.*.

cAttributes specifies inclusion of files with special attributes in the returned information. cAttributes is a string containing one or more of the following characters:

Directory() Attributes

    Attribute    Meaning

    H            Include hidden files

    S            Include system files

    D            Include directories

    V            Search for the DOS volume label and exclude all other files

Normal files are always included in the search, unless you specify V.

Returns

Directory() returns an array of subarrays, with each subarray containing information about each file matching cDirSpec. The subarray has the following structure:

Directory() Subarray Structure

    Position     Metasymbol     Directry.ch

    1            cName          F_NAME

    2            cSize          F_SIZE

    3            dDate          F_DATE

    4            cTime          F_TIME

    5            cAttributes    F_ATTR

If no files are found matching cDirSpec or if cDirSpec is an illegal path or file specification, Directory() returns an empty ({}) array.

Description

Directory() is an environment function that returns information about files in the current or specified directory. It is similar to ADir(), but returns a single array instead of adding values to a series of existing arrays passed by reference.

Use Directory() to perform actions on groups of files. In combination with AEval(), you can define a block that can be applied to all files matching the specified cDirSpec.

The header file, directry.ch, in the CLIP53INCLUDE subdirectory contains #defines for the subarray subscripts, so that the references to each file subarray are more readable.

Examples

■  This example creates an array of information about files in
   the current directory and then lists the names of the files using
   AEval() and QOut():

   #include "Directry.ch"
   //
   aDirectory := Directory("*.*", "D")
   AEval( aDirectory, {|aFile| QOut(aFile[F_NAME])} )

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is directry.ch.

See also

DirMake()


⌃ | ☰

Create a directory

Syntax

DirMake(<cNewDir>) → nSuccess

Arguments

cNewDir is the name of the directory to be created, including an optional drive. If you do not specify a drive, the current one is used.

Returns

DirMake() returns 0 if successful; -1 if there is an argument error. Otherwise, DirMake() returns the DOS error code.

Description

DirMake() creates a specified directory. Note that first you must have sufficient rights to create a directory. To create nested subdirectories, you must create each subdirectory separately, starting from the top-level directory that you want to create (see example below.)

Examples

■  This example assumes that C:TEST exists and uses DirMake()
   twice to create a nested subdirectory under it:

   DirMake("c:testone")    // Create top-most one
   nResult := DirMake("c:testonetwo")
   IF nResult != 0
      ? "Cannot make directory, DOS error ", nResult
      BREAK
   ENDIF

  You may also use something like this:

   DirMake( ".test" )

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

DirRemove()→ hb_DirDelete()Harbour implementation


⌃ | ☰

Remove a directory

Syntax

DirRemove(<cDirName>) → nSuccess

Arguments

cDirName is the name of the directory to erase, including an optional drive. If you do not specify a drive, the current one is used.

Returns

DirRemove() returns 0 if successful; -1 if there is an argument error. Otherwise, DIRREMOVE returns the DOS error code.

Description

DirRemove() removes a specified directory. Note that you must first have sufficient rights to delete a directory. A directory must be empty in order to be deleted. Therefore, to delete a directory that contains subdirectories, you must first delete the subdirectories (see example below).

Examples

■  This example uses DirRemove() to delete a subdirectory named
   C:TESTONE, which only contains an empty subdirectory named
   C:TESTONETWO:

   DirRemove("c:testonetwo")        // First delete lowest dir
   nResult := DirRemove("c:testone")  // Then delete higher dir
   IF nResult != 0
      ? "Cannot remove directory, DOS error ", siResult
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

DiskChange()Harbour implementation


⌃ | ☰

Change the current DOS disk drive

Syntax

DiskChange(<cDrive>) → lSuccess

Arguments

cDrive specifies the letter of the disk drive to change to.

Returns

DiskChange() returns true (.T.) if successful; otherwise, it returns false (.F.).

Examples

■  This example uses DiskChange() to change to drive "D":

   IF DiskChange("D:")
      ? "Successfully changed"
   ELSE
      ? "Not changed"
   ENDIF


■  This example builds a string that contains all currently
   available drives on your system:

   FUNCTION AllDrives()
      LOCAL wI, cDrives := ""

      FOR wI := 1 TO 26
         IF DiskChange( Chr(wI + 64) )
            cDrives := cDrives + Chr(wI + 64)
         ENDIF
      NEXT
   RETURN cDrives

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

DiskName()Harbour implementation


⌃ | ☰

Return the current DOS drive

Syntax

Returns

DiskName() returns the letter of the current DOS drive, without a trailing colon.

Examples

■  This example illustrates the relationship between
   DiskName()and DiskChange() and shows that DiskName() is unaffected by
   the SET DEFAULT TO command:

   ? DiskName()      // C
   SET DEFAULT TO A
   ? DiskName()      // C
   DiskChange("A")
   ? DiskName()      // A
   DiskChange("C")
   ? DiskName()      // C

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

DiskSpace()Harbour implementation


⌃ | ☰

Return the space available on a specified disk

Syntax

DiskSpace([<nDrive>]) → nBytes

Arguments

nDrive is the number of the drive to query, where one is drive A, two is B, three is C, etc. The default is the current DOS drive if nDrive is omitted or specified as zero.

Returns

DiskSpace() returns the number of bytes of empty space on the specified disk drive as an integer numeric value.

Description

DiskSpace() is an environment function that determines the number of available bytes remaining on the specified disk drive. It is useful when COPYing or SORTing to another drive to determine if there is enough space available before initiating the operation. You may also use DiskSpace() with RecSize() and RecCount() to create a procedure to back up database files.

DiskSpace() ignores the SET DEFAULT drive setting.

Examples

■  This example is a user-defined function that demonstrates the
   use of DiskSpace() to back up a database file to another drive:

   FUNCTION BackUp( cTargetFile, cTargetDrive )
      LOCAL nSpaceNeeded, nTargetDrive
      //
      nSpaceNeeded := INT((RecSize() * ;
         LastRec()) + Header() + 1)
      nTargetDrive := Asc(Upper(cTargetDrive)) - 64
      //
      IF DiskSpace(nTargetDrive) < nSpaceNeeded
         RETURN .F.
      ENDIF
      COPY TO (cTargetDrive + ":" + cTargetFile)
      //
      RETURN .T.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

DispBegin()Harbour implementation


⌃ | ☰

Begin buffering screen output

Syntax

Returns

DispBegin() always returns NIL.

Description

DispBegin() is a screen function that informs the CA-Clipper display output system that the application is about to perform a series of display operations.

Use DispBegin() with DispEnd() to allow the display output system to buffer display updates. Display output which occurs after DispBegin() but before DispEnd() is allowed to accumulate in internal buffers. When DispEnd() executes, any pending updates appear on the physical display. This is useful in applications where complex screen displays are slow and the appearance of performance is desired.

DispBegin() and DispEnd() calls are optional. They are not required for normal output.

Notes

■ Nested calls: DispBegin() calls are nested internally. If

several DispBegin() calls occur, buffering is allowed until a corresponding number of DispEnd() calls occur.

■ Guaranteed operations: Display updates performed between

DispBegin() and DispEnd() are not guaranteed to be buffered—some updates may become visible before DispEnd() is called. However, all updates are guaranteed to be visible after the closing call to DispEnd().

■ Terminal operations: Terminal input operations such as Inkey()

or READ should not be performed between DispBegin() and DispEnd(). Doing this may cause input or display output to be lost.

■ Incompatible operations: Display output by other than the

CA-Clipper display functions (e.g., by add-on libraries or by DOS via OutStd(), etc.) may not be compatible with DispBegin() and DispEnd(). Output may be lost.

Examples

■  This example buffers screen output, updates the screen, and
   then displays the buffered screen output:

   DispBegin()            // Start screen buffering
   //
   SetPos(10, 10)
   DispOut("A display update")
   SetPos(11, 10)
   DispOut("Another display update")
   //
   DispEnd()               // Display buffered screen data

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DispBox()Harbour implementation


⌃ | ☰

Display a box on the screen

Syntax

DispBox(<nTop>, <nLeft>, <nBottom>, <nRight>,
   [<cnBoxString>], [<cColorString>]) → NIL

Arguments

nTop, nLeft, nBottom, and nRight define the coordinates of the box. DispBox() draws a box using row values from zero to MaxRow(), and column values from zero to MaxCol(). If nBottom and nRight are larger than MaxRow() and MaxCol(), the bottom-right corner is drawn off the screen.

cnBoxString is a numeric or character expression that defines the border characters of the box. If specified as a numeric expression, a value of 1 displays a single-line box and a value of 2 displays a double-line box. All other numeric values display a single-line box.

If cnBoxString is a character expression, it specifies the characters to be used in drawing the box. This is a string of eight border characters and a fill character. If cnBoxString is specified as a single character, that character is used to draw the whole box.

If this argument is not specified, a single-line box is drawn.

cColorString defines the display color of the box that is drawn. If not specified, the box is drawn using the standard color setting of the current system color as defined by SetColor().

Returns

DispBox() always returns NIL.

Description

DispBox() is a screen function that draws a box at the specified display coordinates in the specified color. If you specify cnBoxString, DispBox() draws a box on the screen using configurable border and fill characters. DispBox() draws the box using cnBoxString starting from the upper left-hand corner, proceeding clockwise and filling the screen region with the ninth character. If the ninth character is not specified, the screen region within the box is not painted. Existing text and color remain unchanged.

In cases where cnBoxString respects CA-Clipper conventions, the behavior of DispBox() is unchanged. The behavior of this function can easily be modified to take advantage of graphic mode. For example, you can replace the standard window frames using single or double lines with new graphical frames that have an impressive 3-D look. Simply replace the cBoxString parameter using the following:

Chr(2) + Chr(nColor+1) // draws a box of thickness 16x8x16x8 Chr(3) + Chr(nColor+1) // draws a box of thickness 8x8x8x8 Chr(4) + Chr(nColor+1) // draws a box of thickness

// 16x16x16x16

Chr(5) + Chr(nColor+1) // draws a box of thickness 16x8x8x8

Note that nColor is a numeric color representation. You must add 1 to this value.

In general, Chr(2) + Chr(nColor+1) can be used instead of CA-Clipper’s B_SINGLE or B_DOUBLE defines.

CA-Clipper graphics comes with two #defines LLG_BOX_GRAY_STD and LLG_BOX_GRAY_SQUARE to allow gray (nColor=7) boxes of width 16×8 or 16×16.

You can completely customize the box by passing Chr(1) + … as the first parameter:

Chr(1) + ; // Box entirely defined Chr(nBackColor+1) + ; // Color used as background fill Chr(nLightColor+1) + ; // Color used to lighten the frame Chr(nDarkColor+1) + ; // Color used to darken the frame Chr(nWidthUp) + ; // Thickness of upper edge of box Chr(nWidthRight) + ; // Thickness of right edge of box Chr(nWidthDown) + ; // Thickness of lower edge of box Chr(nWidthLeft) // Thickness of left edge of box

After DispBox() executes, the cursor is located in the upper corner of the boxed region at nTop + 1 and nLeft + 1. Row() and Col() are also updated to reflect the new cursor position.

Note that box.ch, located in CLIP53INCLUDE, provides constants for various border configurations.

Notes

The number of colors available depends on the current video mode setting ( SET VIDEOMODE ).

Examples

■  This code example displays a double-line box using a numeric
   value to specify the box border:

   #define B_SINGLE   1
   #define B_DOUBLE   2
   //
   DispBox(1, 1, 10, 10, B_DOUBLE, "BG+/B")

■  This example displays a single-line top and double-line side
   box by specifying border characters with a manifest constant defined
   in box.ch:

   #include "Box.ch"
   //
   DispBox(1, 1, 10, 10, B_SINGLE_DOUBLE, "BG+/B")

■  This example displays a box with a 3-D look.  It can be used
   for graphic mode:

   // Display a box with a 3D look of constant width 16x16x16x16
   DispBox( nTop, nLeft, nBottom, nRight, LLG_BOX_GRAY_SQUARE )
   // Write some transparent text in the 3D frame
   GWRITEAT(  nLeft * GMODE()[LLG_MODE_FONT_COL] ,;
   nTop  * GMODE()[LLG_MODE_FONT_ROW] ,;
   "This is some Text...",;
   4,;
   LLG_MODE_SET; )

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

DispCount()Harbour implementation


⌃ | ☰

Return the number of pending DispEnd() requests

Syntax

Returns

DispCount() returns the number of DispEnd() calls required to restore the original display context.

Description

You can use DispCount() to determine the current display context. CA-Clipper uses display contexts to buffer and to supervise screen output operations.

Each call to DispBegin() defines a new display context. Output to the display context is suppressed until a matching DispEnd() statement executes.

Since you may nest DispBegin() calls, use DispCount() to determine whether there are pending screen refresh requests.

Examples

■  This example saves the setting of DispCount(), then releases
   all pending display contexts before writing to the screen:

   PROCEDURE ForceDisplay(cExp)
      LOCAL nSavCount

   nSavCount := DispCount()

   //  Discard pending display contexts
   DO WHILE ( DispCount() > 0)
      DispEnd()

   ENDDO

   DispOut(cExp)

   //  "Rewind" the current display context
   DO WHILE (DISPCCOUNT() < nSavCount )
      DispBegin()
   ENDDO

   RETURN

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DispEnd()Harbour implementation


⌃ | ☰

Display buffered screen updates

Syntax

Returns

DispEnd() always returns NIL.

Description

DispEnd() is a screen function that informs the CA-Clipper display output system that the application has finished performing a series of display operations.

DispEnd() is used with DispBegin() so the display output system can buffer display updates. This can be important for applications in which complex screen displays are slow and the appearance of performance is desired.

Examples

■  This example buffers screen output, updates the screen, and
   then displays the buffered screen output:

   DispBegin()            // Start screen buffering
   //
   SetPos(10, 10)
   DispOut("A display update")
   SetPos(11, 10)
   DispOut("Another display update")
   //
   DispEnd()               // Display buffered screen data

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DispOut()Harbour implementation


⌃ | ☰

Write a value to the display

Syntax

DispOut(<exp>, [<cColorString>]) → NIL

Arguments

exp is the value to display.

cColorString is an optional argument that defines the display color of exp. If unspecified, exp is displayed as the standard color of the current system color as defined by SetColor(). cColorString is a character expression containing the standard color setting. You can specify a literal color setting, if you enclose it in quote marks.

Returns

DispOut() always returns NIL.

Description

DispOut() is a simple output function that writes the value of a single expression to the display at the current cursor position. This function ignores the SET DEVICE setting; output always goes to the screen. You can only use this function within a procedure or function.

Examples

■  This example performs screen output at a specified location in
   different colors.  Note how the cursor position is saved and restored
   using Row(), Col(), and SetPos():

   PROCEDURE Showit
      LOCAL nRow, nCol
      ? nCol := Col()            // save original
      ?? nRow := Row()            // cursor position

      Inkey(2)

      SetPos(nRow, nCol)
      DispOut("This is a test of DispOut()")
      ? Col()                     // display current
      ?? Row()                     // cursor position

      Inkey(2)

      SetPos(nRow, nCol)
      DispOut(Space(26))         // clear original position
      SET DEVICE TO PRINTER      // ignores SET DEVICE

      SetPos(nRow, nCol)         // display at
      DispOut("           all through")
                                 // original position

      RETURN

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DIR*Harbour implementation⌃ | ☰

Display a listing of files from a specified path

Syntax

Arguments

xcFileSpec is a template that must be matched by displayed files and can include standard wildcard (* and ?) characters. You can specify xcFileSpec as a literal file specification string or as a character expression enclosed in parentheses.

Description

DIR is a file command that displays a listing of files from the specified path in one of two formats depending on whether you specify the xcFileSpec argument. If you do not specify a path, DIR displays a standard listing of database files from the current or specified directory. The list includes the database file name, date of last update, and number of records. Including the option xcFileSpec displays a list of all files in the specified directory. This list includes the file name, extension, number of bytes, and date of last update.

If no path is specified, DIR displays files from the current DOS drive and directory unless SET DEFAULT has been used to specify a new default directory.

DIR is a compatibility command and therefore not recommended. It is superseded by the Directory() function which returns an array of file information from a wildcard pattern. Using this array, you can display file information to screen.

Notes

■ Directory picklists: To present directory information to the

user, use ADir() to return one or more arrays of directory information, and AChoice() to present a picklist to the user.

Examples

■  These examples display DOS and database files in the current
   directory:

   cFilespec := "*.*"
   DIR (cFilespec)            // Display all files
   DIR                        // Display all (.dbf) files
   DIR *.prg                  // Display all program files

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

DISPLAYHarbour implementation⌃ | ☰

Display records to the console

Syntax

DISPLAY <exp list>
   [TO PRINTER] [TO FILE <xcFile>]
   [<scope>] [WHILE <lCondition>]
   [FOR <lCondition>] [OFF]

Arguments

exp list is the list of values to display for each record processed.

TO PRINTER echoes output to the printer.

TO FILE xcFile echoes output to the indicated file which can be specified either as a literal file name or as a character expression enclosed in parentheses. If an extension is not specified, .txt is added.

scope is the portion of the current database file to DISPLAY. The default is the current record, or NEXT 1. If a condition is specified, the scope becomes ALL.

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

FOR lCondition specifies the conditional set of records to DISPLAY within the given scope.

OFF suppresses the display of the record number.

Description

DISPLAY is a database command that sequentially accesses records in the current work area, sending the results of the exp list to the console in a tabular format with each column separated by a space. The command does not display column headers or pause at predetermined intervals. DISPLAY is identical to LIST with the exception that its default scope is NEXT 1 rather than ALL.

When invoked, output is sent to the screen and optionally to the printer and/or a file. To suppress output to the screen while printing or echoing output to a file, SET CONSOLE OFF before the DISPLAY command line.

Notes

■ Interrupting output: To let the user interrupt the processing

of a DISPLAY command, using the Inkey() function, add a test for the interrupt key press to the FOR condition. See the example below.

■ Printer margin: Since DISPLAY is a console command, it honors

the current SET MARGIN for output echoed to the printer.

Examples

■  This example illustrates a simple DISPLAY, and a conditional
   DISPLAY to the printer:

   USE Sales NEW
   DISPLAY Date(), Time(), Branch
   DISPLAY Branch, Salesman FOR Amount > 500 TO PRINTER

■  This example interrupts a DISPLAY using Inkey() to test
   whether the user pressed the Esc key:

   #define K_ESC  27
   USE Sales INDEX SalesMan NEW
   DISPLAY Branch, Salesman, Amount WHILE ;
      Inkey() != K_ESC

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DosError()Harbour implementation


⌃ | ☰

Return the last DOS error number

Syntax

DosError([<nNewOsCode>]) → nOsCode

Arguments

nNewOsCode, if specified, alters the value returned by DosError(). The value must be a numeric value that reflects a DOS error number.

Returns

DosError() returns the DOS error number as an integer numeric value.

Description

DosError() is an error function that returns the last DOS error code associated with an activation of the runtime error block. When a runtime error occurs, the DosError() function is set to the current DOS error if the operation has an associated DOS error. The function value is retained until another runtime error occurs. If the failed operation has no associated DOS error, the DosError() returns zero. With low- level file functions, FError() returns the same value as DosError().

Through use of the optional nNewOsCode, you may customize to the reporting activation the returned value for any DOS error.

For a complete list of DOS error numbers and accompanying descriptions, refer to the Error Messages and Appendices Guide.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DoW()Harbour implementation


⌃ | ☰

Convert a date value to a numeric day of the week

Syntax

Arguments

dDate is a date value to convert.

Returns

DoW() returns the day of the week as a number between zero and seven. The first day of the week is one (Sunday) and the last day is seven (Saturday). If dDate is empty, DoW() returns zero.

Description

DoW() is a date conversion function that converts a date value to a number identifying the day of the week. It is useful when you want date calculations on a weekly basis. DoW() is similar to CDoW(), which returns the day of week as a character string instead of a number.

Examples

■  These examples illustrate CDoW() and its relationship to
   DoW():

   ? Date()                        // Result: 09/01/89
   ? DoW(Date())                  // Result: 3
   ? CDoW(Date())                  // Result: Tuesday
   ? DoW(Date() - 2)               // Result: 1
   ? CDoW(Date() - 2)            // Result: Sunday

■  This is a user-defined function that uses DoW() to calculate
   the date of last Monday from any other date:

   FUNCTION LastMonday(dDate)
      RETURN (dDate - DoW(dDate) + 2)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DO CASE⌃ | ☰

Execute one of several alternative blocks of statements

Syntax

DO CASE
CASE <lCondition1>
   <statements>...
[CASE <lCondition2>]
   <statements>...
[OTHERWISE]
   <statements>...
END[CASE]

Arguments

CASE lCondition defines a block of statements to be executed if lCondition evaluates to true (.T.).

OTHERWISE defines a block of statements to be executed if none of the specified CASE conditions evaluates to true (.T.).

Description

DO CASE...ENDCASE is a control structure that executes one of several blocks of statements depending on which of the associated conditions is true (.T.). It works by branching execution to the statements following the first CASE lCondition that evaluates to true (.T.). Execution continues until the next CASE, OTHERWISE, or ENDCASE is encountered. Control then branches to the first statement following the next ENDCASE statement.

If none of the CASE conditions evaluates to true (.T.), the statements following the OTHERWISE statement are executed up to the matching ENDCASE statement. If an OTHERWISE statement is omitted, control branches to the first statement following the matching ENDCASE statement.

You may nest any number of statements, including other control structures (i.e., DO WHILE and FOR), within a single DO CASE structure. In addition, within a single DO CASE structure, there is no fixed limit on the number of CASE statements that a DO CASE structure may contain.

DO CASE...ENDCASE is identical to IF...ELSEIF...ENDIF with neither syntax having a specific advantage over the other.

Examples

■  This example uses DO CASE in a menu structure to branch
   control based on user selection:

   @ 3, 25 PROMPT "First choice"
   @ 4, 25 PROMPT "Second choice"
   MENU TO nChoice
   //
   DO CASE
   CASE nChoice = 0
      RETURN
   CASE nChoice = 1
      ChoiceOne()
   CASE nChoice = 2
      ChoiceTwo()
   ENDCASE

Platforms

Available on MS-DOS

See also

BEGIN SEQUENCE, DO WHILE, FOR, IF, IF()

DO WHILE⌃ | ☰

Execute a loop while a condition is true (.T.)

Syntax

[DO] WHILE <lCondition>
   <statements>...
   [EXIT]
   <statements>...
   [LOOP]
   <statements>...
END[DO]

Arguments

lCondition is the logical control expression for the DO WHILE loop.

EXIT unconditionally branches control from within a DO WHILE or FOR...NEXT structure to the statement immediately following the corresponding ENDDO or NEXT statement.

LOOP branches control to the most recently executed DO WHILE or FOR statement.

Description

DO WHILE...ENDDO is a control structure that executes a block of statements repetitively, as long as lCondition evaluates to true (.T.). When the condition evaluates to true (.T.), control passes into the structure and proceeds until an EXIT, LOOP, or ENDDO is encountered. ENDDO returns control to the DO WHILE statement and the process repeats itself. If an EXIT statement is encountered, control branches to the nearest ENDDO or NEXT statement. If a LOOP statement is encountered, control branches to the nearest DO WHILE or FOR statement. If the condition evaluates to false (.F.), the DO WHILE construct terminates and control passes to the statement immediately following the ENDDO.

Use EXIT to terminate a DO WHILE structure based on a condition other than the DO WHILE condition. LOOP, by contrast, prevents execution of statements within a DO WHILE based on an intermediate condition, and returns to the most recent DO WHILE statement.

DO WHILE constructs may be nested within any other control structures to any depth. The only requirement is that each control structure be properly nested.

Examples

■  This example demonstrates a typical control structure for a
   simple grouped report:

   LOCAL cOldSalesman, nTotalAmount
   USE Sales INDEX Salesman NEW
   DO WHILE .NOT. Eof()
      cOldSalesman := Sales->Salesman
      nTotalAmount := 0
      DO WHILE cOldSalesman = Sales->Salesman ;
         .AND. (.NOT. Eof())
         ? Sales->Salesman, Sales->Amount
         nTotalAmount := nTotalAmount + Sales->Amount
         SKIP
      ENDDO
      ? "Total: ", nTotalAmount, "for", cOldSalesman
   ENDDO
   CLOSE Sales

■  This code fragment demonstrates how LOOP can be used to
   provide an intermediate processing condition:

   DO WHILE <lCondition>
      <initial processing>...
      IF <intermediate condition>
         LOOP
      ENDIF
      <continued processing>...
   ENDDO

■  This example demonstrates the use of DO WHILE to emulate a
   repeat until looping construct:

   LOCAL lMore := .T.
   DO WHILE lMore
      <statements>...
      lMore := (<lCondition>)
   ENDDO

■  This example uses a DO WHILE loop to move sequentially through
   a database file:

   DO WHILE .NOT. Eof()
      <statements>...
      SKIP
   ENDDO

Platforms

Available on MS-DOS

See also

DO*⌃ | ☰

Call a procedure

Syntax

DO <idProcedure> [WITH <argument list>]

Arguments

idProcedure is the name of the procedure or user-defined function to be executed.

WITH argument list specifies up to 128 arguments, separated by commas, to pass to idProcedure. Each argument may be a single variable, field, array, array element, expression, or object. Arguments can be skipped or left off the end of the list.

Description

The DO statement calls a procedure or user-defined function, optionally passing arguments to the called routine. It performs the same action as a user-defined function or procedure specified on a line by itself with the exception that variables other than field variables are passed by reference as the default. In order to pass a field variable as an argument, enclose it in parentheses, unless you declare it with the FIELD statement or with an alias.

In CA-Clipper, the number of specified arguments need not match the number of specified parameters in the called procedure. If the number of arguments is less than the number of parameters, the parameter variables with no corresponding arguments are initialized with a NIL value when the procedure is called. If the number of arguments is greater than the number of parameters, they are ignored.

Also, skipping an argument within the argument list by leaving an empty spot next to the comma initializes the corresponding argument to NIL. To detect the position of the last argument passed in the argument list, use PCount(). To detect a skipped argument, compare the receiving parameter to NIL.

In addition to calling a procedure or user-defined function, DO also has an effect on compilation if you compile the current program file without the /M option. If the CA-Clipper compiler encounters a DO statement and the specified procedure has not already been compiled, the compiler searches the current directory for a .prg file with the same name and compiles it. If the file with the same name as the procedure is not found, the called procedure is assumed to be external, and a reference is added to the object (.OBJ) file. At link time, the linker will search other object files and libraries for this external reference.

In CA-Clipper, DO is a compatibility statement and therefore not recommended. Calling a procedure or function on a line by itself is the preferred method. Since this preferred calling convention normally passes parameters by value, you must preface an argument with the pass- by-reference operator (@) in order to pass by reference. If you are using DO to make a procedure call more readable, a user-defined command, specified with the #command directive, can provide greater readability without sacrificing the safety of variables passed as parameters.

For more information on passing parameters refer to the Functions and Procedures section of the «Basic Concepts» chapter in the Programming and Utilities Guide.

Examples

■  This example executes a procedure with no parameters:

   DO AcctsRpt
   AcctsRpt()                           // Preferred method

■  This example executes a procedure passing two constants:

   DO QtrRpt WITH "2nd", "Sales Division"
   QtrRpt("2nd", "Sales Division")      // Preferred method

■  In this example, a procedure is executed with the first
   argument passed by value and the second passed by reference:

   nNumber := 12
   DO YearRpt WITH nNumber + 12, nNumber
   YearRpt(nNumber + 12, @nNumber)      // Preferred method

■  Here, a procedure is invoked with skipped arguments embedded
   in the list of arguments:

   DO DisplayWindow WITH ,,,,"My Window"
   DisplayWindow(,,,,"My Window")       // Preferred method

Platforms

Available on MS-DOS

See also

DToC()Harbour implementation


⌃ | ☰

Convert a date value to a character string

Syntax

Arguments

dDate is the date value to convert.

Returns

DToC() returns a character string representation of a date value. The return value is formatted in the current date format. The default format is mm/dd/yy. A null date returns a string of spaces equal in length to the current date format.

Description

DToC() is a date conversion function used for formatting purposes when you want to display the date in the SET DATE format and when a character expression is required (in a LABEL FORM, for example). If you need a specialized date format, you can use Transform() or a custom expression.

If you are INDEXing a date in combination with a character string, use DToS() instead of DToC() to convert the date value to a character string.

Examples

■  These examples show general uses of DToC():

   ? Date()                  // Result: 09/01/90
   ? DToC(Date())            // Result: 09/01/90
   ? "Today is " + DToC(Date())
                           // Result: Today is 09/01/90

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

DToS()Harbour implementation


⌃ | ☰

Convert a date value to a character string formatted as yyyymmdd

Syntax

Arguments

dDate is the date value to convert.

Returns

DToS() returns a character string eight characters long in the format yyyymmdd. When dDate is a null date (CToD(«»)), DToS() returns a string of eight spaces. The return value is not affected by the current date format.

Description

DToS() is a date conversion function that is used when creating index expressions consisting of a date value and a character expression. DToS() converts a date value to a character string that can be concatenated to any other character expression. The return value is structured to preserve date order (year, month, and day).

Examples

■  These examples illustrate DToS() in conjunction with several
   other functions:

   ? Date()                        // Result: 09/01/90

   ? DToS(Date())                  // Result: 19900901
   ? Len(DToS(CToD("")))           // Result: 8

■  This example demonstrates how to create an index with a
   compound date and character key using DToS():

   USE Sales NEW
   INDEX ON DToS(Date) + Salesman TO DateName

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

EJECTHarbour implementation⌃ | ☰

Advance the printhead to top of form

Syntax

Description

EJECT is a printing command that sends a formfeed character (Chr(12)) to the printer and sets the PCol() and PRow() values to zero. If you address a printer row less than the last row position since an EJECT or SetPRC() was executed, CA-Clipper automatically performs an EJECT. Because of this, your printing logic must proceed sequentially from left to right down the page. If you need to reset the internal printer row and column values to zero without sending a formfeed, use SetPRC().

Examples

■  This example prints a simple list report and uses EJECT to
   advance to a new page when the line counter reaches the maximum
   number of lines to print per page:

   LOCAL nLine := 99, nPage := 0
   USE Sales NEW
   SET PRINTER ON
   SET CONSOLE OFF
   DO WHILE !Eof()
      IF nLine > 55
         EJECT
         ? "Page " + LTrim(Str(++nPage, 3))
         ? "Date " + CToD(Date())
         ?
         ? "Salesman", "Amount"
         ?
         nLine := 6
      ENDIF
      ? Sales->Salesman, Sales->Amount
      nLine++
      SKIP
   ENDDO
   SET PRINTER OFF
   SET CONSOLE ON
   CLOSE

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Empty()Harbour implementation


⌃ | ☰

Determine if the result of an expression is empty

Syntax

Arguments

exp is an expression of any data type.

Returns

Empty() returns true (.T.) if the expression results in an empty value; otherwise, it returns false (.F.). The criteria for determining whether a value is considered empty depends on the data type of exp according to the following rules:

List of Empty Values

    Data Type    Contents

    Array        Zero-length

    Character    Spaces, tabs, CR/LF, or («»)

    Numeric      0

    Date         Null (CToD(«»))

    Logical      False (.F.)

    Memo         Same as character

    NIL          NIL

Description

The Empty() function has a number of uses. You can use it to determine if a user entered a value into a Get object before committing changes to a database file. It can also determine whether a formal parameter is NIL or unsupplied. In addition, it can test an array for zero-length.

Notes

■ Space characters: The Empty() function treats carriage

returns, line feeds, and tabs as space characters and removes these as well.

Examples

■  These examples illustrate use of Empty() against several
   different data types:

   ? Empty(Space(5)), Empty("")        // Result: .T. .T.
   ? Empty(0), Empty(CToD(""))         // Result: .T. .T.
   ? Empty(.F.), Empty(NIL)            // Result: .T. .T.

■  This example uses Empty() to determine whether the user
   entered a value into the first Get object before writing the new
   value to the database file:

   LOCAL cCust := Space(15), nAmount := 0
   USE Sales NEW
   @ 10, 10 GET cCust
   @ 11, 10 GET nAmount PICTURE "999.99"
   READ
   //
   IF !Empty(cCust)
      APPEND BLANK
      REPLACE Sales->Cust WITH cCust, Sales->Amount ;
         WITH nAmount
   ENDIF

■  This example uses Empty() as part of the VALID clause to force
   the user to enter data into the current Get object:

   LOCAL cCode := Space(5)
   @ 2, 5 SAY "Enter code" GET cCode VALID !Empty(cCode)
   READ

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Eof()Harbour implementation


⌃ | ☰

Determine when end of file is encountered

Syntax

Returns

Eof() returns true (.T.) when an attempt is made to move the record pointer beyond the last logical record in a database file; otherwise, it returns false (.F.). If there is no database file open in the current work area, Eof() returns false (.F.). If the current database file contains no records, Eof() returns true (.T.).

Description

Eof() is a database function used to test for an end of file boundary condition when the record pointer is moving forward through a database file. Any command that can move the record pointer can set Eof().

The most typical application is as a part of the lCondition argument of a DO WHILE construct that sequentially processes records in a database file. Here lCondition would include a test for .NOT. Eof(), forcing the DO WHILE loop to terminate when Eof() returns true (.T.).

Eof() and Found() are often used interchangeably to test whether a SEEK, FIND, or LOCATE command failed. With these commands, however, Found() is preferred.

When Eof() returns true (.T.), the record pointer is positioned at LastRec() + 1 regardless of whether there is an active SET FILTER or SET DELETED is ON. Further attempts to move the record pointer forward return the same result without error. Once Eof() is set to true (.T.), it retains its value until there is another attempt to move the record pointer.

By default, Eof() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression (see example below).

Examples

■  This example demonstrates Eof() by deliberately moving the
   record pointer beyond the last record:

   USE Sales
   GO BOTTOM
   ? Eof()            // Result: .F.
   SKIP
   ? Eof()            // Result: .T.

■  This example uses aliased expressions to query the value of
   Eof() in unselected work areas:

   USE Sales NEW
   USE Customer NEW
   ? Sales->(Eof())
   ? Customer->(Eof())

■  This example illustrates how Eof() can be used as part of a
   condition for sequential database file operations:

   USE Sales INDEX CustNum NEW
   DO WHILE !Eof()
      nOldCust := Sales->CustNum
      nTotalAmount := 0
      DO WHILE nOldCust = Sales->CustNum .AND. (!Eof())
         ? Sales->CustNum, Sales->Description, ;
               Sales->SaleAmount
         nTotalAmount += Sales->SaleAmount
         SKIP
      ENDDO
      ? "Total amount: ", nTotalAmount
   ENDDO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Error class⌃ | ☰

Provides objects containing information about runtime errors

Description

An Error object is a simple object that contains information pertaining to a runtime error. Error objects have no methods, only exported instance variables. When a runtime error occurs, CA-Clipper creates a new Error object and passes it as an argument to the error handler block specified with the ErrorBlock() function. Within the error handler, the Error object can then be queried to determine the nature of the error condition.

Error objects can also be returned to the RECOVER statement of a BEGIN SEQUENCE construct with a BREAK statement. Here, the error object can be queried for local error handling. For more detailed information and examples refer to the «Error Handling Strategies» chapter in the Programming and Utilities Guide.

Methods link

ErrorNew() Create a new Error object


ErrorNew() → oError

Returns

ErrorNew() returns a new Error object.

Exported Instance Variables


args An array of function or operator arguments


args (Assignable)

Contains an array of the arguments supplied to an operator or function when an argument error occurs. For other types of errors, Error:args contains a NIL value.

canDefault Indicates if default recovery is available


canDefault (Assignable)

Contains a logical value indicating whether the subsystem can perform default error recovery for the error condition. A value of true (.T.) indicates that default recovery is available. Availability of default handling and the actual default recovery strategy depends on the subsystem and the error condition. The minimum action is simply to ignore the error condition.

Default recovery is requested by returning false (.F.) from the error block invoked to handle the error. Note that Error:canDefault is never true (.T.) if Error:canSubstitute is true (.T.).

canRetry Indicates if a retry is possible after an error


canRetry (Assignable)

Contains a logical value indicating whether the subsystem can retry the operation that caused the error condition. A value of true (.T.) indicates that a retry is possible. Retry may or may not be available, depending on the subsystem and the error condition.

Retry is requested by returning true (.T.) from the error block invoked to handle the error. Note that Error:canRetry never contains true (.T.) if Error:canSubstitute contains true (.T.).

canSubstitute Indicates if a new result can be substituted after an error


canSubstitute (Assignable)

Contains a logical value indicating whether a new result can be substituted for the operation that produced the error condition. Argument errors and certain other simple errors allow the error handler to substitute a new result value for the failed operation. A value of true (.T.) means that substitution is possible.

The substitution is performed by returning the new result value from the code block invoked to handle the error. Note that Error:canSubstitute is never true (.T.) if either Error:canDefault or Error:canRetry is true (.T.).

cargo User-definable variable


cargo (Assignable)

Contains a value of any data type unused by the Error system. It is provided as a user-definable slot, allowing arbitrary information to be attached to an Error object and retrieved later.

description Character description of the error condition


description (Assignable)

Contains a character string that describes the error condition. A zero-length string indicates that the subsystem does not provide a printable description for the error. If Error:genCode is not zero, a printable description is always available.

filename Name of the file associated with the error


filename (Assignable)

Contains a character value representing the name originally used to open the file associated with the error condition. A zero-length string indicates either that the error condition is not associated with a particular file or that the subsystem does not retain file name information.

genCode CA-Clipper error code number


genCode (Assignable)

Contains an integer numeric value representing a CA-Clipper generic error code. Generic error codes allow default handling of similar errors from different subsystems. A value of zero indicates that the error condition is specific to the subsystem and does not correspond to any of the generic error codes. The header file, error.ch, provides a set of manifest constants for generic error codes.

operation Character description of the failed operation


operation (Assignable)

Contains a character string that describes the operation being attempted when the error occurred. For operators and functions, Error:operation contains the name of the operator or function. For undefined variables or functions, it contains the name of the variable or function. A zero-length string indicates that the subsystem does not provide a printable description of the operation.

osCode Operating system error code number


osCode (Assignable)

Contains an integer numeric value representing the operating system error code associated with the error condition. A value of zero indicates that the error condition was not caused by an error from the operating system. When Error:osCode is set to a value other than zero, DosError() is updated with the same value.

Error:osCode properly reflects the DOS extended error code for file errors. This allows proper distinction between errors which result from sharing violations (e.g., opening EXCLUSIVE when another process has already opened the file) and access violations (e.g., opening read/write when the file is marked read-only).

For a list of DOS error codes refer to the Error Messages and Appendices Guide.

severity Indicates error severity


severity (Assignable)

Contains a numeric value indicating the severity of the error condition. Four standard values are defined in error.ch:

Error:severity Values

       Error.ch            Meaning

       ES_WHOCARES         The condition does not represent a failure; the

                           error is informational.

       ES_WARNING          The condition does not prevent further

                           operations, but may result in a more serious

                           error later.

       ES_ERROR            The condition prevents further operations without

                           corrective action of some kind.

       ES_CATASTROPHIC     The condition requires immediate termination of

                           the application.

Note that the CA-Clipper runtime support code only generates errors with severities of ES_WARNING or ES_ERROR.

subCode Subsystem-specific error code number


subCode (Assignable)

Contains an integer numeric value representing a subsystem-specific error code. A value of zero indicates that the subsystem does not assign any particular number to the error condition.

subSystem Character description of the subsystem generating the error


subSystem (Assignable)

Contains a character string representing the name of the subsystem generating the error. For errors with basic CA-Clipper operators and functions, the subsystem name «BASE» is given. For errors generated by a database driver, Error:subSystem contains the name of the database driver.

tries Number of times the failed operation has been attempted


tries (Assignable)

Contains an integer numeric value representing the number of times the failed operation has been attempted. When Error:canRetry is true (.T.), Error:tries can be used to limit the number of retry attempts. A value of zero indicates that the subsystem does not track the number of times the operation has been tried.

Examples

■  This example demonstrates how a file open operation might be
   handled in an error handler replicating the default CA-Clipper
   behavior.  When, for example, an attempt to open a database file with
   a USE command fails, control returns to the statement following the
   offending command:

   #include "Error.ch"
   #command RETRY      => RETURN (.T.)   // Retry operation
   #command RESUME      => RETURN (.F.)   // Default recovery
   //

   FUNCTION MyError( <oError> )
      //
      // Handle file open error
      IF <oError>:genCode == EG_OPEN .AND.;
         <oError>:canDefault .AND.;
         NetErr()
         //
         RESUME
      ENDIF
      .
      . <other error statements>
      .
      RETURN NIL

■  This example retries an operation within an error handler a
   specified number of times:

   #include "Error.ch"
   #command RETRY      => RETURN (.T.)   // Retry operation
   #command RESUME      => RETURN (.F.)   // Default recovery
   //

   FUNCTION MyError( <oError> )
      //
      // Handle printer not ready error
      IF <oError>:genCode == EG_PRINT .AND.;
         <oError>:canRetry .AND.;
         <oError>:tries < 25
         //
         RETRY
      ENDIF
      .
      . <other error statements>
      .
      RETURN NIL

■  This code fragment returns an error object from an error
   handler to the RECOVER statement for further processing:

   LOCAL objLocal, bLastHandler
   //
   // Save current and set new error handler
   bLastHandler := ErrorBlock({    |oErr| ;
                     MyHandler(oErr, .T.)})
   //
   BEGIN SEQUENCE
      .
      . <operation that might fail>
      .
   RECOVER USING objLocal
      .
      . <send messages to objLocal and handle the error>
      .
   END
   //
   // Restore previous error handler
   ErrorBlock( bLastHandler )

   FUNCTION MyHandler( <oError>, lLocalHandler )
      //
      // Handle locally returning the error object
      IF lLocalHandler
         BREAK <oError>
      ENDIF
      .
      . <other statements to handle the error>
      .
      RETURN NIL

Platforms

Available on MS-DOS

File

Header file is error.ch, default error handler is in Errorsys.prg.

See also

ErrorBlock()Harbour implementation


⌃ | ☰

Post a code block to execute when a runtime error occurs

Syntax

ErrorBlock([<bErrorHandler>]) → bCurrentErrorHandler

Arguments

bErrorHandler is the code block to execute whenever a runtime error occurs. When evaluated, the bErrorHandler is passed an error object as an argument by the system.

Returns

ErrorBlock() returns the current error handling code block. If no error handling block has been posted since the program was invoked, ErrorBlock() returns the default error handling block.

Description

ErrorBlock() is an error function that defines an error handler to execute whenever a runtime error occurs. Specify the error handler as a code block with the following form,

{ |oError| expression list,… }

where oError is an error object containing information about the error. Within the code block, messages can be sent to the error object to obtain information about the error. Returning true (.T.) from the error handling block retries the failed operation and false (.F.) resumes processing.

The error handling code block can be specified either as a list of expressions or as a call to a user-defined function. A call to a user- defined function is more useful since you can use CA-Clipper control statements instead of expressions. This is particularly the case if there is a BEGIN SEQUENCE pending and you want to BREAK to the nearest RECOVER statement.

As this implies, error handling blocks can be used in combination with BEGIN SEQUENCE...END control structures. Within an error handling block, you handle device, low-level, and common errors that have a general recovery mechanism. If the operation needs specific error handling, define a BEGIN SEQUENCE then BREAK to the RECOVER statement, returning the error object for local processing. See the example below.

If no bErrorHandler has been specified using ErrorBlock() and a runtime error occurs, the default error handling block is evaluated. This error handler displays a descriptive message to the screen, sets the ErrorLevel() to 1, then QUITs the program.

Since ErrorBlock() returns the current error handling block, it is possible to specify an error handling block for an operation saving the current error handling block, then restore it after the operation has completed. Also, error handlers specified as code blocks, can be passed to procedures and user-defined functions, and RETURNed as values.

For more information on the structure and operations of error objects, refer to the Error class entry in this chapter and the «Error Handling Strategies» chapter in the Programming and Utilities Guide.

Examples

■  This code fragment posts, and then calls an error handling
   block when there is an error within a BEGIN SEQUENCE construct:

   LOCAL bErrorHandler, bLastHandler, objErr
   bErrorHandler := { |oError| ;
         MyErrorHandler(oError) }
   //
   // Save current handler
   bLastHandler := ErrorBlock(bErrorHandler)
   //
   BEGIN SEQUENCE
      .
      . <operation statements>
      .
   // Receive error object from BREAK
   RECOVER USING oErrorInfo
      .
      . <recovery statements>
      .
   END
   ErrorBlock(bLastHandler)      // Restore handler
   RETURN

   FUNCTION MyErrorHandler( oError )
      //
      BREAK oError      // Return error object to RECOVER
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ErrorLevel()Harbour implementation


⌃ | ☰

Set the CA-Clipper return code

Syntax

ErrorLevel([<nNewReturnCode>]) → nCurrentReturnCode

Arguments

nNewReturnCode is the new return code setting. This can be a value between zero and 255. The default value at startup is zero. If not specified, ErrorLevel() reports the current setting without assigning a new value.

Returns

ErrorLevel() returns the current CA-Clipper exit code as a numeric value, if one has been set using ErrorLevel() with an argument; otherwise, it returns zero.

Description

ErrorLevel() is a dual purpose environment function. It returns the current CA-Clipper return code and optionally sets a new return code. The return code is a value set by a child process so the parent process can test the termination state of the child process. Typically, the parent process is DOS and the child process is an application program. Retrieve a return code with the DOS ERRORLEVEL command or INT 21 Function 4Dh.

When a CA-Clipper program terminates, the return code is set to 1 if the process ends with a fatal error. If the process ends normally, the return code is set to zero, or the last ErrorLevel() set in the program.

Typically, you would set a return code with ErrorLevel() to indicate an error state to the program that invoked the current CA-Clipper program. In most cases this is the application batch file. Here you would test the return code using the DOS ERRORLEVEL command. Refer to your DOS manual for more information.

Notes

ErrorLevel() is not updated after a RUN command terminates.

To obtain the return code of the invoked program, you must create an assembler or C routine that queries the child process return code using INT 21 Function 4Dh. Refer to your DOS documentation for more information.

Examples

■  This example saves the current CA-Clipper return code, then
   sets a new value:

   nOldCode := ErrorLevel()      // Get current error level
   ErrorLevel(1)                 // Set new error level

■  This example uses ErrorLevel() to set a return code that can
   be tested by the parent process:

   #define ERR_FILE_MISSING      255
   #define ERR_POST_INCOMPLETE   254
   //
   IF !FILE("Sysfile.dbf")
      @ 0, 0
      @ 1, 0
      @ 0, 0 SAY "Fatal error: System ;
                  file is missing...quitting"
      ErrorLevel(ERR_FILE_MISSING)
      QUIT
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ERASEHarbour implementation⌃ | ☰

Remove a file from disk

Syntax

ERASE | DELETE FILE <xcFile>

Arguments

xcFile is the name of the file to be deleted from disk and can be specified either as a literal file name or as a character expression enclosed in parentheses. The file name must be fully specified including the extension, and it may optionally be preceded by a drive and/or path specification.

Description

ERASE is a file command that removes a specified file from disk. SET DEFAULT and SET PATH do not affect ERASE. The file is deleted from disk only if found in the current DOS directory or in the directory explicitly specified as part of the file name.

Warning! Files must be CLOSEd before being ERASEd. Otherwise, either a sharing violation or a date corruption on the drive may occur.

Examples

■  This example removes a specified file from disk and then tests
   to see if the file was in fact removed:

   ? FILE("Temp.dbf")         // Result: .T.
   ERASE Temp.dbf
   ? FILE("Temp.dbf")         // Result: .F.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Eval()Harbour implementation


⌃ | ☰

Evaluate a code block

Syntax

Eval(<bBlock>, [<BlockArg list>]) → LastBlockValue

Arguments

bBlock is the code block to be evaluated.

BlockArg list is a list of arguments to send to the code block before it is evaluated.

Returns

Eval() returns the value of the last expression within the block. A code block can return a value of any type.

Description

Eval() is a code block function. It is the most basic code block evaluation facility in the CA-Clipper system. A code block is a special data value that refers to a piece of compiled program code. For more information on code blocks, refer to the «Basic Concepts» chapter in the Programming and Utilities Guide.

To execute or evaluate a code block, call Eval() with the block value and any parameters. The parameters are supplied to the block when it is executed. Code blocks may be a series of expressions separated by commas. When a code block is evaluated, the returned value is the value of the last expression in the block.

The CA-Clipper compiler usually compiles a code block at compile time. There are, however, occasions at runtime when you may need to compile a code block from a character string. You can do this by using the macro operator (&).

Eval() is often used to create iteration functions. These are functions that apply a block to each member of a data structure. AEval(), ASort(), AScan(), and dbEval() are iteration functions (e.g., AEval() applies a block to each element within an array).

Examples

■  This example creates a code block that increments a number,
   and then evaluates it:

   bBlock := { |nArg| nArg + 1 }
   ? Eval(bBlock, 1)                     // Result: 2

■  This example demonstrates compiling a code block at runtime
   using the macro operator (&):

   // Compile a string to a block
   bBlock := &("{ |nArg| nArg + 1 }")

   // Evaluate the block
   ? Eval(bBlock, 1)                     // Result: 2

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Exp()Harbour implementation


⌃ | ☰

Calculate e**x

Syntax

Exp(<nExponent>) → nAntilogarithm

Arguments

nExponent is the natural logarithm for which a numeric value is to be calculated.

Returns

Exp() returns a numeric value that is equivalent to the value e raised to the specified power.

Description

Exp() is a mathematical function that calculates the value, y, (the antilogarithm) of the following equation,

e**x = y

where e is the base of natural logarithms (2.71828…) and x is nExponent. The maximum value of nExponent is 45 before a numeric overflow occurs. Exp() and Log() are inverse functions.

The number of decimal places displayed is determined solely by SET DECIMALS regardless of the current SET FIXED value.

Examples

■  This example demonstrates several invocations of Exp():

   ? Exp(1)                       // Result: 2.72
   SET DECIMALS TO 10
   ? Exp(1)                       // Result: 2.7182818285
   ? Log(Exp(1))                  // Result: 1.0000000000

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

EXIT PROCEDUREHarbour implementation⌃ | ☰

Declare an exit procedure

Syntax

EXIT PROCEDURE <idProcedure>
   [FIELD <idField list> [IN <idAlias>]]
   [LOCAL <identifier> [[:= <initializer>]]]
   [MEMVAR <identifer list>]
   .
   . <executable statements>
   .
   [RETURN]

Arguments

EXIT PROCEDURE declares a procedure that will be executed on program termination.

idProcedure is the name of the exit procedure to declare. Exit procedure names can be any length, but only the first 10 characters are significant. Names may not begin with an underscore but can contain any combination of characters, numbers, or underscores.

FIELD declares a list of identifiers to use as field names whenever encountered. If the IN clause is specified, referring to the declared name includes an implicit reference to the specified alias.

LOCAL declares and optionally initializes a list of variables or arrays whose visibility and lifetime is the current procedure.

MEMVAR declares a list of identifiers to use as private or public memory variables or arrays whenever encountered.

RETURN passes control to the next exit procedure or to the operating system, if no other exit procedures are pending.

Description

The EXIT PROCEDURE statement declares a procedure that will be executed upon program termination. EXIT procedures are called after the last executable statement in a CA-Clipper application has completed. EXIT PROCEDUREs can be used to perform common housekeeping tasks such as saving configuration settings to a file, closing a log file, or concluding a communications session.

The visibility of exit procedures is restricted to the system; therefore, it is not possible to call an EXIT PROCEDURE from a procedure or user-defined function. Exit procedures do not receive parameters.

Once the last executable statement has completed, control passes from one EXIT PROCEDURE to the next until all procedures in the exit list have been called. Control then passes to the operating system.

The ANNOUNCE statement declares a module identifier for a source (.prg) file. Once declared, EXIT PROCEDUREs are referenced with this module identifier. An application may use any number of exit procedures by explicitly REQUESTing their module identifiers.

The EXIT PROCEDUREs requested for an application are collectively referred to as the exit list. There is no mandatory execution order of procedures in the exit list; however, if an EXIT PROCEDURE is declared in the same source (.prg) file as the application’s primary routine (root), it is guaranteed to be the first exit procedure called.

Termination of a given CA-Clipper application can be attributed to any of the following:

RETURNing from the primary (root) routine

■ the QUIT command

■ issuing a BREAK without an enclosing BEGIN SEQUENCE...END

■ unrecoverable error

Execution of an EXIT PROCEDURE cannot be guaranteed when the system encounters an unrecoverable error. If an error is raised during an exit procedure, the system returns to DOS. Pending exit procedures are not called.

Examples

■  This example illustrates construction of a simple timing
   mechanism using INIT and EXIT PROCEDUREs:

   // prints the amount of time required to read,
   // sort, and display a list of file names.

   ANNOUNCE MySystem

   STATIC nStart

   PROCEDURE Main()
      AEval( ASort( Directory( "*.*" ) ),;
         { | aFileInfo | QOut( aFileInfo[ 1 ] ) } )
      RETURN

   INIT PROCEDURE MyInit()
      nStart := Seconds()
      RETURN

   EXIT PROCEDURE MyExit()
      ?
      ? "Elapsed Time: "
      ?? Seconds() - nStart
      RETURN

Platforms

Available on MS-DOS

See also

EXTERNAL*⌃ | ☰

Declare a list of procedure or user-defined function names to the linker

Syntax

EXTERNAL <idProcedure list>

Arguments

idProcedure list is the list of procedures, user-defined functions, or format procedures to add to the list of routines that will be linked into the current executable (.EXE) file.

Description

EXTERNAL is a declaration statement that specifies uncoded references to the linker. Like all other declaration statements, an EXTERNAL statement must be specified before any executable statements in either the program file, or a procedure or user-defined function definition.

During the compilation of CA-Clipper source code, all explicit references to procedures and user-defined functions are made to the linker. In some instances, there may be no references made to procedure or user-defined function names until runtime. EXTERNAL resolves this by forcing the named procedures or user-defined functions to be linked even if they are not explicitly referenced in the source file. This is important in several instances:

■ Procedures, user-defined functions, or formats referenced with

macro expressions or variables

■ Procedures and user-defined functions used in REPORT and LABEL

FORMs and not referenced in the source code

■ User-defined functions used in index keys and not referenced

in the source code

AChoice(), dbEdit(), or MemoEdit() user functions

To group common EXTERNAL declarations together, place them in a header file and then include (#include) the header file into each program (.prg) file that might indirectly use them.

EXTERNAL is a compatibility statement and therefore not recommended. It is superseded by the REQUEST statement that defines a list of module identifiers to the linker.

Examples

■  These examples are equivalent header files consisting of
   common EXTERNAL references for REPORT FORMs:

   // Externals.ch
   EXTERNAL HardCR
   EXTERNAL Tone
   EXTERNAL MemoTran
   EXTERNAL StrTran

   // Externals.ch
   EXTERNAL HardCR, TONE, MEMOTRAN, STRTRAN

Platforms

Available on MS-DOS

See also

FClose()Harbour implementation


⌃ | ☰

Close an open binary file and write DOS buffers to disk

Syntax

FClose(<nHandle>) → lError

Arguments

nHandle is the file handle obtained previously from FOpen() or FCreate().

Returns

FClose() returns false (.F.) if an error occurs while writing; otherwise, it returns true (.T.).

Description

FClose() is a low-level file function that closes binary files and forces the associated DOS buffers to be written to disk. If the operation fails, FClose() returns false (.F.). FError() can then be used to determine the reason for the failure. For example, attempting to use FClose() with an invalid handle returns false (.F.), and FError() returns DOS error 6, invalid handle. See FError() for a complete list of error numbers.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples

■  This example uses FClose() to close a newly created binary
   file and displays an error message if the close fails:

   #include "Fileio.ch"
   //
   nHandle := FCreate("Testfile", FC_NORMAL)
   IF !FClose(nHandle)
      ? "Error closing file, error number: ", FError()
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FCount()Harbour implementation


⌃ | ☰

Return the number of fields in the current .dbf file

Syntax

Returns

FCount() returns the number of fields in the database file in the current work area as an integer numeric value. If there is no database file open, FCount() returns zero.

Description

FCount() is a database function. It is useful in applications containing data-independent programs that can operate on any database file. These include generalized import/export and reporting programs. Typically, you use FCount() to establish the upper limit of a FOR...NEXT or DO WHILE loop that processes a single field at a time.

By default, FCount() operates on the currently selected work area.

Examples

■  This example illustrates FCount(), returning the number of
   fields in the current and an unselected work area:

   USE Sales NEW
   USE Customer NEW
   ? FCount()                     // Result: 5
   ? Sales->(FCount())            // Result: 8

■  This example uses FCount() to DECLARE an array with field
   information:

   LOCAL aFields := Array(FCount())
   AFields(aFields)

■  This example uses FCount() as the upper boundary of a FOR loop
   that processes the list of current work area fields:

   LOCAL nField
   USE Sales NEW
   FOR nField := 1 TO FCount()
      ? Field(nField)
   NEXT

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FCreate()Harbour implementation


⌃ | ☰

Create and/or truncate a binary file to zero-length

Syntax

FCreate(<cFile>, [<nAttribute>]) → nHandle

Arguments

cFile is the name of the file to create. If the file already exists, its length is truncated to zero without warning.

nAttribute is one of the binary file attributes shown in the table below. If this argument is omitted, the default value is zero.

Binary File Attributes

    Value   Fileio.ch      Attribute Description

    0       FC_NORMAL      Normal    Create normal read/write file (default)

    1       FC_READONLY    Read-only Create read-only file

    2       FC_HIDDEN      Hidden    Create hidden file

    4       FC_SYSTEM      System    Create system file

Returns

FCreate() returns the DOS file handle number of the new binary file in the range of zero to 65,535. If an error occurs, FCreate() returns -1 and FError() is set to indicate an error code.

Description

FCreate() is a low-level file function that either creates a new file or opens and truncates an existing file. If cFile does not exist, it is created and opened for writing. If it does exist and can be opened for writing, it is truncated to zero-length. If it cannot be opened for writing, FCreate() returns -1 and FError() returns the appropriate error value.

When FCreate() successfully creates a new file, the file is left open in compatibility sharing mode and read/write access mode. The file attribute specified by the nAttribute argument is applied to the new file when it is closed, allowing writing to a newly created read-only file. For a list of access modes, see FOpen().

Since a file handle is required in order to identify an open file to other file functions, always assign the return value from FCreate() to a variable for later use.

Like other file functions, FCreate() does not use either the DEFAULT or PATH settings for its operation. Instead, it writes to the current DOS directory unless a path is explicitly stated.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples

■  This example creates a file called Testfile and opens it for
   reading and writing:

   #include "Fileio.ch"

   //
   IF (nHandle := FCreate("Testfile", FC_NORMAL)) == -1
      ? "File cannot be created:", FError()
      BREAK
   ELSE
      FWrite(nHandle, "Hello there")
      FClose(nHandle)
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is fileio.ch.

See also

FErase()Harbour implementation


⌃ | ☰

Delete a file from disk

Syntax

FErase(<cFile>) → nSuccess

Arguments

cFile is the name of the file to be deleted from disk, including extension, optionally preceded by a drive and/or path specification.

Returns

FErase() returns -1 if the operation fails and zero if it succeeds. In the case of a failure, FError() can be used to determine the nature of the error.

Description

FErase() is a file function that deletes a specified file from disk. FErase() is the same as the ERASE command but returns a value and can be specified within an expression. When FErase() is called, cFile is deleted from disk only if found in the current DOS directory or in the directory explicitly specified as part of the file name. Like the other file functions and commands, FErase() does not use either SET DEFAULT or SET PATH to locate cFile.

Warning! Files must be CLOSEd before removing them with FErase().

Examples

■  This example deletes a set of files matching a wildcard
   pattern:

   #include "Directry.ch"
   AEval(Directory("*.BAK"), { |aFile| ;
      FErase(aFile[F_NAME]) })

■  This example erases a file and displays a message if the
   operation fails:

   IF FErase("AFile.txt") == -1
      ? "File erase error:", FError()
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FError()Harbour implementation


⌃ | ☰

Test for errors after a binary file operation

Syntax

Returns

FError() returns the DOS error from the last file operation as an integer numeric value. If there is no error, FError() returns zero.

FError() Return Values

    Error   Meaning

    0       Successful

    2       File not found

    3       Path not found

    4       Too many files open

    5       Access denied

    6       Invalid handle

    8       Insufficient memory

    15      Invalid drive specified

    19      Attempted to write to a write-protected disk

    21      Drive not ready

    23      Data CRC error

    29      Write fault

    30      Read fault

    32      Sharing violation

    33      Lock Violation

Description

FError() is a low-level file function that indicates a DOS error after a file function is used. These functions include FClose(), FCreate(), FErase(), FOpen(), FRead(), FReadStr(), and FRename(). FError() retains its value until the next execution of a file function.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples

■  This example tests FError() after the creation of a binary
   file and displays an error message if the create fails:

   #include "Fileio.ch"
   //
   nHandle := FCreate("Temp.txt", FC_NORMAL)
   IF FError() != 0
      ? "Cannot create file, DOS error ", FError()
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FieldBlock()Harbour implementation


⌃ | ☰

Return a set-get code block for a given field

Syntax

FieldBlock(<cFieldName>) → bFieldBlock

Arguments

cFieldName is the name of the field to which the set-get block will refer.

Returns

FieldBlock() returns a code block that, when evaluated, sets (assigns) or gets (retrieves) the value of the given field. If cFieldName does not exist in the specified work area, FieldBlock() returns an empty block.

Description

FieldBlock() is a database function that builds a code block. When executed with an argument, the code block created by this function assigns the value of the argument to cFieldName. When executed without an argument, the code block retrieves the value of cFieldName.

Note that the specified field variable may not exist when the code block is created, but must exist before the code block is executed.

Notes

■ Work area: The code block returned by FieldBlock() sets or

gets the value of the specified field in whatever work area is current when the block is run. For example, given work areas 1 and 2, both containing field FName:

SELECT 1

FName:= «Kate» SELECT 2

FName := «Cindy» bFName := FieldBlock(«FName») SELECT 1 ? Eval(bFName) // Result: «Kate» SELECT 2 ? Eval(bFName) // Result: «Cindy»

The function FieldWBlock() provides a set-get block for a field in a specific work area.

Examples

■  This example compares FieldBlock() to a code block created
   using the macro operator.  Note that using FieldBlock() avoids the
   speed and size overhead of the macro operator:

   // Set-Get block defined using macro operator
   bSetGet := &( "{ |setVal| IF( setVal == NIL,;
                   FName, FName := setVal ) }" )
   // Set-Get block defined using FieldBlock()

   // bSetGet created here is the functional
   // equivalent of bSetGet above
   bSetGet := FieldBlock("FName")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FieldGet()Harbour implementation


⌃ | ☰

Retrieve the value of a field using the ordinal position of the field in the database structure

Syntax

FieldGet(<nField>) → ValueField

Arguments

nField is the ordinal position of the field in the record structure for the current work area.

Returns

FieldGet() returns the value of the specified field. If nField does not correspond to the position of any field in the current database file, FieldGet() returns NIL.

Description

FieldGet() is a database function that retrieves the value of a field using its position within the database file structure rather than its field name. Within generic database service functions this allows, among other things the retrieval of field values without use of the macro operator.

Examples

■  This example compares FieldGet() to functionally equivalent
   code that uses the macro operator to retrieve the value of a field:

   LOCAL nField := 1, FName, FVal
   USE Customer NEW
   //
   // Using macro operator
   FName := Field( nField )           // Get field name
   FVal := &FName                     // Get field value
   // Using FieldGet()
   FVal := FieldGet( nField )         // Get field value

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FieldName()/Field()


⌃ | ☰

Return a field name from the current database (.dbf) file

Syntax

FIELDNAME/Field(<nPosition>) → cFieldName

Arguments

nPosition is the position of a field in the database file structure.

Returns

FieldName() returns the name of the specified field as a character string. If nPosition does not correspond to an existing field in the current database file or if no database file is open in the current work area, FieldName() returns a null string («»).

Description

FieldName() is a database function that returns a field name using an index to the position of the field name in the database structure. Use it in data-independent applications where the field name is unknown. If information for more than one field is required, use AFields() to create an array of field information or COPY STRUCTURE EXTENDED to create a database of field information.

If you need additional database file structure information, use Type() and Len(). To obtain the number of decimal places for a numeric field, use the following expression:

Len(SubStr(Str(idField), RAt(«.», ;

Str(idField)) + 1))

By default, FieldName() operates on the currently selected work area as shown in the example below.

Examples

■  These examples illustrate FieldName() used with several other
   functions:

   USE Sales
   ? FieldName(1)              // Result: BRANCH
   ? FCount()                  // Result: 5
   ? Len(FieldName(0))         // Result: 0
   ? Len(FieldName(40))        // Result: 0

■  This example uses FieldName() to list the name and type of
   each field in Customer.dbf:

   USE Customer NEW
   FOR nField := 1 TO FCount()
      ? PadR(FieldName(nField), 10),;
             ValType(&(FieldName(nField)))
   NEXT

■  This example accesses fields in unselected work areas using
   aliased expressions:

   USE Sales NEW
   USE Customer NEW
   USE Invoices NEW
   //
   ? Sales->(FieldName(1))            // Result: SALENUM
   ? Customer->(FieldName(1))         // Result: CUSTNUM

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FieldPos()Harbour implementation


⌃ | ☰

Return the position of a field in a work area

Syntax

FieldPos(<cFieldName>) → nFieldPos

Arguments

cFieldName is the name of a field in the current or specified work area.

Returns

FieldPos() returns the position of the specified field within the list of fields associated with the current or specified work area. If the current work area has no field with the specified name, FieldPos() returns zero.

Description

FieldPos() is a database function that is the inverse of the FieldName() function. FieldPos() is most often used with the FieldPut() and FieldGet() functions.

FieldPos() return the names of fields in any unselected work area by referring to the function using an aliased expression. See the example below.

Examples

■  This example demonstrates a typical specification of the
   FieldPos() function:

   USE Customer NEW
   ? FieldPos("Name")                     // Result: 1
   ? FieldGet(FieldPos("Name"))           // Result: Kate

■  This example uses FieldPos() to return the position of a
   specified field in a unselected work area:

   USE Customer NEW
   USE Invoices NEW
   ? Customer->(FieldPos("Name"))         // Result: 1
   ? Customer->(FieldGet(FieldPos("Name")))
                                          // Result: Kate

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FieldPut()Harbour implementation


⌃ | ☰

Set the value of a field variable using the ordinal position of the field in the database structure

Syntax

FieldPut(<nField>, <expAssign>) → ValueAssigned

Arguments

nField is the ordinal position of the field in the current database file.

expAssign is the value to assign to the given field. The data type of this expression must match the data type of the designated field variable.

Returns

FieldPut() returns the value assigned to the designated field. If nField does not correspond to the position of any field in the current database file, FieldPut() returns NIL.

Description

FieldPut() is a database function that assigns expAssign to the field at ordinal position nField in the current work area. This function allows you to set the value of a field using its position within the database file structure rather than its field name. Within generic database service functions this allows, among other things, the setting of field values without use of the macro operator.

Examples

■  This example compares FieldPut() to functionally equivalent
   code that uses the macro operator to set the value of a field:

   // Using macro operator
   FName := Field(nField)           // Get field name
   FIELD->&FName := FVal            // Set field value
   // Using FieldPut()
   FieldPut(nField, FVal)           // Set field value

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FieldWBlock()Harbour implementation


⌃ | ☰

Return a set-get code block for a field in a given work area

Syntax

FieldWBlock(<cFieldName>, <nWorkArea>)
   → bFieldWBlock

Arguments

cFieldName is the name of the field specified as a character string.

nWorkArea is the work area number where the field resides specified as a numeric value.

Returns

FieldWBlock() returns a code block that, when evaluated, sets (assigns) or gets (retrieves) the value of cFieldName in the work area designated by nWorkArea. If cFieldName does not exist in the specified work area, FieldWBlock() returns an empty block.

Description

FieldWBlock() is a database function that builds a code block. When evaluated with the Eval() function, the code block first selects the designated nWorkArea. If an argument was passed, the code block then assigns the value of the argument to cFieldName. If no argument was passed, the code block retrieves the value of cFieldName. The original work area is then reselected before the code block returns control.

Note that the specified field variable may not exist when the code block is created but must exist before the code block is executed.

Notes

FieldWBlock() is similar to FieldBlock(), except that

FieldBlock() incorporates a fixed work area into the set-get block.

Examples

■  This example compares FieldWBlock() to a code block created
   using the macro operator.  Note that using FieldWBlock() avoids the
   speed and size overhead of the macro operator:

   // Set-Get block for work area 1 defined with
   // macro operator
   bSetGet := &( "{ |setVal| IF( setVal == NIL, ;
      1->FName, 1->FName := setVal ) }" )
   // Set-Get block defined using FieldWBlock()

   // bSetGet created here is the functional
   // equivalent of bSetGet above
   bSetGet := FieldWBlock("FName", 1)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FIELD⌃ | ☰

Declare database field names

Syntax

FIELD <idField list> [IN <idAlias>]

Arguments

idField list is a list of names to declare as fields to the compiler.

IN idAlias specifies an alias to assume when there are unaliased references to the names specified in the idField list. Unaliased references to variables in idField list are treated as if they are preceded by the special field alias (FIELD->).

Description

The FIELD statement declares the names of database fields to the compiler, and optionally supplies an implicit alias for each name. This allows the compiler to resolve references to variables with no explicit alias—by implicitly assuming the specified idAlias. Only explicit, unaliased references to the specified fields in the idField list are affected. The FIELD statement, like all declarations, has no effect on references made within macro expressions or variables.

The FIELD statement neither opens a database file nor verifies the existence of the specified fields. It is useful primarily to ensure correct references to fields whose accessibility is known at runtime. Attempting to access the fields when the associated database is not in USE will cause an error.

The scope of the FIELD declaration is the procedure or function in which it occurs, or the entire program (.prg) file if the declaration precedes all PROCEDURE or FUNCTION declarations and the /N compiler option is specified.

FIELD statements, like other declarations, must precede any executable statements in the procedure or function definition or the program (.prg) file if the declaration has filewide scope.

FIELD used with the /W compiler option performs compile-time checking for undeclared variables.

For more information on variable declarations and scoping, refer to the Variables section in the «Basic Concepts» chapter of the Programming and Utilities Guide.

Examples

■  This user-defined function includes statements to declare
   database field names in both the current and Employee work areas:

   FUNCTION DisplayRecord
      FIELD CustNo, OrderNo, Salesman
      FIELD EmpName, EmpCode IN Employee
      USE Employee NEW
      USE Orders NEW
      //
      ? CustNo               // Refers to Orders->CustNo
      ? EmpName              // Refers to Employee->EmpName
      //
      CLOSE Orders
      CLOSE Employee
      RETURN NIL

Platforms

Available on MS-DOS

See also

FILE()Harbour implementation


⌃ | ☰

Determine if files exist in the CA-Clipper default directory or path

Syntax

FILE(<cFilespec>) → lExists

Arguments

cFilespec is in the current CA-Clipper default directory and path. It is a standard file specification that can include the wildcard characters * and ? as well as a drive and path reference. Explicit references to a file must also include an extension.

Returns

File() returns true (.T.) if there is a match for any file matching the cFilespec pattern; otherwise, it returns false (.F.).

Description

File() is an environment function that determines whether any file matching a file specification pattern is found. File() searches the specified directory if a path is explicitly specified.

If a path is not specified, File() searches the current CA-Clipper default directory and then the CA-Clipper path. In no case is the DOS path searched. Note also that File() does not recognize hidden or system files in its search.

Examples

■  In this example FILE() attempts to find Sales.dbf in other
   than the current CA-Clipper default:

   ? FILE("Sales.dbf")               // Result: .F.
   ? FILE("APPSDBFSales.dbf")     // Result: .T.
   //
   SET PATH TO APPSDBF
   ? FILE("Sales.dbf")               // Result: .T.
   //
   SET PATH TO
   SET DEFAULT TO APPSDBF
   ? FILE("Sales.dbf")               // Result: .T.
   ? FILE("*.dbf")                   // Result: .T.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FIND*Harbour implementation⌃ | ☰

Search an index for a specified key value

Syntax

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

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FKLabel()*Harbour implementation


⌃ | ☰

Return function key name

Syntax

FKLabel(<nFunctionKey>) → cKeyLabel

Returns

FKLabel() returns a character string representing the name of the function key specified by the numeric argument, nFunctionKey. If this argument is less than one or greater than 40, the function returns a null («») string.

Description

FKLabel() is a compatibility function used to replicate the FKLabel() function in dBASE III PLUS. As a general principle, the use of this function is not recommended and not needed in CA-Clipper. The function keys are labeled Fn, where n ranges from one to 40 and corresponds directly to the FKLabel() argument.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/FKLABEL.PRG.

See also

FKMax()*Harbour implementation


⌃ | ☰

Return number of function keys as a constant

Syntax

Description

FKMax() is a compatibility function used to replicate the FKMax() function in dBASE III PLUS. As a general principle, the use of this function is not recommended and not needed in CA-Clipper. It simply returns a constant value of 40.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/FKMAX.PRG.

See also

FLock()Harbour implementation


⌃ | ☰

Lock an open and shared database file

Syntax

Returns

FLock() returns true (.T.) if an attempt to lock a database file in USE in the current work area succeeds; otherwise, it returns false (.F.). For more information on file locking, refer to the «Network Programming» chapter in the Programming and Utilities Guide.

Description

FLock() is a database function used in network environments to lock an open and shared database file, preventing other users from updating the file until the lock is released. Records in the locked file are accessible for read-only operations.

FLock() is related to USE...EXCLUSIVE and RLock(). USE...EXCLUSIVE opens a database file so that no other user can open the same file at the same time and is the most restrictive locking mechanism in CA-Clipper. RLock() is the least restrictive and attempts to place an update lock on a shared record, precluding other users from updating the current record. FLock() falls in the middle.

FLock() is used for operations that access the entire database file. Typically, these are commands that update the file with a scope or a condition such as DELETE or REPLACE ALL. The following is a list of such commands:

Commands that require an FLock()

    Command                       Mode

    APPEND FROM                   FLock() or USE…EXCLUSIVE

    DELETE (multiple records)     FLock() or USE…EXCLUSIVE

    RECALL (multiple records)     FLock() or USE…EXCLUSIVE

    REPLACE (multiple records)    FLock() or USE…EXCLUSIVE

    UPDATE ON                     FLock() or USE…EXCLUSIVE

For each invocation of FLock(), there is one attempt to lock the database file, and the result is returned as a logical value. A file lock fails if another user currently has a file or record lock for the same database file or EXCLUSIVE USE of the database file. If FLock() is successful, the file lock remains in place until you UNLOCK, CLOSE the DATABASE, or RLock().

By default, FLock() operates on the currently selected work area as shown in the example below.

Notes

SET RELATION: CA-Clipper does not automatically lock all work

areas in the relation chain when you lock the current work area, and an UNLOCK has no effect on related work areas.

Examples

■  This example uses FLock() for a batch update of prices in
   Inventory.dbf:

   USE Inventory NEW
   IF FLock()
      REPLACE ALL Inventory->Price WITH ;
            Inventory->Price * 1.1
   ELSE
      ? "File not available"
   ENDIF

■  This example uses an aliased expression to attempt a file lock
   in an unselected work area:

   USE Sales NEW
   USE Customer NEW
   //
   IF !Sales->(FLock())
      ? "Sales is in use by another"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Found()Harbour implementation


⌃ | ☰

Determine if the previous search operation succeeded

Syntax

Returns

Found() returns true (.T.) if the last search command was successful; otherwise, it returns false (.F.).

Description

Found() is a database function that determines whether a search operation (i.e., FIND, LOCATE, CONTINUE, SEEK, or SET RELATION) succeeded. When any of these commands are executed, Found() is set to true (.T.) if there is a match; otherwise, it is set to false (.F.).

If the search command is LOCATE or CONTINUE, a match is the next record meeting the scope and condition. If the search command is FIND, SEEK or SET RELATION, a match is the first key in the controlling index that equals the search argument. If the key value equals the search argument, Found() is true (.T.); otherwise, it is false (.F.).

The value of Found() is retained until another record movement command is executed. Unless the command is another search command, Found() is automatically set to false (.F.).

Each work area has a Found() value. This means that if one work area has a RELATION set to a child work area, querying Found() in the child returns true (.T.) if there is a match.

By default, Found() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression (see example below).

Found() will return false (.F.) if there is no database open in the current work area.

Examples

■  This example illustrates the behavior of Found() after a
   record movement command:

   USE Sales INDEX Sales
   ? IndexKey(0)              // Result: SALESMAN
   SEEK "1000"
   ? Found()                  // Result: .F.
   SEEK "100"
   ? Found()                  // Result: .T.
   SKIP
   ? Found()                  // Result: .F.

■  This example tests a Found() value in an unselected work area
   using an aliased expression:

   USE Sales INDEX Sales NEW
   USE Customer INDEX Customer NEW
   SET RELATION TO CustNum INTO Sales
   //
   SEEK "Smith"
   ? Found(), Sales->(Found())

■  This code fragment processes all Customer records with the key
   value "Smith" using Found() to determine when the key value changes:

   USE Customer INDEX Customer NEW
   SEEK "Smith"
   DO WHILE Found()
      .

      . <statements>
      .
      SKIP
      LOCATE REST WHILE Name == "Smith"
   ENDDO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FOpen()Harbour implementation


⌃ | ☰

Open a binary file

Syntax

FOpen(<cFile>, [<nMode>]) → nHandle

Arguments

cFile is the name of the file to open, including the path if there is one.

nMode is the requested DOS open mode indicating how the opened file is to be accessed. The open mode is composed of elements from the two types of modes described in the tables below. If just the Access Mode is used, the file is opened non-sharable. The default open mode is zero, which indicates non-sharable and read-only.

FOpen() Access Modes

    Mode    Fileio.ch      Operation

    0       FO_READ        Open for reading (default)

    1       FO_WRITE       Open for writing

    2       FO_READWRITE   Open for reading or writing

The Sharing Modes determine how other processes may access the file.

FOpen() Sharing Modes

    Mode    Fileio.ch      Operation

    0       FO_COMPAT      Compatibility mode (default)

    16      FO_EXCLUSIVE   Exclusive use

    32      FO_DENYWRITE   Prevent others from writing

    48      FO_DENYREAD    Prevent others from reading

    64      FO_DENYNONE    Allow others to read or write

    64      FO_SHARED      Same as FO_DENYNONE

The Access Modes in combination (+) with the Sharing modes determine the accessibility of the file in a network environment.

Returns

FOpen() returns the file handle of the opened file in the range of zero to 65,535. If an error occurs, FOpen() returns -1.

Description

FOpen() is a low-level file function that opens an existing binary file for reading and writing, depending on the nMode argument. Whenever there is an open error, use FError() to return the DOS error number. For example, if the file does not exist, FOpen() returns -1 and FError() returns 2 to indicate that the file was not found. See FError() for a complete list of error numbers.

If the specified file is opened successfully, the value returned is the DOS handle for the file. This value is similar to an alias in the database system and is required to identify the open file to other file functions. It is, therefore, important to assign the return value to a variable for later use as in the example below.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Notes

■ Accessing files in other directories: FOpen() does not obey

either SET DEFAULT or SET PATH. Instead, it searches the current DOS directory and path setting unless a path is explicitly stated as part of the cFile argument.

Examples

■  This example uses FOpen() to open a file with  sharable
   read/write status and displays an error message if the open fails:

   #include "Fileio.ch"
   //
   nHandle := FOpen("Temp.txt", FO_READWRITE + FO_SHARED)
   IF FError() != 0
      ? "Cannot open file, DOS error ", FError()
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is fileio.ch.

See also

FOR⌃ | ☰

Execute a block of statements a specified number of times

Syntax

FOR <idCounter> := <nStart> TO <nEnd>
   [STEP <nIncrement>]
   <statements>...
   [EXIT]
   <statements>...
   [LOOP]
NEXT

Arguments

idCounter is the name of the loop control or counter variable. If the specified idCounter is not visible or does not exist, a private variable is created.

nStart is the initial value assigned to idCounter. If nIncrement is negative, nStart must be less than nEnd.

TO nEnd defines the final value of idCounter. If nIncrement is negative, nStart must be greater than nEnd; otherwise, nStart must be less than nEnd.

STEP nIncrement defines the amount idCounter is changed for each iteration of the loop. nIncrement can be either positive or negative. If the STEP clause is not specified, idCounter is incremented by one for each iteration of the loop.

EXIT unconditionally branches control from within a FOR...NEXT construct to the statement immediately following the nearest NEXT statement.

LOOP branches control to the most recently executed FOR or DO WHILE statement.

Description

FOR...NEXT is a control structure that executes a block of statements a specified number of times. The control structure loops from the initial value of idCounter to the boundary specified by nEnd, moving through the range of values of the control variable for an increment specified by nIncrement. All expressions in the FOR statement are reevaluated for each iteration of the loop. The nStart and nEnd expressions, therefore, can be changed as the control structure operates.

A FOR loop operates until idCounter is greater than nEnd or an EXIT statement is encountered. Control then branches to the statement following the corresponding NEXT statement. If a LOOP statement is encountered, control branches back to the current FOR statement.

If nIncrement is a negative value, idCounter is decremented rather than incremented. The FOR loop, however, continues until idCounter is less than nEnd. This means that nEnd must be less than nStart when the FOR loop begins.

FOR loops are useful for traversing arrays where idCounter is used as the array subscript. See the example below.

FOR...NEXT constructs may be nested within any other control structures to any depth. The only requirement is that each control structure is properly nested.

Examples

■  This example traverses an array in ascending order:

   nLenArray := Len(aArray)
   FOR i := 1 TO nLenArray
      <statements>...
   NEXT

■  To traverse an array in descending order:

   nLenArray := Len(aArray)
   FOR i := nLenArray TO 1 STEP -1
      <statements>...
   NEXT

Platforms

Available on MS-DOS

See also

FRead()Harbour implementation


⌃ | ☰

Read characters from a binary file into a buffer variable

Syntax

FRead(<nHandle>, @<cBufferVar>, <nBytes>) → nBytes

Arguments

nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.

cBufferVar is the name of an existing and initialized character variable used to store data read from the specified file. The length of this variable must be greater than or equal to nBytes. cBufferVar must be passed by reference and, therefore, must be prefaced by the pass- by-reference operator (@).

nBytes is the number of bytes to read into the buffer.

Returns

FRead() returns the number of bytes successfully read as an integer numeric value. A return value less than nBytes or zero indicates end of file or some other read error.

Description

FRead() is a low-level file function that reads characters from a binary file into an existing character variable. It reads from the file starting at the current DOS file pointer position, advancing the file pointer by the number of bytes read. All characters are read including control, null, and high-order (above Chr(127)) characters.

FRead() is similar in some respects to both FReadStr() and FSeek(). FReadStr() reads a specified number of bytes from a file up to the next null (Chr(0)) character. FSeek() moves the file pointer without reading.

If there is an error during the file read, FError() returns the DOS error number. See FError() for the list of error numbers.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples

■  This example uses FRead() after successfully opening a file to
   read 128 bytes into a buffer area:

   #define F_BLOCK      128
   //
   cBuffer := Space(F_BLOCK)
   nHandle := FOpen("Temp.txt")
   //
   IF FError() != 0
      ? "File open error:", FError()
   ELSE
      IF FRead(nHandle, @cBuffer, F_BLOCK) <> F_BLOCK
         ? "Error reading Temp.txt"
      ENDIF
      FClose(nHandle)
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FReadStr()Harbour implementation


⌃ | ☰

Read characters from a binary file

Syntax

FReadStr(<nHandle>, <nBytes>) → cString

Arguments

nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.

nBytes is the number of bytes to read, beginning at the current DOS file pointer position.

Returns

FReadStr() returns a character string up to 65,535 (64K) bytes. A null return value («») indicates an error or end of file.

Description

FReadStr() is a low-level file function that reads characters from an open binary file beginning with the current DOS file pointer position. Characters are read up to nBytes or until a null character (Chr(0)) is encountered. All characters are read including control characters except for Chr(0). The file pointer is then moved forward nBytes. If nBytes is greater than the number of bytes from the pointer position to the end of the file, the file pointer is positioned to the last byte in the file.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples

■  This example displays the ASCII values of the first 16 bytes
   of a text file:

   #include "Fileio.ch"
   //
   nHandle := FOpen("New.txt", FC_NORMAL)
   IF FError() != 0
      ? "File open error:", FError()
   ELSE
      cString := FReadStr(nHandle, 16)
      ? cString
      FClose(nHandle)
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FRename()Harbour implementation


⌃ | ☰

Change the name of a file

Syntax

FRename(<cOldFile>, <cNewFile>) → nSuccess

Arguments

cOldFile is the name of the file to be renamed, including the file extension. A drive letter and/or path name may also be included as part of the file name.

cNewFile is the new name of the file, including the file extension. A drive letter and/or path name may also be included as part of the name.

Returns

FRename() returns -1 if the operation fails and zero if it succeeds. In the case of a failure, FError() can be used to determine the nature of the error.

Description

FRename() is a file function that changes the name of a specified file to a new name and is identical to the RENAME command.

When FRename() is called, cOldFile is renamed only if it is located in the current DOS directory or in the specified path. FRename() does not use SET DEFAULT or SET PATH to locate cOldFile.

If the source directory is different from the target directory, the file moves to the target directory. In the instance that either cNewFile exists or is currently open, FRename() fails and returns -1, indicating that it did not perform its designated action. The nature of the error can be determined with FError().

Warning! Files must be CLOSEd before renaming. Attempting to rename an open file will produce unpredictable results. When a database file is renamed, the associated memo (.dbt) file must also be renamed. Failure to do so may compromise the integrity of your databases.

Examples

■  This example demonstrates a file rename:

   IF FRename("OldFile.txt", "NewFile.txt") == -1
      ? "File error:", FError()
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

FSeek()Harbour implementation


⌃ | ☰

Set a binary file pointer to a new position

Syntax

FSeek(<nHandle>, <nOffset>, [<nOrigin>]) → nPosition

Arguments

nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.

nOffset is the number of bytes to move the file pointer from the position defined by nOrigin. It can be a positive or negative number. A positive number moves the pointer forward, and a negative number moves the pointer backward in the file.

nOrigin defines the starting location of the file pointer before FSeek() is executed. The default value is zero, representing the beginning of file. If nOrigin is the end of file, nOffset must be zero or negative.

Methods of Moving the File Pointer

    Origin  Fileio.ch      Description

    0       FS_SET         Seek from beginning of file

    1       FS_RELATIVE    Seek from the current pointer position

    2       FS_END         Seek from end of file

Returns

FSeek() returns the new position of the file pointer relative to the beginning of file (position 0) as an integer numeric value. This value is without regard to the original position of the file pointer.

Description

FSeek() is a low-level file function that moves the file pointer forward or backward in an open binary file without actually reading the contents of the specified file. The beginning position and offset are specified as function arguments, and the new file position is returned. Regardless of the function arguments specified, the file pointer cannot be moved beyond the beginning or end of file boundaries.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system.

Examples

■  This example uses FSeek() to determine the length of a file by
   seeking from the end of file.  Then, the file pointer is reset to the
   beginning of file:

   #include "Fileio.ch"
   //
   // Open the file read-only
   IF (nHandle := FOpen("Temp.txt")) >= 0
      //
      // Get length of the file
      nLength := FSeek(nHandle, 0, FS_END)
      //
      // Reset file position to beginning of file
      FSeek(nHandle, 0)
      FClose(nHandle)
   ELSE
      ? "File open error:", FError()
   ENDIF

■  This pseudofunction positions the file pointer at the last
   byte in a binary file:

   #define FileBottom(nHandle);
         (FSeek(nHandle, 0, FS_END))

■  This pseudofunction positions the file pointer at the first
   byte in a binary file:

   #define FileTop(nHandle);
         (FSeek(nHandle, 0))

■  This pseudofunction reports the current position of the file
   pointer in a specified binary file:

   #define FilePos(nHandle);
         (FSeek(nHandle, 0, FS_RELATIVE))

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is fileio.ch.

See also

FUNCTION⌃ | ☰

Declare a user-defined function name and formal parameters

Syntax

[STATIC] FUNCTION <idFunction>[(<idParam list>)]
   [LOCAL <identifier> [[:= <initializer>], ... ]]
   [STATIC <identifier> [[:= <initializer>], ... ]]
   [FIELD <identifier list> [IN <idAlias>]]
   [MEMVAR <identifier list>]
   .
   . <executable statements>
   .
   RETURN <exp>

Arguments

idFunction is the name of the user-defined function to be declared. User-defined function names can be any length, but only the first 10 characters are significant. Names can contain any combination of characters, numbers, or underscores, but must begin with a character or an underscore. Leading underscores are not recommended since they are reserved for internal functions.

idParam list is the declaration of one or more parameter variables. Variables specified in this list are declared local.

STATIC FUNCTION declares a user-defined function that can be invoked only by procedures and user-defined functions declared in the same program (.prg) file.

LOCAL declares and optionally initializes a list of variables or arrays whose visibility and lifetime is the current function.

STATIC declares and optionally initializes a list of variables or arrays whose visibility is the current user-defined function and lifetime is the duration of the program.

FIELD declares a list of identifiers to use as field names whenever encountered. If the IN clause is specified, referring to the declared name includes an implicit reference to the specified alias.

MEMVAR declares a list of identifiers to use as private or public memory variables or arrays whenever encountered.

identifier and identifier list are labels to be used as variable or array names.

initializer is a value to which an array or variable is originally set in an inline expression.

RETURN exp passes control back to the calling procedure or user-defined function, returning the result of exp as the value of the function. Each function must have at least one RETURN statement that returns a value. RETURN statements can occur anywhere in the body of a function.

Description

The FUNCTION statement declares a user-defined function and an optional list of local variables to receive parameters often referred to as formal parameters. A user-defined function is a subprogram comprised of a set of declarations and statements executed whenever you refer to idFunction followed by an open and closed parentheses pair. A function definition begins with a FUNCTION statement which is the FUNCTION declaration and ends with the next FUNCTION statement, PROCEDURE statement, or end of file.

Functions encapsulate a computational block of code and then later create expressions using the value returned. Functions and procedures increase both readability and modularity, isolate change, and help manage complexity.

A function in CA-Clipper is the same as a procedure, except that it must return a value. The returned value can be any data type including an array, a code block, or NIL. Each function must begin with a FUNCTION statement and contain at least one RETURN statement with an argument. Function declarations cannot be nested within other function definitions. A user-defined function can be used wherever standard functions are supported, including expressions.

The visibility of function names falls into two classes. Functions that are visible anywhere in a program are referred to as public functions and declared with a FUNCTION statement. Functions that are visible only within the current program (.prg) file are referred to as static functions and declared with a STATIC FUNCTION statement. Static functions have filewide scope.

Static functions limit visibility of a function name, thereby restricting access to the function. Because of this, subsystems defined within a single program (.prg) file can provide an access protocol with a series of public functions and conceal the implementation details of the subsystem within static functions and procedures. Since the static function references are resolved at compile time, they preempt references to public functions which are resolved at link time. This ensures that within a program file, a reference to a static function executes that function if there is a name conflict with a public function.

For more information on user-defined functions, variable declarations, and parameter passing, refer to the «Basic Concepts» chapter in the Programming and Utilities Guide.

Notes

■ Calling a user-defined function: Use the same notation to call

a user-defined function as when calling a standard CA-Clipper function:

idFunction([argument list])

You can call a user-defined function within an expression or on a line by itself. If called on a line by itself, the return value is ignored.

You can also call a user-defined function as an aliased expression by prefacing it with an alias and enclosing it in parentheses:

idAlias->(idFunction(argument list))

When you call a user-defined function as an aliased expression, the work area associated with idAlias is selected, the expression is executed, and the original work area is then reselected. You can specify an aliased expression on a line by itself, as you would any other expression.

A user-defined function in CA-Clipper may call itself recursively. This means you can make a reference to a user-defined function in statements or expressions of the same user-defined function definition.

■ Parameters: User-defined functions, like procedures, can

receive parameters passed from a calling procedure, user-defined function, or DOS command line. A parameter is a place holder for a value or reference. In CA-Clipper, there are two ways to express parameters: you can declare a list of local variable names as a part of the FUNCTION declaration (referred to as formal parameters), or you can specify a list of private variables in a separate PARAMETERS statement. Note that you cannot mix a declaration of formal parameters with a PARAMETERS statement. Attempting this will result in a fatal compiler error.

Functions receive parameters in the order passed. In CA-Clipper, the number of parameters does not have to match the number of arguments passed. You can skip arguments or omit them from the end of the argument list. A parameter not receiving a value or reference is initialized to NIL. You can skip a parameter by passing NIL. If arguments are specified, PCount() returns the position of the last argument passed. (If more arguments are passed than are parameters, they are ignored.)

Parameters specified in a user-defined function can receive arguments passed by value or reference. The default method for expressions and variables is by value. This includes variables that contain references to arrays and objects. All variables except field variables, when prefaced with the pass-by-reference operator (@), are passed by reference. Field variables cannot be passed by reference and are always passed by value.

Examples

■  This example demonstrates a user-defined function that formats
   numeric values as currency:

   ? Currency( 1000 )               // Result: $1,000.00

   FUNCTION Currency( nNumber )
      LOCAL cNumber
      IF nNumber < 0
         cNumber := Transform(-1 * nNumber, ;
               "999,999,999,999.99")
         cNumber := PadL("($" + LTrim(cNumber) + ")", ;
               Len(cNumber))
      ELSE
         cNumber := Transform(nNumber, ;
               "999,999,999,999.99")
         cNumber := PadL("$" + LTrim(cNumber), ;
               Len(cNumber))
      ENDIF
      RETURN cNumber

■  This example demonstrates a user-defined function that takes a
   character string formatted as a comma-separated list and returns an
   array with one element per item:

   aList := ListAsArray("One, Two")
   // Result: {"One", "Two"}

   FUNCTION ListAsArray( cList )
      LOCAL nPos
      // Define an empty array
      LOCAL aList := {}
      //
      DO WHILE (nPos := At(",", cList)) != 0
         // Add a new element
         AAdd(aList, SubStr(cList, 1, nPos - 1))
         cList := SubStr(cList, nPos + 1)
      ENDDO
      AAdd(aList, cList)
      //
      // Return the array
      RETURN aList

■  This example checks for a skipped argument by comparing the
   parameter to NIL:

   FUNCTION MyFunc( param1, param2, param3 )
      IF param2 == NIL
         param2 := "default value"
      ENDIF
      .
      . <statements>
      .
      RETURN NIL

■  This example uses the user-defined function, Currency()
   (defined above), as an aliased expression:

   USE Invoices NEW
   USE Customer NEW
   ? Invoices->(Currency(Amount))

Platforms

Available on MS-DOS

See also

FWrite()Harbour implementation


⌃ | ☰

Write to an open binary file

Syntax

FWrite(<nHandle>, <cBuffer>, [<nBytes>])
   → nBytesWritten

Arguments

nHandle is the file handle obtained from FOpen(), FCreate(), or predefined by DOS.

cBuffer is the character string to write to the specified file.

nBytes indicates the number of bytes to write beginning at the current file pointer position. If omitted, the entire content of cBuffer is written.

Returns

FWrite() returns the number of bytes written as an integer numeric value. If the value returned is equal to nBytes, the operation was successful. If the return value is less than nBytes or zero, either the disk is full or another error has occurred.

Description

FWrite() is a low-level file function that writes data to an open binary file from a character string buffer. You can either write all or a portion of the buffer contents. Writing begins at the current file position, and the function returns the actual number of bytes written.

If FWrite() results in an error condition, FError() can be used to determine the specific error.

Warning! This function allows low-level access to DOS files and devices. It should be used with extreme care and requires a thorough knowledge of the operating system

Examples

■  This example copies the contents of one file to another:

   #include "Fileio.ch"
   #define F_BLOCK      512
   //
   cBuffer := Space(F_BLOCK)
   nInfile := FOpen("Temp.txt", FO_READ)
   nOutfile := FCreate("Newfile.txt", FC_NORMAL)
   lDone := .F.
   //
   DO WHILE !lDone
      nBytesRead := FRead(nInfile, @cBuffer, F_BLOCK)
      IF FWrite(nOutfile, cBuffer, nBytesRead) < ;
                  nBytesRead
         ? "Write fault: ", FError()
         lDone := .T.
      ELSE
         lDone := (nBytesRead == 0)
      ENDIF
   ENDDO
   //
   FClose(nInfile)
   FClose(nOutfile)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

GBMPDISP()


⌃ | ☰

Display a bitmap (.BMP) file on screen

Syntax

GBMPDISP(<aBmpArray> | <cFile>, <nX>, <nY>, [<nTransColor>]
   → NIL

Arguments

aBmpArray defines the pointer created with GBMPLOAD().

-OR-

cFile defines the .BMP file to be displayed.

nX is the position of the starting point on the X-axis (column).

nY is the position of the starting point on the Y-axis (line).

nTransColor is the color to be excluded.

If nColor is set, all colors in the image are displayed except nColor.

Returns

GBMPDISP() always returns NIL.

Description

GBMPDISP() displays a bitmap (.BMP) or icon (.ICO) file previously loaded into memory or display a BMP directly from disk. This function can be used only if you have set the screen to a graphic mode using SET VIDEOMODE. GBMPDISP() respects the constraints defined by GSETCLIP().

Warning! The current color palette is used when you display a .BMP. Be aware that if you allow users to modify the color palette, the colors used in creating your .BMP may be changed because of the current palette components.

Notes

It is possible to create visual effects on top of a .BMP, such as a button that appears to be depressed when the user clicks on it. This can be done by superimposing a rectangle in XOR mode:

#include «Llibg.ch» LOCAL aMyButton SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16 // Load the BMP aMyButton := gBmpload («MyButton.BMP»)

// Display the BMP, always in SET mode

gBmpDisp (aMyButton,100,200)

. . // Your code .

IF mState()[LLM_STATE_LEFT] == LLM_BUTTON_DOWN

// When the mouse button is pressed, we superimpose a BMP

gRect( 100,;

200,; 100 + aMyButton[LLG_BMP_X],; 200 + aMyButton[LLG_BMP_Y],; LLG_FILL,; 8,; LLG_MODE_XOR)

ENDIF

// As long as the button is down…

DO WHILE mState()[LLM_STATE_LEFT] == LLM_BUTTON_DOWN . . // Your code . ENDDO

// When the mouse button is released we reload // the BMP to restore the original look

gRect(100,;

200,; 100 + aMyButton[LLG_BMP_X],;

200 + aMyButton[LLG_BMP_Y],;

LLG_FILL,;

8,;

LLG_MODE_XOR)

Examples

■  This example displays buttons previously stored in aIcons
   using gBmpLoad():

   gBmpDisp(aIcons,100,200)

■  This example loads and displays a background without using a
   variable.  In this case, the area occupied in VMM when the array is
   loaded, is freed by CA-Clipper once the display ends.

   gBmpDisp(gBmpLoad("MyDesk.BMP") , 0 , 0 )

Platforms

Available on MS-DOS

See also

GBMPLOAD()


⌃ | ☰

Load a bitmap (.bmp) or icon (.ico) file into memory

Syntax

GBMPLOAD(<cFileName>) → aBmpArray

Arguments

cFileName is a character value that specifies the name of .bmp or .ico file to load into VMM memory.

Returns

GBMPLOAD() returns a reference to aBmpArray which is the pointer to the VMM region containing the .BMP or .ICO (not a black and white icon). The first two elements of aBmpArray contain the height and width of the .BMP or .ICO in pixels. Do not modify this array before passing it to GBMPDISP(). The following table shows the array structure:

aBmpArray Structure

    Array Position    Return Value

    LLG_BMP_X         Returns size on the X axis

    LLG_BMP_Y         Returns size on the Y axis

The size and elements of this array should never be changed.

Description

GBMPLOAD() allows you to load one or more .BMP or .ICO files into memory without having to display them. This function is useful when you want to load a group of small .BMP files which are used often in an application (e.g., buttons). It avoids having to load the .BMP file each time you display it.

Warning! It is not a good idea to keep backgrounds or images in memory unless you have a great deal of memory. This also includes any variable pointing to the variables which contain the .BMP.

Notes

When a .BMP or .ICO is stored in a LOCAL variable, the memory occupied in the VMM is automatically freed when the function returns. You can free the memory at any time by assigning NIL to the variable. It is not necessary to be in graphic mode to use GBMPLOAD(), but it is necessary to be in graphic mode before calling GBMPDISP().

Examples

■  This example stores all the buttons used by an application in
   an array:

   STATIC aIcons:= {}
   AAdd(aIcons, GBMPLOAD('ARROW_U.BMP'))
   AAdd(aIcons, GBMPLOAD('ARROW_D.BMP'))
   AAdd(aIcons, GBMPLOAD('ARROW_L.BMP'))
   AAdd(aIcons, GBMPLOAD('ARROW_R.BMP'))
   // Set video to graphic mode
   SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16
   // Display the ARROW_U.BMP
   GBMPDISP(aIcons[1], 100, 200)

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

Get class⌃ | ☰

Provides objects for interactive editing of database fields and variables

Description

A Get object is a general purpose mechanism for editing data. It is used in CA-Clipper to implement the @...GET and READ commands. Get objects provide a sophisticated architecture for formatting and editing data, including cursor navigation and data validation. Data validation is performed via user-supplied code blocks, and display formatting can be controlled using standard picture strings.

Normally, a Get object is associated with a particular variable (referred to as the GET variable). The Get object does not directly access this variable; instead, the variable is manipulated by evaluating a supplied code block. When a Get object is created using the standard @...GET command, a code block is automatically created which provides access to the variable named in the command. For a Get object created with the GetNew() function, you must specify an appropriate code block.

A Get object evaluates the supplied code block to retrieve the value of the GET variable. The value is converted to a displayable form and copied into a buffer referred to as the editing buffer. You can display the editing buffer on the screen for editing. Programmable behaviors allow the navigation of the editing buffer and subsequent copying of its contents back to the GET variable.

Methods link

GetNew() Create a new Get object


GetNew([nRow], [nCol], [bBlock], [cVarName],

[cPicture], [cColorSpec]) → oGet

Returns

GetNew() returns a new Get object with the row, col, block, picture, and colorSpec instance variables set from the supplied arguments.

Exported Instance Variables


badDate Indicates if the editing buffer contains an invalid date


badDate

Contains a logical value indicating that the editing buffer does not represent a valid date. Get:badDate contains true (.T.) when the Get object is a date type and the date represented by the contents of the editing buffer is invalid. Get:badDate contains false (.F.) when the date is valid or the GET is not editing a date value.

block Code block to associate Get with a variable


block (Assignable)

Contains a code block that associates the Get object with a variable. The code block takes an optional argument that should assign the value of the argument to the variable. If the argument is omitted, the code block should return the current value of the variable.

If the GET variable is an array element, Get:block always returns the base of the array. The subscript(s) in the expression are stored internally. Thus, in the case of GETs on array elements, you cannot assign or retrieve the value of the array element by executing Get:block. Setting and getting may be done on array element GET variables (and simple variables as well) by use of the varGet() and varPut() methods, defined below.

Note: Use of the varGet and varPut messages—instead of directly evaluating the variable block in the GET—is the preferred method of accessing the GET variable.

buffer Character value that defines the editing buffer


buffer (Assignable)

Contains a character value which is the editing buffer used by the Get object. Get:buffer is meaningful only when the Get object has input focus. At other times, it contains NIL and any attempts to assign a new value are ignored.

cargo User-definable variable


cargo (Assignable)

Contains a value of any data type unused by the Get system. Get:cargo is provided as a user-definable slot, allowing arbitrary information to be attached to a Get object and retrieved later.

changed Indicates whether the Get:buffer has changed


changed

Contains a logical value indicating whether the Get:buffer has changed since the GET received input focus. Get:changed contains true (.T.) if the buffer has changed; otherwise, it contains false (.F.).

clear Indicates whether the editing buffer should be cleared


clear (Assignable)

Contains a logical value indicating whether the editing buffer should be cleared before any more values are entered. Get:clear is set true (.T.) by Get:setFocus() and Get:undo() when the G variable is a numeric type or when Get:picture contains the «@K» picture function. At all other times, it contains false (.F.).

col (Assignable)

Contains a numeric value defining the screen column where the Get is displayed.

colorSpec Display attributes string


colorSpec (Assignable)

Contains a character string defining the display attributes for the Get object. The string must contain two color specifiers. The first, called the unselected color, determines the color of the Get object when it does not have input focus. The second, called the selected color, determines the color of the GET when it has input focus.

If no colors are specified, Get:colorSpec is initialized using the current SetColor() colors. The SetColor() unselected and enhanced colors are used as the Get object’s unselected and selected colors, respectively. See the SetColor() entry in this chapter for more information on color specifiers.

decPos Decimal point position within the editing buffer


decPos

Contains a numeric value indicating the decimal point position within the editing buffer. Get:decPos is meaningful only when the value being edited is numeric and the Get object has input focus. Otherwise, it contains NIL.

exitState Means by which the user exited the Get


exitState (Assignable)

Contains a numeric value used in the CA-Clipper version of Getsys.prg to record the means by which a Get object was exited.

GET Exit States

       Number  Getexit.ch     Meaning

       0       GE_NOEXIT      No exit attempted, prepare  for editing

       1       GE_UP          Go to previous

       2       GE_DOWN        Go to next

       3       GE_TOP         Go to first

       4       GE_BOTTOM      Go to last

       5       GE_ENTER       edit normal end

       6       GE_WRITE       Terminate READ state with  save

       7       GE_ESCAPE      Terminate READ state without  save

       8       GE_WHEN        WHEN clause unsatisfied

Getexit.ch contains manifest constants for the Get:exitState values.

hasFocus Logical value indicating the input focus


hasFocus

Contains a logical value that indicates if the Get object has input focus. Get:hasFocus contains true (.T.) if the Get object has input focus; otherwise, it contains false (.F.).

message Character string displayed on the Get system’s status bar


message (Assignable)

Contains a character string that is displayed on the Get system’s status bar line when the GET has input focus. Typically, it describes the anticipated contents of, or user response to the GET. Refer to the READ command for details pertaining to the Get system’s status bar.

minus Indicates if a minus sign has been entered


minus (Assignable)

Contains a logical value indicating that a minus sign (-) has been added to the editing buffer. Get:minus is set to true (.T.) only when the Get object is a numeric type, the current value of the editing buffer is zero and the last change to the editing buffer was the addition of the minus sign. It is cleared when any change is made to the buffer.

name (Assignable)

Contains a character string representing the name of the GET variable. This value is optional and can be assigned at your discretion. With Get objects created using the standard @...GET command, Get:name always contains the GET variable name.

The Get object itself ignores this variable. It is used by the standard READ command and ReadModal() function to implement the ReadVar() function (see the ReadVar() entry in this chapter).

original Character string containing the original value of the Get


original

Contains a value of any data type that is a copy of the value in the GET variable at the time the Get object acquired input focus. This value implements the Get:undo message. Get:original is meaningful only while the GET has input focus. At all other times, it contains NIL.

picture (Assignable)

Contains a character value defining the PICTURE string that controls formatting and editing for the Get object. See the @...GET entry in this chapter for more information on PICTURE strings.

pos Current cursor position within the editing buffer


pos

Contains a numeric value indicating the position of the cursor within the editing buffer. Get:pos is meaningful only when the Get object has input focus. At all other times, it contains NIL.

postBlock Code block to validate a newly entered value


postBlock (Assignable)

Contains an optional code block that validates a newly entered value. If present, the Get:postBlock should contain an expression that evaluates to true (.T.) for a legal value and false (.F.) for an illegal value. For Get objects created with the standard @...GET...VALID command, Get:postBlock is assigned the expression specified in the VALID clause.

The Get object itself ignores this variable. It is used by the standard READ command to implement the VALID clause.

During postvalidation the Get:postBlock is passed a reference to the current Get object as an argument. Note that this differs from the CA-Clipper 5.0 behavior where the Get:postBlock was passed the updated value of the GET variable, and a logical value representing whether the Get object had been edited.

preBlock Code block to decide if editing is permitted


preBlock (Assignable)

Contains an optional code block that decides whether editing should be permitted. If present, the Get:preBlock should evaluate to true (.T.) if the cursor enters the editing buffer; otherwise, it should evaluate to false (.F.). For Get objects created with the standard @...GET...WHEN command, Get:preBlock is initialized with the expression specified in the WHEN clause.

The Get object itself ignores this variable. It is used by the standard READ command to implement the WHEN clause.

During prevalidation, the Get:preBlock is passed a reference to the current Get object as an argument. Note that this behavior differs from CA-Clipper 5.0 where no arguments were passed to Get:preBlock when it was run during prevalidation.

reader Contains a block to affect READ behavior on a Get object


reader

Contains a code block to implement special READ behaviors for any GET. If Get:reader contains a code block, ReadModal() evaluates that block to READ the GET (the Get object is passed as an argument to the block). The block may in turn call any desired function to provide custom editing of the Get object. If Get:reader does not contain a code block, ReadModal() uses a default read procedure (GetReader()) for the Get object.

Note that Get:reader allows particular Get objects to have specialized READ behaviors without changing the standard ReadModal() function. This preserves compatibility for GETs which are to be handled in the customary way and also eliminates potential conflicts between different extensions to the GET/READ system.

rejected Indicates if last insert/overStrike character was rejected


rejected

Contains a logical value indicating whether the last character specified by a Get:insert or Get:overStrike message was placed in the editing buffer. Get:rejected contains true (.T.) if the last character was rejected; otherwise, it contains false (.F.). Note that any subsequent text entry message resets this variable.

row (Assignable)

Contains a numeric value defining the screen row where the GET displays.

subscript Information about array Get objects


subscript (Assignable)

Contains an array of numeric values representing the subscripts of a GET array element. Each element of Get:subscript represents a dimension of the GET array. For example:

@ 1,1 GET aTestA[4] // Get:subscript contains {4} @ 1,1 GET aTestB[3,6] // Get:subscript contains {3,6}

If the GET does not involve an array, Get:subscript contains NIL.

type Get variable data type


type

Contains a single letter representing the data type of the GET variable. For more information on the values that represent data types, refer to the ValType() entry in this chapter.

typeOut Indicates attempt to move the cursor out of editing buffer


typeOut

Contains a logical value indicating whether the most recent message attempted to move the cursor out of the editing buffer, or if there are no editable positions in the buffer. Get:typeOut contains true (.T.) if the last message satisfied this condition. Note, Get:typeOut is reset by any message that moves the cursor.

assign() Assigns the editing buffer contents to the Get variable


assign() → self

Assigns the value in the editing buffer to the GET variable by evaluating Get:block with the buffer value supplied as its argument. This message is meaningful only when the Get object has input focus.

colorDisp() Changes a Get object’s color then redisplays it


colorDisp([cColorString]) → self

Get:colorDisp() is a method that changes a Get object’s colors and redisplays it. It is exactly equivalent to assigning Get:colorSpec and issuing Get:display().

display() Displays the Get on the screen


display() → self

Displays the GET on the screen. If the Get object has input focus, the Get:buffer displays in its selected color and the cursor is placed at the screen location corresponding to the current editing position within the buffer. If the GET does not have input focus, the Get:block is evaluated and the result displays in the GET‘s unselected color with no cursor.

HitTest() Indicates position of mouse cursor relative to Get object


HitTest(nRow, nColumn) → self

Determines the screen position specified by nRow and nColumn is on the Get object.

Applicable Hit Test Return Values

       Value   Constant     Description

        0      HTNOWHERE    The mouse cursor is not within the region of the

                            screen that the GET occupies

       -1025   HTCAPTION    The mouse cursor is on the GET’s caption

       -2049   HTCLIENT     The mouse cursor is on the GET

Button.ch contains manifest constants for the Get:hitTest() return values.

killFocus() Takes input focus away from the Get object


killFocus() → self

Takes input focus away from the Get object. Upon receiving this message, the Get object redisplays its editing buffer and discards its internal state information.

reset() Resets the internal state information of the Get


reset() → self

Resets the Get object’s internal state information. This includes resetting the editing buffer to reflect the GET variable’s current value and setting the cursor position to the first editable position within the buffer. This message has meaning only when the Get object has input focus.

setFocus() Gives input focus to the Get object


setFocus() → self

Gives input focus to the Get object. Upon receiving this message, the Get object creates and initializes its internal state information, including the exported instance variables: Get:buffer, Get:pos, Get:decPos, and Get:original. The contents of the editing buffer are then displayed in the GET‘s selected color.

undo() Sets the Get variable back to Get:original


undo() → self

Sets the GET variable back to the value it had when the GET acquired input focus. This message has meaning only while the GET has input focus.

The effect of the Get:undo() message is equivalent to assigning the GETvariable from the saved value in Get:original and then sending the Get:reset() message.

unTransform() Converts character value to its original data type


unTransform() → xValue

Converts the character value in the editing buffer back to the data type of the original variable. Get:assign() is equivalent to Get:varPut (Get:unTransform()).

updateBuffer() Updates the editing buffer and redisplays the Get


updateBuffer() → self

Sets the editing buffer to reflect the current value of the Get variable, and redisplays the GET. This message has meaning only while the GET has input focus.

varGet() Returns the current value of the Get variable


varGet() → GetVarValue

Returns the current value of the GET variable. For simple GET variables this is equivalent to executing Get:block:

aGet:varGet() == Eval(aGet:block)

However, if the GET variable is an array element, Eval(aGet:block) will not return the value of the GET variable; in this case, you must use varGet(). An example of varGet() may be found in the ReadModal() function, defined in Getsys.prg.

varPut() Sets the Get variable to the passed value


varPut() → Value

Sets the GET variable to the passed value. For simple GET variables this is equivalent to executing Get:block with an argument:

aGet:varPut(aValue) == Eval(aGet:block, aValue)

However, if the GET variable is an array element, Eval(aGet:block, aValue) will not set the value of the GET variable; in this case use of varPut() is required.

end() Moves the cursor to the rightmost position


end() → self

Moves the cursor to the rightmost editable position within the editing buffer.

home() Moves the cursor to the leftmost position


home() → self

Moves the cursor to the leftmost editable position within the editing buffer.

Left() Moves the cursor left one character


Left() → self

Moves the cursor left to the nearest editable position within the editing buffer. If there is no editable position to the left, the cursor position is left unchanged.

Right() Moves the cursor right one character


Right() → self

Moves the cursor right to the nearest editable position within the editing buffer. If there is no editable position to the right, the cursor position is left unchanged.

toDecPos() Moves the cursor to the immediate right of Get:decPos


toDecPos() → self

Moves the cursor to the immediate right of the decimal point position in the editing buffer. This message is only meaningful when editing numeric values.

wordLeft() Moves the cursor left one word


wordLeft() → self

Moves the cursor one word to the left within the editing buffer. If the cursor is already at the leftmost editable position, it is left unchanged.

wordRight() Moves the cursor right one word


wordRight() → self

Moves the cursor one word to the right within the editing buffer. If the cursor is already at the rightmost editable position, it is left unchanged.

backspace() Moves the cursor to the left and deletes one character


backspace() → self

Deletes the character to the left of the cursor moving the cursor one position to the left. If the cursor is already at the leftmost editable position in the editing buffer, this message has no effect.

delete() Deletes the character under the cursor


delete() → self

Deletes the character under the cursor.

delEnd() Deletes from current cursor position to the end of the Get


delEnd() → self

Deletes from the current character position to the end of the GET, inclusive.

delLeft() Deletes the character to the left of the cursor


delLeft() → self

Deletes the character to the left of the cursor.

delRight() Deletes the character to the right of the cursor


delRight() → self

Deletes the character to the right of the cursor.

delWordLeft() Deletes the word to the left of the cursor


delWordLeft() → self

Deletes the word to the left of the cursor.

delWordRight() Deletes the word to the right of the cursor


delWordRight() → self

Deletes the word to the right of the cursor.

insert() Inserts characters into the editing buffer


insert(cChar) → self

Inserts cChar into the editing buffer at the current cursor position, shifting the existing contents of the buffer to the right. The cursor is then placed one position to the right of the inserted string.

overStrike() Overwrites characters in the editing buffer


overStrike(cChar) → self

Puts cChar into the editing buffer at the current cursor position, overwriting the existing contents of the buffer. The cursor is placed one position to the right of the inserted string.

Examples

■  This example creates a new Get object, assigns some new
   attributes to its instance variables, and then edits the GET with the
   ReadModal() function:

   LOCAL cVar := Space(10)
   //

   // Create a new Get object
   objGet := GetNew()
   //

   // Assign some instance variables
   objGet:row := 10
   objGet:col := 10
   //

   // Assign the name of the associated
   // variable and the block
   objGet:name := "cVar"
   objGet:block := { |cValue| IF(PCount() > 0,;
                      cVar := cValue, cVar) }
   //
   objGet:picture := "@!"
   objGet:colorSpec := "BG+/B, W+/BG"
   objGet:postBlock := { |oGet| !Empty(oGet:varGet()) }
   //

   // Edit the single Get object
   ReadModal({objGet})

Platforms

Available on MS-DOS

File

Source file is Getsys.prg.

See also

GetActive()Harbour implementation


⌃ | ☰

Return the currently active Get object

Syntax

GetActive([<oGet>]) → objGet

Arguments

oGet is a reference to a Get object.

Returns

GetActive() returns the Get object referenced by oGet. If oGet is not specified, then the current active Get object within the current READ is used. If there is no READ active when GetActive() is called, it returns NIL.

Description

GetActive() is an environment function that provides access to the active Get object during a READ. The current active Get object is the one with input focus at the time GetActive() is called.

Examples

■  This code uses a WHEN clause to force control to branch to a
   special reader function.  Within this function, GetActive() retrieves
   the active Get object:

   @ 10, 10 GET x
   @ 11, 10 GET y WHEN MyReader()
   @ 12, 10 GET z
   READ

   // Called just before second get (above)
   // becomes current
   FUNCTION MyReader
      LOCAL objGet               // Active Get holder
      objGet := GetActive()      // Retrieve current

                                 // active Get
      BarCodeRead( objGet )
      RETURN (.F.)               // Causes Get to be
                                 // skipped in READ

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

GetApplyKey()Harbour implementation


⌃ | ☰

Apply a key to a Get object from within a reader

Syntax

GetApplyKey(<oGet>, <nKey>, <GetList>, <oMenu>,
   <nMsgRow>, <nMsgLeft>, <nMsgRight>, <cMsgColor>)
   → NIL

Arguments

oGet is a reference to a Get object.

nKey is the Inkey() value to apply to oGet.

GetList is a reference to the current list of Get objects.

oMenu is a reference to any top bar menu.

nMsgRow is a numeric value representing the row of the message bar.

nMsgLeft is a numeric value representing the left column of the message bar.

nMsgRight is a numeric value representing the right column of the message bar.

cMsgColor is a character string representing the colors to be used for the message bar text.

Returns

GetApplyKey() always returns NIL.

Description

GetApplyKey() is a Get system function that applies an Inkey() value to a Get object. Keys are applied in the default way. That is, cursor movement keys change the cursor position within the GET, data keys are entered into the GET, etc.

If the key supplied to GetApplyKey() is a SET KEY, GetApplyKey() will execute the set key and return; the key is not applied to the Get object.

Notes

■ Focus: The Get object must be in focus before keys are

applied. Refer to Get:setFocus and Get:killFocus for more information.

CLEAR GETS: The Get object must be in focus before keys are

applied. Refer to Get:setFocus and Get:killFocus for more information.

Examples

This example will apply keystrokes until Exit:

   WHILE (oGet:exitState == GE_NOEXIT)
      GETAPPLYKEY (oGet, Inkey(0), GetList, oMenu, nMsgRow,;
   nMsgLeft, nMsgRight, nMsgColor)
   ENDDO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

GetDoSetKey()Harbour implementation


⌃ | ☰

Process SET KEY during GET editing

Syntax

GetDoSetKey(<bKeyBlock>, <oGet>) → NIL

Arguments

oGet is a reference to the current Get object.

bKeyBlock is the code block to execute.

Returns

GetDoSetKey() always returns NIL.

Description

GetDoSetKey() is a function that executes a SET KEY code block, preserving the context of the passed Get object.

Note that the procedure name and line number passed to the SET KEY block are based on the most recent call to ReadModal().

Notes

■ If a CLEAR GETS occurs in the SET KEY code, Get:exitState is

set to GE_ESCAPE. In the standard system this cancels the current Get object processing and terminates ReadModal().

Examples

■  The following example determines if the last key pressed,
   nKey, has a SET KEY associated with it.  If it does, then GETDOSETKEY
   is called to execute that block on the current GET.

   IF ((bKeyBlock := SETKEY (nKey)) == NIL)
      GETDOSETKEY (bKeyBlock, oGet)
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

GetEnv()Harbour implementation


⌃ | ☰

Retrieve the contents of a DOS environment variable

Syntax

GetEnv(<cEnvironmentVariable>) → cString

Arguments

cEnvironmentVariable is the name of the DOS environment variable. When specifying this argument, you can use any combination of uppercase and lowercase letters; GetEnv() is not case-sensitive.

Returns

GetEnv() returns the contents of the specified DOS environment variable as a character string. If the variable cannot be found, GetEnv() returns a null string («»).

Description

GetEnv() is an environment function that lets you retrieve information from the DOS environment into an application program. Typically, this is configuration information, including path names, that gives the location of files (database, index, label, or reports). This function is particularly useful for network environments.

Notes

■ Empty return value: If you are certain that an environment

variable exists and yet GetEnv() always returns a null string («»), be sure there are no spaces between the environment variable name and the first character of the string assigned to it in the DOS SET command.

■ Compatibility: In previous releases of CA-Clipper, the

function was called GetE(). This abbreviated form of GetEnv() is still operational.

Examples

■  This example retrieves the current DOS PATH setting, making it
   the current CA-Clipper PATH:

   cPath := GetEnv("PATH")
   SET PATH TO (cPath)

■  This example uses environment variables to configure the
   specific locations of files.  When you set up a system, define
   environment variables that contain the location of various file types
   as well as the CLIPPER environment variable (see "The Runtime
   Environment" chapter in the Programming and Utilities Guide), like
   this:

   C>SET LOC_DBF=<database file path>
   C>SET LOC_NTX=<index file path>
   C>SET LOC_RPT=<report file path>

   In the configuration section of your application program, assign the
   contents of the environment variables to variables.  Then when you
   access a file, preface the reference with the path variable as
   follows:

   cDdfDirectory := GetEnv("LOC_DBF")
   USE (cDdfDirectory + "Invoices")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

GetPostValidate()Harbour implementation


⌃ | ☰

Postvalidate the current Get object

Syntax

GetPostValidate(<oGet>) → lSuccess

Arguments

oGet is a reference to the current Get object.

Returns

GetPostValidate() returns a logical value indicating whether the Get object has been postvalidated successfully.

Description

GetPostValidate() is a Get system function that validates a Get object after editing, including evaluating Get:postBlock (the VALID clause) if present.

The return value indicates whether the GET has been postvalidated successfully. If a CLEAR GETS is issued during postvalidation, Get:exitState is set to GE_ESCAPE and GetPostValidate() returns true (.T.).

Notes

■ In the default system, a Get:exitState of GE_ESCAPE cancels

the current GET and terminates ReadModal().

Examples

■  This example calls GETPOSTVALIDATE to determine whether or not
   the VALID clause of oGet is satisfied.  If not, then the user is not
   allowed to exit from the Get object.

   IF (! GETPOSVALIDATE (oGet))
      oGet : exitState := GE_NOEXIT
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

GetPreValidate()Harbour implementation


⌃ | ☰

Prevalidate a Get object

Syntax

GetPreValidate(<oGet>) → lSuccess

Arguments

oGet is a reference to the current Get object.

Returns

GetPreValidate() returns a logical value indicating whether the Get object has been prevalidated successfully.

Description

GetPreValidate() is a function that validates the Get object for editing, including evaluating Get:preBlock (the WHEN clause) if it is present. The logical return value indicates whether the GET has been prevalidated successfully.

Get:exitState is also set to reflect the outcome of the prevalidation:

Get:exitState Values

    Getexit.ch   Meaning

    GE_NOEXIT    Indicates prevalidation success, okay to edit

    GE_WHEN      Indicates prevalidation failure

    GE_ESCAPE    Indicates that a CLEAR GETS was issued

Note that in the default system, a Get:exitState of GE_ESCAPE cancels the current GET and terminates ReadModal().

Examples

■  This example demonstrates the GetPreValidate() function.

   IF GETPREVALIDATE (oGet)
      // process the get
   ELSE
      // WHEN clause not satisfied
      // give a warning to the user
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

GetReader()Harbour implementation


⌃ | ☰

Execute standard READ behavior for a Get object

Syntax

GetReader(<oGet>, <GetList>, <oMenu>, <nMsgRow>,
   <nMsgLeft>, <nMsgRight>, <cMsgColor>) → NIL

Arguments

oGet is a reference to a Get object.

GetList is an array of all the Get objects in the current Get list.

oMenu is a reference to a TopBarMenu object.

nMsgRow is a numeric value representing the row number on the screen where the message bar is located.

nMsgLeft is a numeric value representing the left border of the row bar.

nMsgRight is a numeric value representing the right border of the row bar.

cMsgColor is a character string representing the color string to be used for the message bar.

Returns

GetReader() always returns NIL.

Description

GetReader() is a GET function that implements the standard READ behavior for GETs. By default, ReadModal() uses the GetReader() function to read Get objects. GetReader() in turn uses other functions in Getsys.prg to do the work of reading the Get object.

Notes

■ If a Get object’s Get:reader instance variable contains a code

block, ReadModal() will evaluate that block in lieu of the call to GetReader(). For more information refer to the Get:reader reference.

Examples

■  This example sets the current Get object to the first GET in
   the Get list.  Then, a READ is performed on this GET which has no
   menu object, but includes a message bar at row 25 from column 0 to
   column 80.  The color of the text on the message bar is white with a
   red background.

   oGet := GetList [1]
   GETREADER (oGet, Getlist, NIL,25,;
                  0,80,"W+/R")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

GELLIPSE()


⌃ | ☰

Draw an ellipse or circle

Syntax

GELLIPSE(<nXc>,<nYc>,<nRadiusX>,<nRadiusY>,[<nDegStart>]
   [<nDegEnd>], [<nStyle>], [<nColor>], [<nMode>],
   [<nOutLineColor>], [<nHeight3D>]) → NIL

Arguments

nXc, nYc, nRadiusX, and nRadiusY define the ellipse center point coordinates in pixels.

Note: If nRadiusX and nRadiusY have the same value, the result will be a circle.

nDegStart is the value of the starting angle in degrees. The default value is 0.

nDegEnd is the value of the final angle in degrees. The default value is 360.

Note: Changing the values of nDegStart and nDegEnd allows you to draw arcs of a circle or ellipse and sections of a «pie chart.»

nStyle defines the style of the ellipse using one of the constants listed in the table below:

Ellipse Style Constants

    Constant     Description

    LLG_FILL     The ellipse is displayed first and then filled with the

                 color and mode specified below

    LLG_FRAME    Display of the ellipse is restricted to its contour in the

                 color and mode specified below

nColor is a numeric value representing the display color. If this parameter is missing, the last color specified in a call to a CA-Clipper function is used. The value range is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are between 0 and 15. In 256-color modes, valid values are between 0 and 255.

nMode is a numeric value that represents the display mode. The following are valid nMode values:

Display Mode Constants

    Constant       Description

    LLG_MODE_SET   Display in SET mode (ignores any pixels present under the

                   line displayed).  This is the most common display mode.

    LLG_MODE_AND   Display in AND mode (executes an AND on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_OR    Display in OR mode (executes an OR on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_XOR   Display in XOR mode (executes an XOR on pixels present

                   under the line at display time and on the display color).

                   See note.

Note: This method allows you to move objects around on the screen without damaging the background. To retrieve the initial background, just repeat the call for display in XOR mode. If the display mode parameter is missing, the last mode specified in a call to a CA-Clipper function is used.

nOutLineColor is a numeric value representing the outline color. If this parameter is missing, the last color specified in a call to a CA-Clipper function is used. The value range is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are between 0 and 15. In 256-color modes, valid values are between 0 and 255.

nHeight3D is a numeric value representing the height of the 3-D effect in pixels.

Returns

GELLIPSE() always returns NIL.

Description

GELLIPSE() draws an ellipse or circle. This function can be used only if you have set the screen to a graphic mode using SET VIDEOMODE. This function respects the constraints defined by GSETCLIP().

Examples

■  This example displays an ellipse in a region limited by
   clipping:

   // Switch to graphic mode

   SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16
   // Restrict the display region to one portion of the screen
   GSETCLIP(100,100,300,300)
   // Draw a quarter section of an ellipse
   GELLIPSE(200, 200, 160, 230, 045,;

      135, LLG_FILL, 12, LLG_MODE_SET)
   QUIT                            // End of application

Platforms

Available on MS-DOS

File

Library is LLIBG.LLB, header file is Llibg.ch.

See also

GFNTERASE()


⌃ | ☰

Erase a font from memory

Syntax

Arguments

aFont is a pointer to the VMM region where the .FND font is loaded. aFont would have been created with an earlier call to GFNTLOAD().

Returns

GFNTERASE() always returns NIL.

Description

GFNTERASE() erases a specified font from memory. Since CA-Clipper is unable to reallocate the memory occupied by a loaded font (i.e., no automatic garbage collection), it is your responsibility to release this memory. This can be done with the following:

aFont2Erase := GFNTERASE(aFont2Erase)

Examples

■  This example loads a Font file called MyFont .FND:

   FUNCTION ShowOneFont (cString)
      LOCAL aFont
               // Load a specific font file into memory
      aFont := GFNTLOAD("MyFont.FND")

               // Display cString using the loaded font
      GWRITEAT(X , Y , cString, nColor, LLG_MODE_SET, aFont)
      // *Important*  You must erase the font from memory if it is

      // no longer used.  This is because CA-Clipper's VMM is

      // unable to automatically free the memory occupied by aFont.
      GFNTERASE(aFont)
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GFNTLOAD()


⌃ | ☰

Load a font file into memory

Syntax

GFNTLOAD(<cFontFile>) → aFont

Arguments

cFontFile is a character value that represents the name of the font file to load.

Returns

GFNTLOAD() returns a pointer to the VMM region where the font is loaded. This value can later be used as input to GFNTERASE().

Description

CA-Clipper supports two types of fonts:

1. Video ROM fonts—.FND

Video ROM .FND fonts are used in all the standard CA-Clipper terminal calls such as DevOut(), TBrowse(), and GWRITEAT(). The size of .FND fonts is always 16×8. If you want to use a different size font, such as 8×8, you will need to supply the font file.

2. Windows Bitmap fonts—.FNT

The Windows Bitmap .FNT fonts can be used with the GWRITEAT() function.

Using .FND fonts: The .FND fonts are 16 pixels high. Therefore, the font is displayed from pixel 1 to pixel 16 of each screen row. CA-Clipper allows you to control the number of pixel rows to use for the font:

GFNTSET(aFont, nClipTop, nClipBottom)

Pass aFont as NIL if you only want to change the nClipTop and nClipBottom.

This feature provides the ability to display a one pixel frame around a GET or MENU PROMPT, etc. without having to use GWRITEAT(), because DevOut() (@..SAY..) is faster than GWRITEAT().

Using .FNT fonts: Be aware that .FNT fonts are proportional. For example, this means that the characters «m» and «i» will not be the same number of pixels in width.

To use .FNT fonts, load a FNT font into memory :

aFntFont := GFNTLOAD( «MyFnt.FNT» )

GWRITEAT( X, Y, cString, nColor, LLG_MODE_SET, aFont )

By passing LLG_MODE_NIL to GWRITEAT(), you can retrieve the width of the string to be displayed on screen (without displaying it).

nWidth will contain the # of pixels of the string:

nWidth := GWRITEAT( X , Y, cString, nColor, LLG_MODE_NIL, aFntFont)

nColumns will contain the # of columns:

nColumns := nWidth / 8.

Examples

■  This example loads a Font file called MyFont.FND:`

   // Function ShowOneFont (cString)
   LOCAL aFont
   // Load a specific font file (MyFont.FND) into memory
   aFont := GFNTLOAD("MyFont.FND")
   // Display cString using the loaded font
   GWRITEAT(X, Y, cString, nColor, LLG_MODE_SET, aFont)
   // *Important*
   // You must erase the font from memory if it is no longer
   // needed.
   // This is because CA-Clipper's VMM is unable to automatically
   // free the memory occupied by aFont.
   GFNTERASE(aFont)
   RETURN

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GFNTSET()


⌃ | ☰

Set an already loaded font as active

Syntax

GFNTSET(<aFont>, [<nClipTop>, <nClipBottom>])
   → aClipInfo

Arguments

aFont represents the pointer to the VMM region where the .FND font is loaded. aFont would have been created with GFNTLOAD().

nClipTop and nClipBottom specify how many pixel rows to use when displaying standard text output. This provides the ability to display a one pixel frame around a GET.

Returns

GFNTSET() returns a two-element array containing font clipping information.

Description

GFNTSET() sets an already loaded font as active. When GFNTSET() is called, all subsequent DevOut() calls will use the new font. This means that you can use multiple .FND fonts at the same time. To go back to the standard ROM font, use GFNTSET( LLG_FNT_ROM ). You can also use an .FND font in a GWRITEAT() as shown in the following code:

aFndFont := GFNTLOAD(«TestFnd.FND») nColor := 3 GWRITEAT(1, 1, «This is some text», nColor, LLG_MODE_SET, aFndFont)

GFNTSET() returns a two-element array containing font clipping information. The structure of this array is { nTopPixelRow, nBottomPixelRow }. This feature allows text to fit at a reduced height. A common requirement is to draw a frame around a GET without having to use a full text line over and under the GET. When you display a character with a DevOut() or a GET display method, the background always gets overwritten. So, if a frame is precisely drawn around the GET, part of the frame will be overwritten as soon as a single character is displayed.

In general, all regular fonts do not use the top and bottom row of pixels. This allows a displayed character to be clipped or restricted so that DevPos()/DISPLAY() will only erase the lines 1-14 (instead of 0- 15) and will preserve the frame previously drawn.

Examples

■  This example loads a font file called MyFont.FND:

   FUNCTION ShowOneFont (cString)
      LOCAL aFontBig, aFontSmall
               // Load a couple of fonts into memory
      aFontBig    := GFNTLOAD("BigFnt.FND")
      aFontSmall  := GFNTLOAD("SmallFnt.FND")
               // Set the BigFnt.FND to be active.  As soon as
   GFNTSET() is
               // called, @...SAY, DevOut() etc. will use the new
   font.
      GFNTSET(aFontBig)
      @1,1 SAY "This text should appear in the font 'BigFnt.FND'"
               // Display something in a Big font
      GWRITEAT(X , Y , "Using Big Font...",   nColor, LLG_MODE_SET)
      GWRITEAT(X , Y , "Using Small Font...", nColor, LLG_MODE_SET,;
   aFontSmall)
               // Set the SmallFnt.FND to be active
      GFNTSET(aFontSmall)
               // Display something in a Small font
      GWRITEAT(X , Y , "Using Small Font...", nColor, G_MODE_SET)
               // Use the standard ROM font
      GFNTSET(G_FNT_ROM)
               // Display something
      GWRITEAT(X , Y , "Using ROM Font...", nColor, G_MODE_SET)
               // *Important*  You must erase the fonts from memory
   // if it is no
               // longer used.  This is because CA-Clipper's VMM is
   // unable to free
               // the memory occupied by aFont
      GFNTERASE(aFontBig)
      GFNTERASE(aFontSmall)
      RETURN  NIL

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GFRAME()


⌃ | ☰

Draw a frame with a 3-D look

Syntax

GFRAME(<nXStart>, <nYStart>, <nXEnd>, <nYEnd>, <nColorBack>,
   <nColorLight>, <nColorDark>, <nWidthUp>, <nWidthRight>,
   <nWidthDown>, <nWidthLeft>, [<nMode>], [<nStyle>]) → NIL

Arguments

nXStart, nYStart, nXEnd, and nYEnd define frame coordinates in pixels.

nColorBack is a numeric value representing the display color of the border background.

nColorLight is a numeric value representing the light display color for borders.

nColorDark is a numeric value representing the dark display color for borders.

The range of color values is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are 0-15. In 256-color modes, valid values are 0-255.

nWidthUp is a numeric value representing the thickness of the frame borders. The values nWidthRight, nXStart, nYStart, nXEnd, nYEnd are the external dimensions nWidthDown of the frame, and the width of the borders is measured nWidthLeft within the rectangle.

nMode represents the frame mode. The following are valid nMode values:

Frame Mode Constants

    Constant       Description

    LLG_MODE_SET   Display in SET mode (ignores any pixels present under the

                   line displayed).  This is the most common display mode.

    LLG_MODE_AND   Display in AND mode (executes an AND on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_OR    Display in OR mode (executes an OR on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_XOR   Display in XOR mode (executes an XOR on pixels present

                   under the line at display time and on the display color).

                   See note.

nStyle defines the style of the ellipse using one of the constants listed in the table below:

Style Mode Constants

    Constant     Description

    LLG_FILL     Fills the frame with nColorBack.  This is the default.

    LLG_FRAME    Displays the frame in 3-D without filling in the frame with

                 nColorBack.

Note: This method allows you to move objects around on the screen without damaging the background. To retrieve the initial background, just repeat the call for display in XOR mode. If the display mode parameter is missing, the last mode specified in a call to a CA-Clipper function is used.

Returns

GFRAME() always returns NIL.

Description

GFRAME() draws box frames with a 3-D look using three appropriately selected colors. For example, gray for the background, black for the dark color and white for the light color. This function can be used only if you have set the screen to a graphic mode using GMODE(). This function respects the constraints defined by GSETCLIP().

Examples

■  This example shows how to display a series of frames with thin
   borders (3 pixels):

   Switch to graphic mode
   SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16
   // Buttons
   GFRAME(0, 0, 53, 399, 7, 15, 8, 3, 3, 3, 3, LLG_MODE_SET)
   // Coordinates
   GFRAME(0, 400, 53, 456, 7, 15, 8, 3, 3, 3, 3, LLG_MODE_SET)
   // Painting
   GFRAME(54, 0, 639, 399, 7, 15, 8, 3, 3, 3, 3, LLG_MODE_SET)
   // Palette
   GFRAME(54, 400, 639, 456, 7, 15, 8, 3, 3, 3, 3, LLG_MODE_SET)
   // Messages
   GFRAME(0, 457, 639, 479, 7, 15, 8, 3, 3, 3, 3, LLG_MODE_SET)
   QUIT                        // End of application

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GGETPIXEL()


⌃ | ☰

Get color information for a pixel

Syntax

GGETPIXEL(<nX>, <nY>) → nColor

Arguments

nX is a numeric value representing the position on the X-axis (row).

nY is a numeric value representing the position on the Y-axis (column).

Returns

GGETPIXEL() returns the value of a specific pixel.

Description

GGETPIXEL() can be used to get the color of a specific pixel.

Examples

■  The following example retrieves the color of pixel at X-
   coordinate 100 and Y-coordinate 100:

   nColor := GGETPIXEL(100, 100)

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

GLINE()


⌃ | ☰

Draw a line in graphic mode

Syntax

GLINE(<nXStart>, <nYStart>, <nXEnd>, <nYEnd>,
   [<nColor>], [<nMode>]) → NIL

Arguments

nX1, nY1, nX2, and nY2 define the line coordinates in pixels.

nColor is a numeric value representing the display color. If the parameter is missing, the last color specified in a call to a CA-Clipper function is used. The range of values is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are between 0 and 15. In 256-color modes, valid values are between 0 and 255.

Display Mode Constants

    Constant       Description

    LLG_MODE_SET   Display in SET mode (ignores any pixels present under the

                   line displayed).  This is the most common display mode.

    LLG_MODE_AND   Display in AND mode (executes an AND on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_OR    Display in OR mode (executes an OR on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_XOR   Display in XOR mode (executes an XOR on pixels present

                   under the line at display time and on the display color).

                   See note.

Note: This method allows you to move objects around on the screen without damaging the background. To retrieve the initial background, just repeat the call for display in XOR mode. If the display mode parameter is missing, the last mode specified in a call to a CA-Clipper graphic function is used.

Returns

GLINE() always returns NIL.

Description

GLINE() draws lines on the screen and respects the constraints defined by GSETCLIP(). This function can be used only if you have set the screen to a graphic mode using SET VIDEOMODE.

Examples

■  This example displays a line in a region restricted by
   clipping:

   // Switch to graphic mode
   SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16
   // Restrict the display region to a portion of the screen
   GSETCLIP(100, 100, 300, 300)
   // Draw a line using color 6
   GLINE(0, 0, 400, 400, 6, LLG_MODE_SET)
   QUIT                           // End of application

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GMODE()


⌃ | ☰

Switch video mode

Syntax

GMODE([<nMode>]) → aOldState

Arguments

nMode is a numeric value that represents the video mode.

The following are valid nMode values. They are all #defines in Llibg.ch.

Video Mode Constants

    Constant                      Description

    LLG_VIDEO_TXT                 Switch to text mode

    LLG_VIDEO_VGA_640_480_16      Switch to VGA 640x480x16 mode

    LLG_VIDEO_VESA_800_592_16     Switch to VESA 800x592x16

    LLG_VIDEO_VESA_1024_768_16    Switch to VESA 1024x768x16

    LLG_VIDEO_VESA_1280_1024_16   Switch to VESA 1280x1024x16

    LLG_VIDEO_VESA_640_480_256    Switch to VESA 640x480x256

    LLG_VIDEO_VESA_800_592_256    Switch to VESA 800x592x256

    LLG_VIDEO_VESA_1024_768_256   Switch to VESA 1024x768x256

    LLG_VIDEO_VESA_1280_1024_256  Switch to VESA 1280x1024x256

Note: LLG_VIDEO_TEXT and LLG_VIDEO_VGA_640_480_16 are the only two video modes applicable to CA-Clipper.

You can precede nMode by a minus sign. Supplying a negative argument in this manner causes GMODE() to check if the specified mode is available without switching to that mode.

Returns

If the video mode is available, GMODE() will return an array containing the settings for the requested video mode. The following table shows the array structure:

aOldState Structure

    Array Position           Return Value

    LLG_MODE_TEXT_ROW        Numeric value representing the number of text

                             rows on screen.

    LLG_MODE_TEXT_COL        Numeric value representing the number of text

                             columns on screen.

    LLG_MODE_GRAPH_ROW       Numeric value representing the number of

                             graphic rows on screen.

    LLG_MODE_GRAPH_COL       Numeric value representing the number of

                             graphic columns on screen.

    LLG_MODE_FONT_ROW        Numeric value representing the number of

                             graphic rows per character.

    LLG_MODE_FONT_COL        Numeric value representing the number of

                             graphic columns per character.

    LLG_MODE_COLOR_MAX       Numeric value representing the number of

                             available colors.

    LLG_MODE_IN_USE          Numeric value representing the video mode that

                             was in use before calling GMODE().  See table

                             in the Arguments section.

    LLG_MODE_LIB_VERSION     Numeric value representing the version of the

                             LLIBG library.

    LLG_MODE_LST_COLOR       Numeric value representing the last color used

                             in a GXXX()function.  This value will be used

                             in the next call to a GXXX() function if the

                             color parameter is not defined.  The initial

                             value is 7.

    LLG_MODE_LST_MODE        Numeric value representing the last mode

                             (SET|AND|OR|XOR).

If nMode is omitted, GMODE() returns the current video mode settings.

Description

The GMODE() function is used to change the video mode or to retrieve information about the current video mode. CA-Clipper graphic mode supports the video modes described above. LLG_VIDEO_TEXT and LLG_VIDEO_VGA_640_480_16 are the only two video modes applicable to CA-Clipper. You can switch between modes at any time in your application. To switch to regular text mode use GMODE(LLG_VIDEO_TXT). The video will not change if GMODE() is called without parameters. GMODE() will return the current video mode information only.

When switching from LLG_VIDEO_TXT to LLG_VIDEO_VGA_640_480_16 mode, all displayed text lines are converted to the equivalent graphic mode display. This conversion does not happen when switching back to text mode. If you need an application to start in graphic mode with an empty screen, call CLS before calling GMODE (LLG_VIDEO_VGA_640_480_16).

Important! To switch video modes, the SET VIDEOMODE command must be used. Without this command, the video mode may not be switched properly.

Notes

During video mode switching, the library calls CA-Clipper’s SetMode() function with 25,80 as parameters. If you use other values, the call to GMODE() should be followed with a call to SETMODE (nYourRow,nYourCol).

In graphic mode, you have access to all available screen lines and columns. Any call to SetMode() with a number of lines less than or equal to 30 causes CA-Clipper graphic mode to use a 16-pixel font that yields 30 lines.

For example, if you call SETMODE (25,80) with a font that is 8 pixels wide by 16 pixels high, and switch video mode to LLG_VIDEO_VGA_640_480_16, the same font is used. You get an additional 5 rows of text to the specified 25 i.e.,(480/16) = 30 rows of text!

CA-Clipper uses the following chart for calculating font sizes based on video settings:

SetMode(nRow, nColumn) Calculation Chart

    nRow      Fonts          Number of Rows Available

    31- 34    14-pixel font  34

    43        See note below

    60+       8-pixel font   60

Note: The 43-line mode being an EGA emulation of a VGA card, is not available in 640 x 480 x 16 mode.

The following are the available settings:

Available Settings

    Wide / High Pixels     Column / Row

    640 x  480             80 x  30 or 80 x  60

    800 x  592             100 x  37 or 100 x  74

    1024 x  768            128 x  48 or 100 x  96

    1280 x 1024            160 x  64 or 160 x 128

During the execution of a QUIT or on the last RETURN of your application, the application is automatically set back to the starting video mode, which is usually text mode.

Note: CA-Clipper uses the ROM fonts of your VGA video card. This allows you to speed up text display. It guarantees zero use of main memory since no font loading is required, even in graphic mode. You can also avoid having to provide one or more font files with the .EXE.

Examples

■  This example executes an entire application in graphic mode:

   // Switch to graphic mode
   SET VIDEOMODE TO LLG_MODE_VGA_640_480_16

   // This is equivalent to GMODE (LLG_VIDEO_VGA_640_480_16)
   // Your CA-Clipper instructions will now operate
   // in graphic mode!
   .
   .
   .
   QUIT                            // End of application

■  This example stores the graphic mode parameters in variables
   which can be used later on in an application:

// Switch to graphic mode and save the current graphic mode
   // settings
   SET VIDEOMODE TO LLG_MODE_VGA_640_480_16
   aMode := GMODE()
   // Store the different values
   nTxtRow    := aMode[LLG_MODE_TEXT_ROW]
   nTxtCol    := aMode[LLG_MODE_TEXT_COL]
   nGraRow    := aMode[LLG_MODE_GRAPH_ROW]
   nGraCol    := aMode[LLG_MODE_GRAPH_COL]
   nFonRow    := aMode[LLG_MODE_FONT_ROW]
   nFonCol    := aMode[LLG_MODE_FONT_COL]
   nColorMax  := aMode[LLG_MODE_COLOR_MAX]
   nVideoMode := aMode[LLG_MODE_IN_USE]

   nLibVer    := aMode[LLG_MODE_LIB_VERSION]
   nLstColor  := aMode[LLG_MODE_LST_COLOR]
   nLstMode   := aMode[LLG_MODE_LST_MODE]

■  This example creates two pseudo-functions which return the
   number of lines and columns in pixels, similar to the way MaxRow()
   and MaxCol() return line and column values:

   #translate GMAXROW()   => GMODE()[LLG_MODE_GRAPH_ROW]
   #translate GMAXCOL()   => GMODE()[LLG_MODE_GRAPH_COL]

■  This is a similar function that returns the number of colors
   available:

   #translate GMAXCOLOR() => GMODE()[LLG_MODE_COLOR_MAX]

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GOHarbour implementation⌃ | ☰

Move the pointer to the specified identity

Syntax

GO[TO] <xIdentity> | BOTTOM | TOP

Arguments

xIdentity is a unique value guaranteed by the structure of the data file to reference a specific item in a data source (database). In a .dbf, identity is the record number. In other data formats, identity is the unique primary key value.

BOTTOM specifies the last logical record in the current work area.

TOP specifies the first logical record in the current work area.

Description

GO[TO] is a database command that positions the record pointer in the current work area at the specified identity. In an Xbase data structure, this identity is the record number because every record, even an empty record, has a record number. In data structures of different design, identity may be defined as something other than record number.

Examples

■  This example saves the current record number, searches for a
   key, and then restores the record pointer to the saved position:

FUNCTION KeyExists( xKeyExpr )

   LOCAL nSavRecord := RecNo()      // Save the current record
                                    // pointer position
   LOCAL lFound

   SEEK xKeyExpr
   IF ( lFound := Found() )
      .
      .  < statements >
      .
   ENDIF

   GOTO nSavRecord      // Restore the record pointer position

   RETURN ( lFound )

Platforms

Available on MS-DOS

See also

GPOLYGON()


⌃ | ☰

Draw a polygon on screen

Syntax

GPOLYGON(<aVertex>, <lFilled>, <nMode>, <nOutLine>,
   <nFillColor>) → NIL

Arguments

aVertex is an array value representing an array of polygon vertices coordinates.

lFilled is a logical value that creates a filled or non-filled polygon. LLG_FILL or LLG_FRAME are valid constants.

nMode is a numeric value representing the video Mode. The following are valid nMode values. They are all # defines in Llibg.ch.

Display Mode Constants

    Constant       Description

    LLG_MODE_SET   Display in SET mode (ignores any pixels present under the

                   line displayed).  This is the most common display mode.

    LLG_MODE_AND   Display in AND mode (executes an AND on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_OR    Display in OR mode (executes an OR on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_XOR   Display in XOR mode (executes an XOR on pixels present

                   under the line at display time and on the display color).

                   See note.

Note: This method allows you to move objects around on the screen without damaging the background. To retrieve the initial background, just repeat the call for display in XOR mode. If the display mode parameter is missing, the last mode specified in a call to a CA-Clipper graphic function is used.

nOutLine is a numeric value representing the outline color.

nFillColor is a numeric value representing the fill color.

Returns

GPOLYGON() always returns NIL.

Description

GPOLYGON() can be used to create a polygon. Simply pass an array of coordinates which make up the polygon.

Examples

■  The following array of vertices would draw a triangle:

   aVertex := {{1,5},;      // First point
   {20,45},;                  // Second point
   {65,145} ;               // Third point}

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, the header file is Llibg.ch.

See also

GPUTPIXEL()


⌃ | ☰

Draw a pixel on the screen

Syntax

GPUTPIXEL(<nX>, <nY>, <nColor>, <nMode>) → NIL

Arguments

nX and nY define pixel coordinates for row and column on the screen.

nColor is a numeric value representing the display color of the pixel.

The range of values is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are between 0 and 15. In 256-color modes, valid values are between 0 and 255.

nMode is the numeric value representing the video mode. The following are valid nMode values. They are all # defines in Llibg.ch.

Video Mode Constants

    Constant       Description

    LLG_MODE_SET   Display in SET mode (ignores any pixels present under the

                   line displayed).  This is the most common display mode.

    LLG_MODE_AND   Display in AND mode (executes an AND on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_OR    Display in OR mode (executes an OR on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_XOR   Display in XOR mode (executes an XOR on pixels present

                   under the line at display time and on the display color).

                   See note.

Note: This method allows you to move objects around on the screen without damaging the background. To retrieve the initial background, just repeat the call for display in XOR mode. If the display mode parameter is missing, the last mode specified in a call to a CA-Clipper graphic function is used.

Returns

GPUTPIXEL() always returns NIL.

Description

This function can be used to change the color of a specific pixel on the screen.

Examples

■  The following example will put a white pixel at X-coordinate
   200 and Y-coordinate 100:

   GPUTPIXEL (200, 100, 15, LLG_MODE_SET)

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GRECT()


⌃ | ☰

Draw a rectangle in graphic mode

Syntax

GRECT(<nXStart>, <nYStart>, <nXEnd>, <nYEnd>,
   [<nStyle>], [<nColor>], [<nMode>]) → NIL

Arguments

nXStart, nYStart, nXEnd and nYEnd define the rectangle coordinates in pixels.

nStyle defines the style of the rectangle using one of the constants listed in the table below:

Style Mode Constants

    Constant     Description

    LLG_FILL     The rectangle is displayed first and then it is filled with

                 the color and mode specified below

    LLG_FRAME    Display of the rectangle is restricted to its contour in

                 the color and mode specified below

nColor is a numeric value that represents the display color. If this parameter is missing, the last color specified in a call to a CA-Clipper graphic function is used. The value range of values is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are between 0 and 15. In 256-color modes, valid values are between 0 and 255.

nMode represents the display mode. The following are valid nMode values:

Display Mode Constants

    Constant       Description

    LLG_MODE_SET   Display in SET mode (ignores any pixels present under the

                   line displayed).  This is the most common display mode.

    LLG_MODE_AND   Display in AND mode (executes an AND on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_OR    Display in OR mode (executes an OR on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_XOR   Display in XOR mode (executes an XOR on pixels present

                   under the line at display time and on the display color).

                   See note.

Note: This method allows you to move objects around on the screen without damaging the background. To retrieve the initial background, just repeat the call for display in XOR mode. If the display mode parameter is missing, the last mode specified in a call to a CA-Clipper graphic function is used.

Returns

GRECT() always returns NIL.

Description

GRECT() draws filled or empty rectangles on the screen. This function can be used only if you have set the screen to a graphic mode using GMODE(). It respects the constraints defined by GSETCLIP().

Examples

■  This example shows how to display a rectangle in a region
   restricted by clipping:

   // Switch to graphic mode
   SET VIDEOMODE LLG_VIDEO_VGA_640_480_16)
   // Restrict the display region to one portion of the screen
   GSETCLIP(100,100,300,300)
   // Draw a filled rectangle that is partially clipped
   GRECT(120,120,350,350,LG_FILL,2,LLG_MODE_SET)
   QUIT                               // End of application

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GSETCLIP()


⌃ | ☰

Define the allowed display area

Syntax

GSETCLIP([<nX1>, <nY1>, <nX2>, <nY2>]) → aOldRegion

Arguments

nX1 is a numeric value representing the left X-axis (column) position of the region in pixels.

nY1 is a numeric value representing the top Y-axis (row) position of the region in pixels.

nX2 is a numeric value representing the right X-axis (column) position of the region in pixels.

nY2 is a numeric value representing the bottom Y-axis (row) position of the region in pixels.

Either all parameters should be specified or none.

Returns

GSETCLIP() returns an array of four numbers representing the new clipping region if you specify all arguments, and the current region if you specify none.

Description

GSETCLIP() limits the active display to a portion of the screen. This function applies only to CA-Clipper graphic mode functions beginning with «G», such as GRECT(), GLINE(), GBMPDISP(). Text emulation functions such as DevOut() and QOut() are not affected by setting clipping regions. To enhance redraw speed, clipping of the function for rewriting text in GWRITEAT() graphic mode is simplified. CA-Clipper graphic mode checks whether each character displayed fits entirely in the clipping region. If it does, the character is displayed; otherwise, it is not.

Notes

The clipping region is initialized to be the entire screen. To specify maximum clipping (which amounts to eliminating clipping altogether), you need to pass parameters to GSETCLIP() corresponding to the entire screen. There are two ways to do this:

■ Save the clipping state immediately after the change. This is

equivalent to the whole screen at that instant:

SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16 // Retrieve clipping value aMaxClip := GSETCLIP() // Execute clipping GSETCLIP(nCoord list) . . . // Your code . . . // Retrieve clipping value GSETCLIP(aMaxClip[1] , aMaxClip[2] , aMaxClip[3] , aMaxClip[4])

■ Use GMODE() which returns the screen size in pixels:

// Switch to graphic mode SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16

// Perform clipping GSETCLIP(nCoord list) . . . // Your code . . . // Retrieve clipping value GSETCLIP(0, 0, ; GMODE()[LLG_MODE_GRAPH_ROW], ; GMODE()[LLG_MODE_GRAPH_COL])

Examples

■  This example restricts display to a portion of the screen:

// Switch to graphic mode
   SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16


   // Restrict the display region
   GSETCLIP(100, 100, 300, 300)

   DO WHILE ! (Inkey() == K_ESC)
      AreaDraw()                 // Call a drawing function
   ENDDO
   QUIT                           // End of application

■  This example stores clipping region parameters for later use:

   // Switch to graphic mode
   SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16

   // Retrieve current values
   aOldRegion := GSETCLIP()

   // Restrict display region to a portion of the screen
   GSETCLIP(100,100,300,300)

   DO WHILE !(Inkey() == K_ESC)
      AreaDraw()
      // Call a function that draws something
   ENDDO

   // Reset original clipping regions
   GSETCLIP(aOldRegion[1],;
      aOldRegion[2],;
      aOldRegion[3],;
      aOldRegion[4])
   QUIT                        // End of application

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GSETEXCL()


⌃ | ☰

Define a screen region to be excluded from display

Syntax

GSETEXCL([<nExclArea>]|[<nTop>, <nLeft>, <nBottom>,
   <nRight>, <nType>]) → NIL

Arguments

nExclArea is a numeric value representing the exclusion area number.

nTop, nLeft, nBottom, nRight, and nType define the exclusion area coordinates.

Coordinate Type Constants

    Constant          Description

    LLM_COOR_TEXT     <nTop> which is the default, is the row line number.

    LLM_COOR_GRAPH    <nTop> is the row in pixels.

Note: Either zero, nExclArea, or all other parameters should be specified.

Returns

If nExclArea is specified, an array of exclusion area coordinates for nExclArea is returned. GSETEXCL(LLG_EXCL_KILL_ALL) deletes all previously defined exclusion areas. If no arguments are specified, GSETEXCL() returns the number of active exclusion areas. If nTop, nLeft, nBottom, nRight,and nType are specified, NIL is returned.

Description

This function is used to prevent output from being displayed in a defined region of the screen. The GSETEXCL() function is probably the most complex function in CA-Clipper graphic mode. If you have never used the DispBegin() and DispEnd() functions, please read CA-Clipper’s documentation for further explanation of these two functions. Essentially, these functions are used to trap or «buffer» all screen output. DispBegin() initiates the buffering and DispEnd() stops the buffering and updates the screen.

GSETEXCL() is the opposite of GSETCLIP(). GSETEXCL() and GSETCLIP() must never be used at the same time. A call to GSETCLIP() will destroy all previously defined exclusion areas. CA-Clipper internally maintains exclusion areas as if they were multiple inclusion areas.

To understand GSETEXCL(), imagine a cascading window system with three windows, A, B and C:

Our goal is to display information in window A while it is covered by windows B and C.

■ Old text mode technique: Using CA-Clipper in text mode and

assuming you saved each window region prior to painting the window boxes, you would probably do the following:

1. Issue a DispBegin() to activate video buffering.

2. Pop off each screen by individually saving the current screens

and immediately restoring that window’s previous background, starting with window C, and then doing window B. For example,

cNewScrC := SaveScreen(nTop, nLeft, nBottom, nRight) RestScreen(nTop, nLeft, nBottom, nRight,cOldScrC) cNewScrB := SaveScreen(nTop, nLeft, nBottom, nRight) RestScreen(nTop, nLeft, nBottom, nRight,cOldScrB)

3. At this point, window A is the only window visible and it is

easy to manipulate or paint information in window A.

4. You would then save and redisplay window B and C, for example,

cOldScrC := SaveScreen(nTop, nLeft, nBottom, nRight) RestScreen(nTop, nLeft, nBottom, nRight,cNewScrC) cOldScrB := SaveScreen(nTop, nLeft, nBottom, nRight) RestScreen(nTop, nLeft, nBottom, nRight,cNewScrB)

5. Issue a DispEnd() because up to now the user has not seen any

screen activity since every screen output function has been buffered!

By issuing a DispEnd(), ALL of the buffered data is instantly flushed to the screen. Essentially the user sees only the final screen and not the intermediate screen activity along the way. The user is not aware of the displaying and redisplaying of windows B and C. This provides a smooth visual effect. This buffering method is available in text mode because display orders are fast, simple and the memory needed to save a full screen is small (4KB).

■ New graphic mode technique: The situation is totally

different in graphic mode. DispBegin() and DispEnd() are not enabled in CA-Clipper graphic mode. CA-Clipper uses exclusion areas instead of removing windows until we have the desired window current. This exclusion area concept is used in almost every graphical system, including Microsoft Windows. An exclusion area is simply a defined screen region which is prevented from having data written to it.

In the example above, you would declare windows B and C as exclusion areas. This prevents data from being written to these windows. Therefore, when you modify information in window A, windows B and C are not affected. The above example using exclusion areas would be as follows:

GSETEXCL(nTop, nLeft, nBottom, nRight) // Window B coordinates GSETEXCL(nTop, nLeft, nBottom, nRight) // Window C coordinates // Manipulate or paint information in window A. GSETEXCL (LLG_EXCL_KILL_ALL)

Notes

You must reset the exclusion areas once the screen work is completed; otherwise, the exclusion areas remain active. This essentially prevents any data from ever being written to those screen regions. As you can see, DispBegin() and DispEnd() require a lot of work to manage a simple cascade of windows, and the overhead in graphic mode renders the technique unusable. Exclusion zones do not consume memory, are faster, and are simpler to use.

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

GSETPAL()


⌃ | ☰

Change components of a color

Syntax

GSETPAL(<nColor>, <nRedValue>, <nGreenValue>,
   <nBlueValue>) → aOldPalette

GSETPAL() → aOldPalette

GSETPAL(<aPalette>) → aOldPalette

GSETPAL(<nColor>, <aRGB>) → aOldPalette

Arguments

nColor is a numeric value that represents a display color.

The range of values for the parameter is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are between 0 and 15. In 256-color modes, valid values are between 0 and 255.

nRedValue is a numeric value that represents the red component assigned to nColor. Its possible values are from 0 to 63.

nGreenValue is a numeric value that represents the green component assigned to nColor. Its possible values are from 0 to 63.

nBlueValue is a numeric value that represents the blue component assigned to nColor. Its possible values are from 0 to 63.

aFullOldPalette is an array of components in the palette. The structure of the array is { nRedValue, nGreenValue, nBlueValue }.

aRGB is an array of components in the palette. The structure of the array is { nRedValue, nGreenValue, nBlueValue }.

Returns

aOldPalette represents an array of components in palette:

aOldPalette := { nRedValue, nGreenValue, nBlueValue }

Description

The GSETPAL() function changes a color’s basic component values. This function must be called for each color if you want to change the palette. It can be used in text or graphic mode.

Notes

CA-Clipper saves the VGA|VESA environment including the palette. It also saves the first call to GMODE() or SET VIDEOMODE. When you do a QUIT or reach the last RETURN of your application, your initial video mode is automatically restored. You do not need to save the original color palette.

Examples

■  This example stores a video mode's color components in a
   multidimensional array.  It is identical to calling GSETPAL() with no
   parameters:

   FUNCTION aPalSave()
      LOCAL aPalStore := {}
      LOCAL nI        := 0

   // For all colors in the current video mode
      FOR nI := 1 TO GMODE()[LLG_MODE_COLOR_MAX]
   // Save color reference and color components
         AAdd(aPalStore, {nI-1,;
            GSETPAL(nI-1)[1],;
            GSETPAL(nI-1)[2],;
            GSETPAL(nI-1)[3]})
      NEXT nI
      // Return an array of arrays
      RETURN aPalStore

■  This example loads all color components of a video mode using
   a multidimensional array which contains the individual components:

   FUNCTION aPalRest(aPalette)
      LOCAL nI := 0
      // For all the arrays in the major array
      FOR nI := 1 TO Len(aPalette)
      // Reset the color components
         GSETPAL(aPalette[nI,1],;
            aPalette[nI,2],;
            aPalette[nI,3],;
            aPalette[nI,4];)
      NEXT nI
      RETURN aPalette

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

GWRITEAT()


⌃ | ☰

Draw graphic text without background

Syntax

GWRITEAT(<nColStart>, <nLnStart>, <cString>, [<nColor>],
   [<nMode>], [<aFont>]) → nWidth

Arguments

nColStart and nLnStart define graphic text coordinates in pixels.

cStringis a character value representing the character string to be displayed.

nColoris a numeric value representing the display color. If the parameter is missing, the last color specified in a call to a CA-Clipper graphic function is used.

The range of values is limited to the number of colors available in the selected video mode. In 16-color modes, valid values are between 0 and 15. In 256-color modes, valid values are between 0 and 255.

nMode is a numeric value representing the display mode. The following are valid nMode values. They are all #defines in Llibg.ch.Display color

Display Mode Constants

    Constant       Description

    LLG_MODE_SET   Display in SET mode (ignores any pixels present under the

                   line displayed).  This is the most common display mode.

    LLG_MODE_AND   Display in AND mode (executes an AND on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_OR    Display in OR mode (executes an OR on pixels present

                   under the line at display time and on the display color).

    LLG_MODE_XOR   Display in XOR mode (executes an XOR on pixels present

                   under the line at display time and on the display color).

                   See note.

    LLG_MODE_NIL   Allows you to compute the width of the string without

                   displaying anything on the screen.  Be aware that .FNT

                   fonts are proportional, which means that an «m» and an

                   «i» do not use the same number of pixels.

Note: This method allows you to move objects around on the screen without damaging the background. To retrieve the initial background, just repeat the call for display in XOR mode. If the display mode parameter is missing, the last mode specified in a call to a CA-Clipper graphic function is used.

aFont is an optional font array pointer which was created with the GFNTLOAD(«MyFont.FND») function:

FUNCTION ShowOneFont (cString)

LOCAL aFont // Load a specific font file into memory aFont := GFNTLOAD(«MyFont.FND») // Display cString using the loaded font

GWRITEAT(X , Y , cString, nColor, LLG_MODE_SET, aFont) // Important // You must erase the font if it is no longer used. GFNTERASE(aFont) RETURN NIL

Returns

GWRITEAT() returns the width of the written text in pixels.

Description

GWRITEAT() displays text in graphic mode without affecting the background. It is important not to confuse the functions DevOut() and GWRITEAT(). Even when you are in graphic mode, you should continue to use DevPos(), DevOut(), and QOut() for all «normal» displays. The functions related to GETs, TBROWSE, etc. use both foreground and background colors, and text can only be displayed in areas whose size is a multiple of the selected font size.

Notes

GWRITEAT() should be used for graphic enhancements, such as a window title within its frame (as you do not want to overwrite the window frame’s borders), or to display information in graphic areas where you want to explicitly handle whether or not the background is erased before a new display, as in adding a title to a bitmap.

Unlike DevOut(), this function receives graphic coordinates only. This allows you to display text pixel by pixel. Since GWRITEAT() works with pixel coordinates instead of row and column coordinates, you may need to properly calculate nX and nY. This function can be used only if you have set the screen to a graphic mode using SET VIDEOMODE().

This function respects the constraints defined by GSETCLIP().

Examples

■  This example writes a see-through title on the frame of a 3-D
   box:

   // Switch to graphic mode
   SET VIDEOMODE TO LLG_VIDEO_VGA_640_480_16
   // Display a 3D box of constant width 16x16x16x16
   DispBox(nTop, nLeft, nBottom, nRight, LLG_BOX_GRAY_SQUARE)
   // Write the alias name transparently in the 3D frame
   GWRITEAT( nLeft * GMODE()[LLG_MODE_FONT_COL],;
   nTop  * GMODE()[LLG_MODE_FONT_ROW],;
   Alias(Select()),;
   4,;
   LLG_MODE_SET)
   QUIT                            // End of application

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

HardCR()Harbour implementation


⌃ | ☰

Replace all soft carriage returns in a character string with hard carriage returns

Syntax

HardCR(<cString>) → cConvertedString

Arguments

cString is the character string or memo field to be converted.

Returns

HardCR() returns a character string up to 65,535 (64K) characters in length.

Description

HardCR() is a memo function that replaces all soft carriage returns (Chr(141)) with hard carriage returns (Chr(13)). It is used to display long character strings and memo fields containing soft carriage returns with console commands. In CA-Clipper, console commands (including REPORT and LABEL FORM) do not automatically convert soft carriage returns to hard carriage returns, making it necessary for you to explicitly make the conversion. Soft carriage returns are added by MemoEdit() when lines wrap.

Notes

HardCR() in REPORT and LABEL FORMs: If HardCR() is used in a

REPORT FORM or LABEL FORM contents expression and nowhere else, you must declare it EXTERNAL to ensure that it is linked.

HardCR() does not remove a soft carriage return if it is

specified alone (i.e. HARDCR (Chr(141) ). It requires the combination of a soft carriage return and a line feed, i.e., Chr(141) + Chr(10).

Examples

■  To display a memo field formatted with the automatic word
   wrapping of MemoEdit():

   USE Sales NEW
   ? HardCR(Sales->Notes)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

Header()Harbour implementation


⌃ | ☰

Return the current database file header length

Syntax

Returns

Header() returns the number of bytes in the header of the current database file as an integer numeric value. If no database file is in use, Header() returns a zero (0).

Description

Header() is a database function that is used with LastRec(), RecSize(), and DiskSpace() to create procedures for backing up files.

By default, Header() 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 (see example below).

Examples

■  This example determines the header size of Sales.dbf:

   USE Sales NEW
   ? Header()            // Result: 258

■  This example defines a pseudofunction, DbfSize(), that uses
   Header() with RecSize() and LastRec() to calculate the size of the
   current database file in bytes:

   #define DbfSize()      ((RecSize() * LastRec()) + ;
         Header() + 1)

   Later you can use DbfSize() as you would any function:

   USE Sales NEW
   USE Customer NEW
   ? DbfSize()
   ? Sales->(DbfSize())

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

I2Bin()Harbour implementation


⌃ | ☰

Convert a CA-Clipper numeric to a 16-bit binary integer

Syntax

I2Bin(<nInteger>) → cBinaryInteger

Arguments

nInteger is an integer numeric value to be converted. Decimal digits are truncated.

Returns

I2Bin() returns a two-byte character string containing a 16-bit binary integer.

Description

I2Bin() is a low-level file function that converts an integer numeric value to a character string formatted as a binary integer—least significant byte first. I2Bin() is used with FWrite() to convert a CA-Clipper numeric to a standard binary form. The inverse of I2Bin() is Bin2I().

Examples

■  This example opens a database file using low-level file
   functions and writes a new date of the last update to bytes 1-3:

   #include "Fileio.ch"
   //
   nHandle = FOpen("Sales.dbf", FO_READWRITE)
   //
   // Convert date of last update to int
   nYear = I2Bin(90)
   nMonth = I2Bin(12)
   nDay = I2Bin(15)
   //
   // Point to the date of last update
   FSeek(nHandle, 1, FS_SET)
   //
   // Write the new update date using only the first byte
   FWrite(nHandle, nYear, 1)
   FWrite(nHandle, nMonth, 1)
   FWrite(nHandle, nDay, 1)
   FClose(nHandle)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM.

See also

IF⌃ | ☰

Execute one of several alternative blocks of statements

Syntax

IF <lCondition1>
   <statements>...
[ELSEIF <lCondition2>]
   <statements>...
[ELSE]
   <statements>...
END[IF]

Arguments

lCondition is a logical control expression. If it evaluates to true (.T.), all following statements are executed until an ELSEIF, ELSE, or ENDIF is encountered.

ELSEIF lCondition identifies statements to execute if the associated condition evaluates to true (.T.) and all preceding IF or ELSEIF conditions evaluate to false (.F.). Any number of ELSEIF statements can be specified within the same IF...ENDIF control structure.

ELSE identifies statements to execute if the IF and all preceding ELSEIF conditions evaluate to false (.F.).

Description

The IF control structure works by branching execution to statements following the first true (.T.) evaluation of the IF or any ELSEIF condition. Execution then continues until the next ELSEIF, ELSE, or ENDIF is encountered whereupon execution branches to the first statement following the ENDIF.

If no condition evaluates to true (.T.), control passes to the first statement following the ELSE statement. If an ELSE statement is not specified, control branches to the first statement following the ENDIF statement.

IF...ENDIF structures may be nested within IF...ENDIF structures and other control structure commands. These structures, however, must be nested properly.

The IF...ELSEIF...ENDIF form of the IF construct is identical to DO CASE...ENDCASE. There is no specific advantage of one syntax over the other. The IF construct is also similar to the IF() function which can be used within expressions.

Examples

■  This example evaluates a number of conditions using an
   IF...ELSEIF...ENDIF construct:

   LOCAL nNumber := 0
   //
   IF nNumber < 50
      ? "Less than 50"
   ELSEIF nNumber = 50
      ? "Is equal to 50"
   ELSE
      ? "Greater than 50"
   ENDIF

Platforms

Available on MS-DOS

See also

BEGIN SEQUENCE, DO CASE, DO WHILE, FOR, IF()

IF()


⌃ | ☰

Return the result of an expression based on a condition

Syntax

IF(<lCondition>, <expTrue>, <expFalse>) → Value

Arguments

lCondition is a logical expression to be evaluated.

expTrue is the value, a condition-expression, of any data type, returned if lCondition is true (.T.).

expFalse is the value, of any date type, returned if lCondition is false (.F.). This argument need not be the same data type as expTrue.

Returns

IF() returns the evaluation of expTrue if lCondition evaluates to true (.T.) and expFalse if it evaluates to false (.F.). The value returned is the data type of the valid condition-expression.

Description

IF() is a logical conversion function. It is one of the most powerful and versatile functions in CA-Clipper. It provides a mechanism to evaluate a condition within an expression. With this ability you can convert a logical expression to another data type.

Examples

■  This example converts a logical data value to a numeric data
   value:

   lPaid = .T.
   ? IF(lPaid, 1, 0)               // Result: 1

■  In this example a logical field is formatted depending on
   whether the Customer is past due or not:

   @ Row() + 1, 25 SAY IF(lPaid, Space(10), "Go get 'em")

■  If you are printing forms, you can print an indicating symbol
   in different columns depending on the value of a logical field:

   @ Row(), IF(InHospital, 10, 12) SAY "X"

■  You can also use IF() to force the LABEL FORM to print blank
   lines.  Enter the following expression when you create the label with
   RL.EXE:

   IF(Empty(Company), Chr(255), Company)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

IIF()


⌃ | ☰

Return the result of an expression based on a condition

Syntax

[I]IF(<lCondition>, <expTrue>, <expFalse>) → Value

Arguments

lCondition is a logical expression to be evaluated.

expTrue is the value, a condition-expression, of any data type, returned if lCondition is true (.T.).

expFalse is the value, of any date type, returned if lCondition is false (.F.). This argument need not be the same data type as expTrue.

Returns

IIF() returns the evaluation of expTrue if lCondition evaluates to true (.T.) and expFalse if it evaluates to false (.F.). The value returned is the data type of the valid condition-expression.

Description

IIF() is a logical conversion function. It is one of the most powerful and versatile functions in CA-Clipper. It provides a mechanism to evaluate a condition within an expression. With this ability you can convert a logical expression to another data type.

Examples

■  This example converts a logical data value to a numeric data
   value:

   lPaid = .T.
   ? IIF(lPaid, 1, 0)               // Result: 1

■  In this example a logical field is formatted depending on
   whether the Customer is past due or not:

   @ Row() + 1, 25 SAY IIF(lPaid, Space(10), "Go get 'em")

■  If you are printing forms, you can print an indicating symbol
   in different columns depending on the value of a logical field:

   @ Row(), IIF(InHospital, 10, 12) SAY "X"

■  You can also use IIF() to force the LABEL FORM to print blank
   lines.  Enter the following expression when you create the label with
   RL.EXE:

   IIF(Empty(Company), Chr(255), Company)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

IndexExt()


⌃ | ☰

Return the default index extension based on the database driver currently linked

Syntax

Returns

Unless you have linked another database driver, IndexExt() returns «.ntx» to indicate that the default CA-Clipper driver is in effect. If the dBASE III PLUS compatible database driver is linked, the function returns «.ndx».

Description

IndexExt() returns the default index file extension by determining which database driver is currently linked. Note that it is preferable to use ordBagExt() than IndexExt().

Notes

IndexExt() returns the default index extension of the

driver loaded, not the actual index file extension. If no driver is loaded, «.ntx» is returned.

Examples

■  In this example, IndexExt() creates an existence test for the
   Customer index file independent of the database driver linked into
   the current program:

   USE Customer NEW
   //
   IF .NOT. FILE("Customer" + IndexExt())
      INDEX ON CustName TO Customer
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

IndexKey()Harbour implementation


⌃ | ☰

Return the key expression of a specified index

Syntax

IndexKey(<nOrder>) → cKeyExp

Arguments

nOrder is the ordinal position of the index in the list of index files opened by the last USE...INDEX or SET INDEX TO command for the current work area. A zero value specifies the controlling index, without regard to its actual position in the list.

Returns

IndexKey() returns the key expression of the specified index as a character string. If there is no corresponding index or if no database file is open, IndexKey() returns a null string («»).

Description

IndexKey() is a database function that determines the key expression of a specified index in the current work area and returns it as a character string. To evaluate the key expression, specify IndexKey() as a macro expression like this: &(IndexKey(nOrder)).

IndexKey() has a number of applications, but two specific instances are important. Using IndexKey(), you can TOTAL on the key expression of the controlling index without having to specify the key expression in the source code. The other instance occurs within a dbEdit() user function. Here, you may want to determine whether or not to update the screen after the user has edited a record. Generally, it is only necessary to update the screen if the key expression of the controlling index has changed for the current record. Both of these examples are illustrated below.

By default, IndexKey() operates on the currently selected work area. It can be made to operate on an unselected work area by specifying it within an aliased expression (see example below).

Examples

■  This example accesses the key expression of open indexes in
   the current work area:

   #define ORD_NATURAL      0
   #define ORD_NAME         1
   #define ORD_SERIAL      2
   //
   USE Customer INDEX Name, Serial NEW
   SET ORDER TO ORD_SERIAL
   ? IndexKey(ORD_NAME)         // Result: Name index exp
   ? IndexKey(ORD_SERIAL)      // Result: Serial index exp
   ? IndexKey(ORD_NATURAL)      // Result: Serial index exp

■  This example accesses the key expression of the controlling
   index in an unselected work area:

   USE Customer INDEX Name, Serial NEW
   USE Sales INDEX Salesman NEW
   ? IndexKey(0), Customer->(IndexKey(0))

■  This example uses IndexKey() as part of a TOTAL ON key
   expression.  Notice that IndexKey() is specified using a macro
   expression to force evaluation of the expression:

   USE Sales INDEX Salesman NEW
   TOTAL ON &(IndexKey(0)) FIELDS SaleAmount TO ;
         SalesSummary

■  This example uses IndexKey() to determine whether the dbEdit()
   screen should be updated after the user has edited the current field
   value.  Generally, you must update the dbEdit() screen if the user
   changes a field that is part of the controlling index key.
   FieldEdit() is a user-defined function called from a dbEdit() user
   function to edit the current field if the user has pressed an edit
   key.

   #include "Dbedit.ch"
   #define ORD_NATURAL   0
   FUNCTION FieldEdit()
      LOCAL indexVal
      // Save current key expression and value
      indexVal = &(IndexKey(ORD_NATURAL))
      .
      . <code to GET current field value>
      .
      // Refresh screen if key value has changed
      IF indexVal != &(IndexKey(ORD_NATURAL))
         nRequest = DE_REFRESH
      ELSE
         nRequest = DE_CONT
      ENDIF
      RETURN nRequest

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

IndexOrd()Harbour implementation


⌃ | ☰

Return the order position of the controlling index

Syntax

Returns

IndexOrd() returns an integer numeric value. The value returned is equal to the position of the controlling index in the list of open indexes for the current work area. A value of zero indicates that there is no controlling index and records are being accessed in natural order. If no database file is open, IndexOrd() will also return a zero.

Description

IndexOrd() is a database function that determines the position of the controlling index in the list of index files opened by the last USE...INDEX or SET INDEX TO in the current work area. It is often useful to save the last controlling index so it can be restored later.

By default, IndexOrd() 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 (see example below).

Examples

■  This example uses IndexOrd() to save the current order.  After
   changing to a new order, it uses the saved value to restore the
   original order:

   USE Customer INDEX Name, Serial NEW
   nOrder := IndexOrd()                  // Result: 1
   SET ORDER TO 2
   ? IndexOrd()                           // Result: 2
   SET ORDER TO nOrder
   ? IndexOrd()                           // Result: 1

■  This example uses an aliased expression to determine the order
   number of the controlling index in an unselected work area:

   USE Sales INDEX Salesman, CustNum NEW
   USE Customer INDEX Name, Serial NEW
   ? Sales->(IndexOrd())               // Result: 1

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Inkey()Harbour implementation


⌃ | ☰

Extract a character from the keyboard buffer or a mouse event

Syntax

Inkey([<nSeconds>] [,<nEventMask>]) → nInkeyCode

Arguments

nSeconds specifies the number of seconds Inkey() waits for a keypress or mouse event. You can specify the value in increments as small as one-tenth of a second. Specifying zero halts the program until a key is pressed or an unmasked event occurs. If nSeconds is omitted, Inkey() does not wait for a keypress or mouse event.

nEventMask specifies which events should be returned. If nEventMask is omitted, the value represented by the SET EVENTMASK command will be used. If there is no SET EVENTMASK command issued, the default value that will be used is 128 (keyboard events only).

This parameter can be any combination of the following values. The constant values listed below are defined in inkey.ch.

Inkey Constants

    Constant       Value     Descripiton

    INKEY_MOVE     1         Mouse Events

    INKEY_LDOWN    2         Mouse Left Click Down

    INKEY_LUP      4         Mouse Left Click Up

    INKEY_RDOWN    8         Mouse Right Click Down

    INKEY_RUP      16        Mouse Right Click Up

    INKEY_KEYBOARD 128       Keyboard Events

    INKEY_ALL      159       All Mouse and Keyboard Events

Returns

Inkey() returns an integer value from -39 to 386 for keyboard events and integer values from 1001 to 1007 for mouse events. This value identifies either the key extracted from the keyboard buffer or the mouse event that last occurred. If the keyboard buffer is empty, and no mouse events are taking place, Inkey() returns 0. Inkey() returns values for all ASCII characters, function, Alt+Function, Ctrl+Function, Alt+Letter, and Ctrl+Letter key combinations.

Description

Inkey() is a keyboard function that extracts the next key pending in the keyboard buffer or the next mouse event and returns a value representing the appropriate event. The value is also saved internally and can be accessed using LastKey(). If the nSeconds argument is specified and there are no pending keys in the buffer, program execution pauses until a key appears in the keyboard buffer, or an appropriate mouse event occurs, or nSeconds has elapsed. The time Inkey() waits is based on the operating system clock and is not related to the microprocessor speed. If nSeconds is zero, program execution pauses until a key is pressed or an unmasked mouse event occurs. Note that Inkey() is not a wait state and, therefore, SET KEYs are not active.

Inkey() is similar to the NextKey() function. Unlike Inkey(), however, NextKey() reads, but does not extract the key or mouse event. This is useful when you need to test for a key or mouse event without processing it.

Inkey() is the basic primitive of the CA-Clipper system for fetching keys and mouse events. It is used for polling the keyboard, polling the mouse, or pausing program execution. As an example, you can use Inkey() to terminate commands with a record scope such as LIST, LABEL FORM, and REPORT FORM by including it in a WHILE condition.

Examples

■  The following example will inform Inkey() to terminate if the
   left mouse button has been clicked or the right mouse button has been
   clicked.  If no events of this type occur within 10 seconds, Inkey()
   will terminate.

   ? Inkey( 10 , INKEY_LDOWN + INKEY_RDOWN )

Platforms

Available on MS-DOS

INDEXHarbour implementation⌃ | ☰

Create an index file

Syntax

INDEX ON <expKey> [TAG <cOrderName>] [TO <cOrderBagName>]
   [FOR <lCondition>] [ALL]
   [WHILE <lCondition>] [NEXT <nNumber>]
   [RECORD <nRecord>] [REST]
   [EVAL <bBlock>] [EVERY <nInterval>]
   [UNIQUE] [ASCENDING|DESCENDING]
   [USECURRENT] [ADDITIVE]
   [CUSTOM] [NOOPTIMIZE]

Note:  Although both the TAG and the TO clauses are optional, you
must specify at least one of them.

Arguments

expKey is an expression that returns the key value to place in the index for each record in the current work area. expKey can be character, date, logical, or numeric type. The maximum length of the index key expression is determined by the driver.

TAG cOrderName is the name of the order to be created. cOrderName can be any CA-Clipper expression that evaluates to a string constant.

TO cOrderBagName is the name of a disk file containing one or more orders. The active RDD determines the order capacity of an order bag. The default DBFNTX driver only supports single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBFMDX drivers). You may specify cOrderBagName as the file name with or without a path name or extension. If an extension is not provided as part of cOrderBagName, CA-Clipper will use the default extension of the current RDD.

Both the TAG and the TO clauses are optional, but you must use at least one of them.

FOR lCondition specifies the conditional set of records on which to create the order. Only those records that meet the condition are included in the resulting order. lCondition is an expression that may be no longer than 250 characters under the DBFNTX and DBFNDX drivers. The maximum value for these expressions is determined by the RDD. The FOR condition is stored as part of the order bag and used when updating or recreating the index using the REINDEX command. Duplicate key values are not added to the order bag.

Drivers that do not support the FOR condition will produce an «unsupported» error.

The FOR clause provides the only scoping that is maintained for all database changes. All other scope conditions create orders that do not reflect database updates.

ALL specifies all orders in the current or specified work area. ALL is the default scope of INDEX .

WHILE lCondition specifies another condition that must be met by each record as it is processed. As soon as a record is encountered that causes the condition to fail, the INDEX command terminates. If a WHILE clause is specified, the data is processed in the controlling order. The WHILE condition is transient (i.e., it is not stored in the file and not used for index updates and REINDEXing purposes). The WHILE clause creates temporary orders, but these orders are not updated.

Drivers that do not support the WHILE condition will produce an «unsupported» error.

Using the WHILE clause is more efficient and faster than using the FOR clause. The WHILE clause only processes data for which lCondition is true (.T.) from the current position. The FOR clause, however, processes all data in the data source.

NEXT nNumber specifies the portion of the database to process. If you specify NEXT, the database is processed in the controlling order for the nNumber number of identities. The scope is transient (i.e., it is not stored in the order and not used for REINDEXing purposes).

RECORD nRecord specifies the processing of the specified record.

REST specifies the processing of all records from the current position of the record pointer to the end of file (EOF).

EVAL bBlock evaluates a code block every nInterval, where nInterval is a value specified by the EVERY clause. The default value is 1. This is useful in producing a status bar or odometer that monitors the indexing progress. The return value of bBlock must be a logical data type. If bBlock returns false (.F.), indexing halts.

EVERY nInterval is a clause containing a numeric expression that modifies the number of times bBlock is EVALuated. The EVERY option of the EVAL clause offers a performance enhancement by evaluating the condition for every nth record instead of evaluating every record ordered. The EVERY keyword is ignored if you specify no EVAL condition.

UNIQUE specifies that the key value of each record inserted into the order be unique. Duplicate key values are not added to the order.

ASCENDING specifies that the keyed pairs be sorted in increasing order of value. If neither ASCENDING nor DESCENDING is specified, ASCENDING is assumed. Although not stored as an explicit part of the file, ASCENDING is an implicit file attribute that is understood by the REINDEX command.

Drivers that do not support the ASCENDING condition will produce an «unsupported» error. The following keywords are new to CA-Clipper 5.3.

DESCENDING specifies that the keyed pairs be sorted in decreasing order of value. Using this keyword is the same as specifying the Descend() function within expKey, but without the performance penalty during order updates. If you create a DESCENDING index, you will not need to use the Descend() function during a SEEK. DESCENDING is an attribute of the file, where it is stored and used for REINDEXing purposes.

Drivers that do not support the DESCENDING condition will produce an «unsupported» error.

USECURRENT specifies that only records in the controlling order—and within the current range as specified by ORDSETSCOPE()—will be included in this order. This is useful when you have already created a conditional order and want to reorder the records which meet that condition, and/or to further restrict the records meeting a condition. If not specified, all records in the database file are included in the order.

ADDITIVE specifies that any open orders should remain open. If not specified, all open orders are closed before creating the new one. Note, however, that the production index file is never closed.

CUSTOM specifies that a custom built order will be created for RDDs that support them. A custom built order is initially empty, giving you complete control over order maintenance. The system does not automatically add and delete keys from a custom built order. Instead, you explicitly add and delete keys using ordKeyAdd() and ordKeyDel(). This capability is excellent for generating pick lists of specific records and other custom applications.

NOOPTIMIZE specifies that the FOR condition will not be optimized. If NOOPTIMIZE is not specified, the FOR condition will be optimized if the RDD supports optimization.

Description

The INDEX command adds a set of keyed pairs, ordered by expKey to a file specified by cOrderBagName using the database open in the current work area.

In RDDs that support production or structural indexes (e.g., DBFCDX, DBFMDX), if you specify a tag but do not specify an order bag, the tag is created and added to the order bag. 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.

If cOrderBagName does not exist, it is created in accordance with the RDD in the current or specified work area.

If cOrderBagName exists and the RDD specifies that order bags can only contain a single order, cOrderBagName is erased and the new order is added to the order bag and to the order list in the current or specified work area.

If cOrderBagName exists and the RDD specifies that order bags can contain multiple tags, cOrderName is created if it does not already exist; otherwise, cOrderName is replaced in cOrderBagName and the order is added to the order list in the current or specified work area.

ASCENDING or DESCENDING specifies the sequence of keyed pairs in the order. If neither clause is specified, the default is ASCENDING.

If you specify the UNIQUE clause, the resulting order will contain only unique records. Some RDDs may do this by only including record references to a key value once. Others may produce a runtime recoverable error as a non-unique key insertion is attempted.

The EVAL clause lets you specify a code block to be evaluated as each record is placed in the order. The EVERY clause lets you modify how often bBlock is called. Instead of evaluation as each record is placed in the order, evaluation only occurs as every nInterval records are placed in the order.

The INDEX command accepts certain clauses that let the user create conditional and partial orders. Some orders are intended to be maintained across the application, others are considered «temporary» orders.

The FOR clause provides the only order scoping that is permanent and can be maintained across the life of the application. The string passed as the FOR condition is stored within the order for later use in maintaining the order. Though only accessing part of a database, orders created using this clause exist as long as the database is active. The FOR clause lets you create maintainable scoped orders.

The WHILE, NEXT, REST and RECORD clauses process data from the current position of the database cursor in the default or specified work area. If you specify these clauses, the order list remains open and the active order is used to organize the database while it is being created. These clauses let you create temporary (non-maintainable) orders. Orders created using these clauses contain records in which lCondition is true (.T.) at the location of the record pointer.

Notes

RDD support: Not all RDDs support all aspects of the INDEX command. See the «Replaceable Database Driver Architecture» chapter in the Drivers Guide for details on a particular RDD.

Examples

■  The following example creates a simple order (index) based on
   one field (Acct):

   USE Customer NEW
   INDEX ON Customer->Acct TO CuAcct

■  This example creates a conditional order (index) based on a
   FOR clause.  This index will contain only records whose field
   TransDate contains a date greater than or equal to January 1, 1995:

   USE Invoice NEW
   INDEX ON Invoice->TransDate      ;
      TO InDate      ;
      FOR ( Invoice->TransDate >= CToD( "01/01/95" ) )

■  This example creates an order in a multiple-order bag (i.e., a
   tag in
   an index that can support multiple tags in an index file):

   USE Customer NEW
   INDEX ON Customer->Acct TAG CuAcct TO Customer

■  The following example creates an order that calls a routine,
   MyMeter, during its creation:

   #define MTR_INCREMENT   10

   USE Customer NEW
   INDEX ON Customer->Acct TO CuAcct EVAL ;
         {|| MYMETER() } EVERY MTR_INCREMENT

   FUNCTION MYMETER()

      STATIC nRecsDone := 0

      nRecsDone := += MTR_INCREMENT
      ? ( nRecsDone/LastRec() ) * 100

      RETURN (.T.)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

INIT PROCEDURE⌃ | ☰

Declare an initialization procedure

Syntax

INIT PROCEDURE <idProcedure> [(<idParam list>)]
   [FIELD <idField list> [IN <idAlias>]]
   [LOCAL <identifier> [[:= <initializer>]]]
   [MEMVAR <identifer list>]
   .
   . <executable statements>
   .
   [RETURN]

Arguments

INIT PROCEDURE declares a procedure that will be executed at program startup.

idProcedure is the name of the initialization procedure to declare. Initialization procedure names can be any length, but only the first 10 characters are significant. Names may not begin with an underscore but can contain any combination of characters, numbers, or underscores.

idParam list is the declaration of one or more parameter variables. Variables specified in this list are declared local.

FIELD declares a list of identifiers to use as field names whenever encountered. If the IN clause is specified, referring to the declared name includes an implicit reference to the specified alias.

LOCAL declares and, optionally, initializes a list of variables or arrays whose visibility and lifetime is the current procedure.

MEMVAR declares a list of identifiers to use as private or public memory variables or arrays whenever encountered.

RETURN passes control to the next initialization procedure or the first executable routine in the program, if no other initialization procedures are pending.

Description

The INIT PROCEDURE statement declares a procedure that will be executed at program startup. INIT procedures are called prior to the first executable statement in a CA-Clipper application, and are useful for performing common initialization tasks such as reading configuration settings, or opening a communications port.

INIT PROCEDUREs are executed implicitly by CA-Clipper at program startup. The visibility of initialization procedures is restricted to the system; therefore, it is not possible to call an INIT PROCEDURE from a procedure or user-defined function. Each INIT PROCEDURE receives a copy of the DOS command line arguments used to invoke the application.

Control passes from one INIT PROCEDURE to the next until all procedures in the initialization list have been called. Control then passes to the first executable statement in the program.

The ANNOUNCE statement declares a module identifier for a source (.prg) file. Once declared, INIT PROCEDUREs are referenced by this module identifier. An application may use any number of initialization procedures by explicitly REQUESTing their module identifiers.

The INIT PROCEDUREs requested for an application are collectively referred to as the initialization list. There is no default execution order of procedures in the initialization list; however, the following rules apply:

■ The CA-Clipper initialization procedure, CLIPINIT, is always

called first

■ If an INIT PROCEDURE is declared in the same source (.prg)

file as the application’s primary (root) routine, it will be the last initialization procedure called

CLIPINIT is called first to establish system integrity by installing the default error recovery system (ErrorSys). Once CLIPINIT has finished executing, control passes to the next INIT PROCEDURE in the initialization list.

If an error is raised during system initialization, the system returns to DOS, and pending initialization procedures are not called.

Examples

■  The following example uses both INIT and EXIT PROCEDUREs to
   save and restore the context of the operating system. You can have
   your program, "Myfile.prg", REQUEST SaveDos:

   ANNOUNCE SaveDos

   #define DOS_SCREEN    1
   #define DOS_ROW       2
   #define DOS_COL       3
   #define DOS_CURSOR    4
   #define DOS_COUNT     4

   STATIC saSaveDos[ SD_COUNT ]

   INIT PROCEDURE dosSave()
      SAVE SCREEN TO saSaveDos[ DOS_SCREEN ]
      saSaveDos[ DOS_ROW ]    := Row()
      saSaveDos[ DOS_COL ]    := Col()
      saSaveDos[ DOS_CURSOR ] := SetCursor()
      RETURN

   EXIT PROCEDURE dosRestore()
      RESTORE SCREEN FROM saSaveDos[ DOS_SCREEN ]
      SETPOS   ( saSaveDos[ DOS_ROW ], saSaveDos[ DOS_COL ] )
      SetCursor( saSaveDos[ DOS_CURSOR ] )
      RETURN

Platforms

Available on MS-DOS

See also

INPUT*Harbour implementation⌃ | ☰

Enter the result of an expression into a variable

Syntax

INPUT [<expPrompt>] TO <idVar>

Arguments

expPrompt is an optional prompt displayed before the input area. The prompt can be an expression of any data type.

TO idVar specifies the name of the variable to be assigned the evaluation result. If idVar is not visible or does not exist, a private variable is created and assigned the result.

Description

INPUT is a console command and wait state that takes entry from the keyboard in the form of a valid expression of up to 255 characters and any data type. When invoked, INPUT sends a carriage return/linefeed to the screen, displays the prompt, and begins accepting keyboard input at the first character position following the prompt. Input greater than MaxCol() wraps to the next line.

Pressing Return terminates entry of the expression. The expression is then compiled and evaluated using the macro operator (&), and the result assigned to idVar. If the variable is not visible or does not exist, it is created as a private. If no expression is entered, no action is taken.

INPUT supports only two special keys: Backspace and Return. Esc is not supported. Backspace deletes the last character typed. Return confirms entry and is the only key that can terminate an INPUT.

Examples

■  In this example INPUT assigns a keyboard entry to an existing
   local variable:

   LOCAL exp
   INPUT "Expression: " TO exp
   IF exp != NIL
      ? exp
   ELSE
      ? "No expression entered"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

INT()Harbour implementation


⌃ | ☰

Convert a numeric value to an integer

Syntax

Arguments

nExp is a numeric expression to be converted to an integer.

Returns

Int() returns an integer numeric value.

Description

Int() is a numeric function that converts a numeric value to an integer by truncating—not rounding—all digits to the right of the decimal point. Int() is useful in operations where the decimal portion of a number is not needed.

Examples

■  These examples demonstrate the results of various invocations
   of the INT() function:

   ? INT(100.00)               // Result: 100
   ? INT(.5)                     // Result: 0
   ? INT(-100.75)               // Result: -100

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

IsAlpha()Harbour implementation


⌃ | ☰

Determine if the leftmost character in a string is alphabetic

Syntax

IsAlpha(<cString>) → lBoolean

Arguments

cString is the character string to be examined.

Returns

IsAlpha() returns true (.T.) if the first character in cString is alphabetic; otherwise, it returns false (.F.).

Description

IsAlpha() is a character function that determines if the specified string begins with an alphabetic character. An alphabetic character consists of any uppercase or lowercase letter from A to Z. IsAlpha() returns false (.F.) if the string begins with a digit or any other character.

Examples

■  These examples demonstrate various results of IsAlpha():

   ? IsAlpha("AbcDe")               // Result: .T.
   ? IsAlpha("aBcDE")               // Result: .T.
   ? IsAlpha("1BCde")               // Result: .F.
   ? IsAlpha(".FRED")               // Result: .F.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

IsColor()Harbour implementation


⌃ | ☰

Determine if the current computer has color capability

Syntax

IsColor() | ISCOLOUR() → lBoolean

Returns

IsColor() returns true (.T.) if there is a color graphics card installed; otherwise, it returns false (.F.).

Description

IsColor() is a screen function that allows you to make decisions about the type of screen attributes to assign (color or monochrome). Note that some monochrome adapters with graphics capability return true (.T.).

Examples

■  This example installs color attribute variables at runtime:

   IF IsColor()
      cBox  = "BG+/B, W/N"
      cSays = "BG/B, W/N"
      cGets = "W/N, N/W"
   ELSE
      cBox  = "W+"
      cSays = "W/N, N+/W"
      cGets = "W/N, N/W"
   ENDIF
   .
   . <statements>
   .
   SetColor(cSays)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

IsDigit()Harbour implementation


⌃ | ☰

Determine if the leftmost character in a character string is a digit

Syntax

IsDigit(<cString>) → lBoolean

Arguments

cString is the character string to be examined.

Returns

IsDigit() returns true (.T.) if the first character of the character string is a digit between zero and nine; otherwise, it returns false (.F.).

Description

IsDigit() is a character function that determines whether the first character in a string is a numeric digit between zero and nine. If any other character is the first character of the cString, IsDigit() returns false (.F.).

IsDigit() is useful where you need to know if the current character string is a number before converting it to a numeric value with the Val() function.

Examples

■  These examples demonstrate various results of IsDigit():

   ? IsDigit("AbcDe")         // Result: .F.
   ? IsDigit("1abcd")         // Result: .T.
   ? IsDigit(".12345")         // Result: .F.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

IsLower()Harbour implementation


⌃ | ☰

Determine if the leftmost character is a lowercase letter

Syntax

IsLower(<cString>) → lBoolean

Arguments

cString is the character string to be examined.

Returns

IsLower() returns true (.T.) if the first character of the character string is a lowercase letter; otherwise, it returns false (.F.).

Description

IsLower() is a character function that determines whether the first character of a character string is lowercase. It is the inverse of IsUpper() which determines whether a character begins with an uppercase character.

Both IsLower() and IsUpper() relate to the Lower() and Upper() functions which actually convert lowercase characters to uppercase, and vice versa.

Examples

■  These examples demonstrate various results of IsLower():

   ? IsLower("aBcDe")         // Result: .T.
   ? IsLower("AbcDe")         // Result: .F.
   ? IsLower("1abcd")         // Result: .F.
   ? IsLower("abcd")            // Result: .T.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

IsPrinter()Harbour implementation


⌃ | ☰

Determine whether LPT1 is ready

Syntax

Returns

IsPrinter() returns true (.T.) if LPT1 is ready; otherwise, it returns false (.F.).

Description

IsPrinter() is a printer function that determines whether the parallel port (LPT1) is online and ready to print. IsPrinter() is hardware-dependent and, therefore, only works on IBM BIOS compatible systems.

You can check IsPrinter() to make sure the printer is ready before you begin a print operation; however, if an error occurs during the print operation, a runtime error is generated.

Examples

■  This example tests the parallel port for readiness with up to
   25 retries.  If the parallel port is ready, the printer operation
   begins:

   LOCAL nCount := 0, nTimes := 25, lReady
   //
   DO WHILE nCount++ <= nTimes .AND. !(lReady := ;
         IsPrinter())
   ENDDO
   //
   IF lReady
      REPORT FORM Sales TO PRINTER
   ELSE
      ? "Printer not ready..."
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM.

See also

IsUpper()Harbour implementation


⌃ | ☰

Determine if the leftmost character in a string is uppercase

Syntax

IsUpper(<cString>) → lBoolean

Arguments

cString is the character string to be examined.

Returns

IsUpper() returns true (.T.) if the first character is an uppercase letter; otherwise, it returns false (.F.).

Description

IsUpper() is a character function that determines whether the first character of a string is uppercase. It is the inverse of IsLower(). Both IsUpper() and IsLower() relate to the Upper() and Lower() functions which actually convert uppercase characters to lowercase, and vice versa.

Examples

■  These examples illustrate IsUpper() applied to various values:

   ? IsUpper("AbCdE")         // Result: .T.
   ? IsUpper("aBCdE")         // Result: .F.
   ? IsUpper("$abcd")         // Result: .F.
   ? IsUpper("8ABCD")         // Result: .F.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

JOINHarbour implementation⌃ | ☰

Create a new database file by merging records/fields from two work areas

Syntax

JOIN WITH <xcAlias> TO <xcDatabase>
   FOR <lCondition> [FIELDS <idField list>]

Arguments

WITH xcAlias is the name of the work area to merge with records from the current work area. You can specify it either as a literal alias or as a character expression enclosed in parentheses.

TO xcDatabase is the name of the target database file specified either as a literal filename or as a character expression enclosed in parentheses.

FOR lCondition selects only records meeting the specified condition.

FIELDS idField list is the projection of fields from both work areas into the new database file. To specify any fields in the secondary work area, reference them with the alias. If the FIELDS clause is not specified, all fields from the primary work area are included in the target database file.

Description

JOIN creates a new database file by merging selected records and fields from two work areas based on a general condition. JOIN works by making a complete pass through the secondary work area for each record in the primary work area, evaluating the condition for each record in the secondary work area. When the lCondition is true (.T.), a new record is created in the target database file using the FIELDS specified from both work areas.

If SET DELETED is OFF, deleted records in both source files (i.e., the two files being JOINed) are processed. However, their deleted status is not retained in the target xcDatabase. No record in the target file is marked for deletion regardless of its deleted status in either of the source files.

If SET DELETED is ON, no deleted records are processed in either of the source files. Thus, deleted records do not become part of the target xcDatabase. Similarly, filtered records are not processed and do not become part of the target file.

Warning! The number of records processed will be the LastRec() of the primary work area multiplied by the LastRec() of the secondary work area. For example, if you have two database files with 100 records each, the number of records JOIN processes is the equivalent of sequentially processing a single database file of 10,000 records. Therefore, use this command carefully.

Examples

■  This example joins Customer.dbf to Invoices.dbf to produce
   Purchases.dbf:

   USE Invoices NEW
   USE Customers NEW
   JOIN WITH Invoices TO Purchases;
      FOR Last = Invoices->Last;
      FIELDS First, Last, Invoices->Number, ;
         Invoices->Amount

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

KEYBOARDHarbour implementation⌃ | ☰

Stuff a string into the keyboard buffer

Syntax

Arguments

cString is the string to stuff into the keyboard buffer.

Description

KEYBOARD is a keyboard command that stuffs cString into the keyboard buffer after clearing any pending keystrokes. The characters remain in the keyboard buffer until fetched by a wait state such as ACCEPT, INPUT, READ, AChoice(), MemoEdit(), and dbEdit(), or Inkey(). In addition to display characters, cString may include control characters.

Generally, to convert an Inkey() code of a control key to a character value, use Chr(). There are, however, some limitations. You can only stuff characters with Inkey() codes between zero and 255, inclusive, into the keyboard buffer.

Typically, KEYBOARD is used in a SET KEY procedure to reassign keys in a wait state. Another use within the AChoice() user function is to input the keys you want AChoice() to execute before returning control to it. The same concept applies to dbEdit().

Examples

■  This example uses KEYBOARD to stuff a GET with an item
   selected from a picklist each time the GET is entered:

#include "Inkey.ch"
   LOCAL cVar1 := Space(10), nVar := 2500, ;
         cVar2 := Space(10)
   CLEAR
   @ 09, 10 GET cVar1
   @ 10, 10 GET cVar2 WHEN PickList()
   @ 11, 10 GET nVar
   READ
   RETURN

   FUNCTION PickList
      STATIC aList := { "First", "Second", ;
         "Three", "Four" }
      LOCAL cScreen, nChoice, nKey := LastKey()
      cScreen := SaveScreen(10, 10, 14, 20)
      @ 10, 10 TO 14, 20 DOUBLE
      IF (nChoice := AChoice(11, 11, 13, 19, aList)) != 0
         KEYBOARD CHR(K_CTL_Y) + aList[nChoice] + ;
               Chr(nKey)

      ENDIF
      RestScreen(10, 10, 14, 20, cScreen)
      RETURN .T.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is inkey.ch.

See also

L2Bin()Harbour implementation


⌃ | ☰

Convert a CA-Clipper numeric value to a 32-bit binary integer

Syntax

L2Bin(<nExp>) → cBinaryInteger

Arguments

nExp is the numeric value to be converted. Decimal digits are truncated.

Returns

L2Bin() returns a four-byte character string formatted as a 32-bit binary integer.

Description

L2Bin() is a low-level file function used with FWrite() to write CA-Clipper numeric values to a binary file. This function is like I2Bin() which formats a CA-Clipper numeric to a 16-bit binary value.

L2Bin() is the inverse function of Bin2L().

Examples

■  This example creates a new binary file, and then writes a
   series of numbers to the files using L2Bin() to convert the numeric
   value to 32-bit binary form:

   #include "Fileio.ch"
   //
   LOCAL nNumber, nHandle
   nHandle := FCreate("MyFile", FC_NORMAL)
   FOR nNumber := 1 TO 100
      FWrite(nHandle, L2Bin(nNumber) + Chr(0))
   NEXT
   FClose(nHandle)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM.

See also

LastKey()Harbour implementation


⌃ | ☰

Return the Inkey() value of the last key extracted from the keyboard buffer

Syntax

Returns

LastKey() returns an integer value from -39 to 386 for keyboard events and integer values from 1001 to 1007 for mouse events. This value identifies either the key extracted from the keyboard buffer or the mouse event that last occurred. If the keyboard buffer is empty, and no mouse events are taking place, LastKey() returns 0. LastKey() returns values for all ASCII characters, function, Alt+Function, Alt+Letter, and Ctrl+Letter key combinations.

Description

LastKey() is a function that reports the Inkey() value of the last key fetched from the keyboard buffer by the Inkey() function, or the next mouse event, or a wait state such as ACCEPT, INPUT, READ, WAIT, AChoice(), dbEdit(), or MemoEdit(). The time LastKey() waits is based on the operating system clock and is not related to the microprocessor speed. LastKey() retains its current value until another key is fetched from the keyboard buffer.

LastKey() has a number of uses which include:

■ Determining the key that terminates a READ

■ Determining the key that exits the current Get object within a

user-defined function, invoked by a VALID clause

■ Identifying an exception key in the user function of

AChoice(), dbEdit(), or MemoEdit()

LastKey() is also used with Updated() to determine if any Get object’s buffer was changed during a READ.

LastKey() is related to NextKey() and ReadKey(). NextKey() reads the current key pending in the keyboard buffer without removing it. Use NextKey() instead of Inkey() when polling for a key.

For a complete list of Inkey() codes and inkey.ch constants for each key, refer to the Error Messages and Appendices Guide.

Examples

■  This example illustrates a typical application of LastKey() to
   test the key that exits a READ.  If the user exits with any key other
   than Esc and a GET was changed, the specified database file is
   updated:

   #include "Inkey.ch"
   //
   USE Customer NEW
   MEMVAR->balance = Customer->Balance
   @ 10, 10 SAY "Current Balance" GET MEMVAR->balance
   READ
   //
   IF (LastKey() != K_ESC) .AND. Updated()
      REPLACE Customer->Balance WITH MEMVAR->balance

   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is inkey.ch.

See also

LastRec()Harbour implementation


⌃ | ☰

Determine the number of records in the current .dbf file

Syntax

LastRec() | RecCount()* → nRecords

Returns

LastRec() returns the number of physical records in the current database file as an integer numeric value. Filtering commands such as SET FILTER or SET DELETED have no effect on the return value. LastRec() returns zero if there is no database file in USE in the current work area.

Description

LastRec() is a database function that determines the number of physical records in the current database file. LastRec() is identical to RecCount() which is supplied as a compatibility function.

By default, LastRec() 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 (see example below).

Note: Although the functionality of RecNo() has been expanded to encompass the concept of «identity,» the LastRec() function continues to return only record numbers—not identities. LastRec() has no expanded functionality, so it is not «identity-aware.»

Examples

■  This example illustrates the relationship between LastRec(),
   RecCount(), and COUNT:

   USE Sales NEW
   ? LastRec(), RecCount()            // Result: 84 84
   //
   SET FILTER TO Salesman = "1001"
   COUNT TO nRecords
   ? nRecords, LastRec()            // Result: 14 84

■  This example uses an aliased expression to access the number
   of records in a open database file in an unselected work area:

   USE Sales NEW
   USE Customer NEW
   ? LastRec(), Sales->(LastRec())

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

LABEL FORMHarbour implementation⌃ | ☰

Display labels to the console

Syntax

LABEL FORM <xcLabel>
   [TO PRINTER] [TO FILE <xcFile>] [NOCONSOLE]
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
   [SAMPLE]

Arguments

xcLabel is the name of the label (.lbl) file that contains the FORM definition of the LABEL and can be specified either as a literal file name or as a character expression enclosed in parentheses. If an extension is not specified .lbl is assumed.

TO PRINTER echoes output to the printer.

TO FILE xcFile echoes output to xcFile. Specify xcFile as a literal file name or as a character expression enclosed in parentheses. If an extension is not specified, .txt is added.

NOCONSOLE suppresses all LABEL FORM output to the console. If not specified, output automatically displays to the console unless SET CONSOLE is OFF.

scope is the portion of the current database file to display labels. The default is ALL records.

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

FOR lCondition specifies to LABEL FORM, the conditional set of records within the given scope.

SAMPLE displays test labels as rows of asterisks. Each test label has the same number of columns and rows as the label definition. Then, following each test label display, is the query, «Do you want more samples?» Answering «Y» forces another test label display. Answering «N» causes LABEL FORM to display the actual labels for the specified scope and condition.

Description

LABEL FORM is a console command that sequentially accesses records in the current work area, displaying labels using a definition stored in a .lbl file. Create the .lbl using RL.EXE or by dBASE III PLUS. Refer to the «Report and Label Utility» chapter in the Programming and Utilities Guide for more information about creating label definitions.

When invoked, output is sent to the screen and, optionally, to the printer and/or a file. To suppress output to the screen while printing or echoing output to a file, SET CONSOLE OFF before invocation of LABEL FORM or use the NOCONSOLE keyword.

When invoked, LABEL FORM searches the current SET PATH drive and directory, if the xcLabel file is not found in the current directory and the path is not specified.

Notes

■ Interrupting LABEL FORM: To interrupt a LABEL FORM, use

Inkey() as a part of the FOR condition to test for an interrupt key press. See the example below.

■ Printer margin: LABEL FORM obeys the current SET MARGIN for

output echoed to the printer.

Examples

■  This example prints a set of labels and writes them to a file
   with a single command.  Two forms of the command are shown:

   LOCAL cLabel := "Sales", cFile := "Sales"
   USE Sales INDEX Sales NEW
   LABEL FORM Sales TO PRINTER TO FILE Sales
   LABEL FORM (cLabel) TO PRINTER TO FILE (cFile)

■  This example interrupts LABEL FORM using Inkey() to test if
   the user pressed the Esc key:

   #define K_ESC  27
   USE Sales INDEX Sales NEW
   LABEL FORM Sales WHILE Inkey() != K_ESC

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Left()Harbour implementation


⌃ | ☰

Extract a substring beginning with the first character in a string

Syntax

Left(<cString>, <nCount>) → cSubString

Arguments

cString is a character string from which to extract characters. The maximum size of cString is 65,535 (64K) bytes.

nCount is the number of characters to extract.

Returns

Left() returns the leftmost nCount characters of cString as a character string. If nCount is negative or zero, Left() returns a null string («»). If nCount is larger than the length of the character string, Left() returns the entire string.

Description

Left() is a character function that returns a substring of a specified character string. It is the same as SubStr(cString, 1, nCount). Left() is also like Right(), which returns a substring beginning with the last character in a string.

Left(), Right(), and SubStr() are often used with both the At() and RAt() functions to locate the first and/or the last position of a substring before extracting it.

Examples

■  This example extracts the first three characters from the left
   of the target string:

   ? Left("ABCDEF", 3)                  // Result: ABC

■  This example extracts a substring from the beginning of a
   string up to the first occurrence of a comma:

   LOCAL cName := "James, William"
   ? Left(cName, At(",", cName) - 1)   // Result: James

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Len()Harbour implementation


⌃ | ☰

Return the length of a character string or the number of elements in an array

Syntax

Len(<cString> | <aTarget>) → nCount

Arguments

cString is the character string to count.

aTarget is the array to count.

Returns

Len() returns the length of a character string or the number of elements in an array as an integer numeric value. If the character string is a null string («») or the array is empty, Len() returns zero.

Description

Len() is a character and array function that returns the length of a character string or the number of elements in an array. With a character string, each byte counts as one, including an embedded null byte (Chr(0)). By contrast, a null string («») counts as zero.

For an array, Len() returns the number of elements. If the array is multidimensional, subarrays count as one element. This means that the Len() of a nested or multidimensional array simply returns the length of the first dimension. To determine the number of elements in other dimensions, use Len() on the subarrays as shown in the example below. Note that nested arrays in CA-Clipper need not have uniform dimensions.

Examples

■  These examples demonstrate Len() with various arguments:

   ? Len("string of characters")         // Result: 20
   ? Len("")                              // Result: 0
   ? Len(Chr(0))                        // Result: 1
   //
   LOCAL aTest[10]
   ? Len(aTest)                           // Result: 10

■  This example creates a literal two-dimensional array, and then
   returns the number of elements in the subarray contained in the first
   element of the original array:

   LOCAL aArray := { {1, 2}, {1, 2}, {1, 2} }
   ? Len(aArray)                        // Result: 3
   ? Len(aArray[1])                     // Result: 2

■  This example navigates a multidimensional array using Len():

LOCAL aArray := { {1, 2}, {1, 2}, {1, 2} }
   LOCAL nRow, nColumn, nRowCount, nColumnCount

   //
   nRowCount = Len(aArray)
   FOR nRow = 1 TO nRowCount
      nColumnCount = Len(aArray[nRow])
      FOR nColumn = 1 TO nColumnCount
         ? nRow, nColumn, aArray[nRow][nColumn]
      NEXT
   NEXT

■  In this example a function returns an array of numeric values
   that describe the dimensions of a nested or multidimensional array.
   The function assumes that the array has uniform dimensions:

   FUNCTION Dimensions( aArray )
      LOCAL aDims := {}
      DO WHILE ( ValType(aArray) == "A" )
         AAdd( aDims, Len(aArray) )
         aArray := aArray[1]
      ENDDO
      RETURN (aDims)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ListBox class⌃ | ☰

Create a list box

Description

A list box displays a list of strings (or items) to the user. You can use the methods of ListBox to add, arrange, remove, and interrogate the items in a list box.

Methods link

ListBox() Create a new ListBox object


ListBox(nTop, nLeft, nBottom, nRight

[, lDropDown]) → oListBox

Arguments

nTop is a numeric value that indicates the top screen row of the list box.

nLeft is a numeric value that indicates the left screen column of the list box.

nBottom is a numeric value that indicates the bottom screen row of the list box.

nRight is a numeric value that indicates the right screen column of the list box.

lDropDown is an optional logical value that indicates whether the list box is a drop-down list box. A value of true (.T.) indicates that it is a drop-down list box; otherwise, a value of false (.F.) indicates that it is not. The default is false (.F.).

Returns

Returns a ListBox object when all of the required arguments are present; otherwise, ListBox() returns NIL.

Exported Instance Variables


bitmap The bitmap file to display on the button


bitmap (Assignable)

Contains a character string that indicates a bitmap file to be displayed on the button. Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .bml extension.

CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed. This instance variable only affects applications running in graphic mode and is ignored in text mode.

bottom Numeric value indicating bottommost screen row


bottom (Assignable)

Contains a numeric value that indicates the bottommost screen row where the list box is displayed.

buffer Numeric value indicating position of item


buffer

Contains a numeric value that indicates the position in the list of the selected item.

capCol Numeric value indicating location of caption by column


capCol (Assignable)

Contains a numeric value that indicates the screen column where the list box’s caption is displayed.

capRow Numeric value indicating location of caption by row


capRow (Assignable)

Contains a numeric value that indicates the screen row where the list box’s caption is displayed.

caption Character string describing list box


caption (Assignable)

Contains a character string that concisely describes the list box on the screen.

When present, the & character specifies that the character immediately following it in the caption is the list box’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to a list box. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the ListBox object. ListBox:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a ListBox object and retrieved later.

coldBox Optional string specifying characters


coldBox (Assignable)

Contains an optional string that specifies the characters to use when drawing a box around the list box when it does not have input focus. Its default value is a single line box.

Standard Box Types

       Constant            Description

       B_SINGLE            Single line box

       B_DOUBLE            Double line box

       B_SINGLE_DOUBLE     Single line top/bottom, double line sides

       B_DOUBLE_SINGLE     Double line top/bottom, single line sides

Box.ch contains manifest constants for the ListBox:coldBox value.

colorSpec Character string indicating color


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the list box’s display() method. If the list box is a drop-down list, the string must contain eight color specifiers, otherwise it must contain seven color specifiers.

Note: The background colors of the ListBox Color Attributes are ignored in graphic mode.

ListBox Color Attributes

       Position     Applies To                          Default Value from

       in colorSpec                                     System Color Setting

       1            List box items that are not selected      Unselected

                    when the list does not have input focus

       2            The selected list box item when the       Unselected

                    list does not have input focus

       3            List box items that are not selected      Unselected

                    when the list has input focus

       4            The selected list box item when the       Enhanced

                    list has input focus

       5            The list box’s border                     Border

       6            The list box’s caption                    Standard

       7            The list box caption’s accelerator key    Background

       8            The list box’s drop-down button           Standard

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box in the item properties.

dropDown Optional logical value indicating a drop-down list


dropDown

Contains an optional logical value that indicate whether the object is a drop-down list. A value of true (.T.) indicates that it is a drop-down list; otherwise, a value of false (.F.) indicates that it is not. The default is false.

fBlock Code block evaluated at each input focus change


fBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the ListBox object receives or loses input focus. The code block takes no implicit arguments. Use the ListBox:hasFocus variable to determine if the list box is receiving or losing input focus. A value of true (.T.) indicates that it is receiving input focus; otherwise, a value of false (.F) indicates that it is losing input focus.

This code block is included in the ListBox class to provide a method of indicating when an input focus change event has occurred. The name «fBlock» refers to focus block.

hasFocus Logical value indicating the input focus


hasFocus

Contains a logical value that indicates whether the ListBox object has input focus. ListBox:hasFocus contains true (.T.) if it has input focus; otherwise, it contains false (.F.).

hotBox Optional string specifying characters


hotBox (Assignable)

Contains an optional string that specifies the characters to use when drawing a box around the list box when it has input focus. Its default value is a double-line box.

Standard Box Types

       Constant            Description

       B_SINGLE            Single line box

       B_DOUBLE            Double line box

       B_SINGLE_DOUBLE     Single line top/bottom, double line sides

       B_DOUBLE_SINGLE     Double line top/bottom, single line sides

Box.ch contains manifest constants for the ListBox:hotBox value.

isOpen Logical value indicating visibility of list


isOpen

Contains a logical value that indicates whether the list is visible. A value of true (.T.) indicates that the list is visible; otherwise a value of false (.F.) indicates that it is not visible. When ListBox:dropDown is false (.F.), ListBox:isOpen is always true (.T.); otherwise, ListBox:isOpen is true (.T.) during the period of time between calling ListBox:open() and ListBox:close().

itemCount Numeric value total number of items


itemCount

Contains a numeric value that indicates the total number of items contained within the ListBox object.

left Numeric value indicating leftmost screen column


left (Assignable)

Contains a numeric value that indicates the leftmost screen column where the list box is displayed.

message Character string describing the list box


message (Assignable)

Contains a character string that describes the list box. It is displayed on the screen’s status bar line.

right Numeric value indicating rightmost screen column


right (Assignable)

Contains a numeric value that indicates the rightmost screen column where the list box is displayed.

sBlock Code block evaluated at every state change


sBlock (Assignable)

Contains an optional code block that, when present, is evaluated immediately after the ListBox object’s selection changes. The code block takes no implicit arguments. Use the ListBox:buffer variable to determine the current selection.

This code block is included in the ListBox class to provide a method of indicating when a state change event has occurred. The name «sBlock» refers to state block.

top Numeric value indicating topmost screen row


top (Assignable)

Contains a numeric value that indicates the topmost screen row where the list box is displayed.

topItem Numeric value indicating position of first item


topItem (Assignable)

Contains a numeric value that indicates the position in the list box of the first visible item.

typeOut Logical value indicating list contents


typeOut

Contains a logical value that indicates whether the list contains any items. A value of true (.T.) indicates that the list contains selectable items; otherwise, a value of false (.F.) indicates that the list is empty.

vScroll Optional ScrollBar object whose orientation must be vertical


vScroll (Assignable)

Contains an optional ScrollBar object whose orientation must be vertical. The scroll bar thumb position reflects the relationship between the current first visible item on the screen and the total number of possible top items (total number of items — number of visible items — 1).

When present, the scroll bar is automatically integrated within the behaviors of the following ListBox object methods: addItem(), display(), delItem(), HitTest(), insItem(), nextItem(), prevItem(), and Select().

addItem() Appends a new item to a list


oListBox:addItem(cText [, expValue]) → self

cText is a character string that indicates the item’s text to display in the list.

expValue is a value that is associated with the list item. If omitted, the item’s associated data will be NIL.

addItem() is a method of the ListBox class that is used for appending a new item to a list. When adding an item, an optional value may be included. This enables you to associate pertinent data with the text displayed in the list.

Note: When present, the scroll bar is automatically updated to reflect the addition of the new item.

close() Restores screen under drop-down list box


oListBox:close() → self

close() is a method of the ListBox class that is used for restoring the screen under a drop-down list box.

delItem() Removes item from a list


oListBox:delItem(nPosition) → self

nPositionis a numeric value that indicates the position in the list of the item to delete.

delItem() is a method of the ListBox class that is used for removing an item from a list. ListBox:buffer is automatically adjusted when an item is deleted while the last item in the list is selected.

Note: When present, the scroll bar is automatically updated to reflect the deletion of the item.

display() Shows a list box and its caption


oListBox:display() → self

display() is a method of the ListBox class that is used for showing a list and its caption on the screen. display() uses the values of the following instance variables to correctly show the list in its current context, in addition to providing maximum flexibility in the manner a list box appears on the screen: bottom, capCol, capRow, caption, coldBox, colorSpec, hasFocus, hotBox, itemCount, left, right, style, top, topItem, and vScroll.

Note: When present, the scroll bar is automatically displayed when the ListBox:display() method is called.

findText() Determines the position of an item within a list


oListBox:findText(cText [,nPosition]

[,lCaseSensitive] [,lExact]) → nPosition

cText is a character string that indicates the text that is being searched for.

nPosition is an optional numeric value that indicates the starting position in the list of the search. The default is 1.

lCaseSensitive is an optional logical value that indicates whether the search should be case sensitive. Set lCaseSensitive to true (.T.) to indicate that the search should be case sensitive; otherwise, set lCaseSensitive to false (.F.). The default is true (.T.).

lExact is an optional logical value that indicates whether the search enforces an exact comparison including length and trailing characters. A value of true (.T.) indicates that findText() searches for an exact match; otherwise, a value of false (.F.) indicates that it should not. The default is the current setExact() setting.

Returns a numeric value that indicates the position in the list of the first item from nPosition whose text matches cText, or 0 if ListBox:findText() is unsuccessful.

findText() is a method of the ListBox class that is used for determining whether an item is a member of a list and its position within the list. findText() always searches from nPosition to the end of the list and, when necessary, continues from the beginning of the list to nPosition — 1.

getData() Retrieves the data portion of a list box item


oListBox:getData(nPosition) → expValue

nPosition is a numeric value that indicates the position within the list of the item whose data is being retrieved.

Returns the data associated with the item in the list specified by nPosition.

getData() is a method of the ListBox class that is used for retrieving the data portion of a list box item.

getItem() Retrieves a list box item


oListBox:getItem(nPosition) → aItem

nPosition is a numeric value that indicates the position in the list of the item that is being retrieved.

Returns the list box item specified by nPosition expressed as a two-element array consisting of the item’s text and data respectively. The text is a character string that indicates the item’s text to display in the list. The data is a value that is associated with the list item.

getItem() is a method of the ListBox class that is used for retrieving a list box item.

getText() Retrieves the text portion of a list box item


oListBox:getText(nPosition) → cText

nPosition is a numeric value that indicates the position within the list of the item whose text is being retrieved.

Returns the text associated with the item in the list specified by nPosition.

getText() is a method of the ListBox class that is used for retrieving the text portion of a list box item.

HitTest() Indicates position of mouse cursor relative to list box


oListBox:hitTest(nMouseRow, nMouseCol)

→ nhitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the relationship of the mouse cursor with the list box.

Applicable Hit Test Return Values

       Value   Constant       Description

       > 0     Not Applicable The position in the list of the item whose

                              region the mouse is within

       0       HTNOWHERE      The mouse cursor is not within the region of

                              the screen that the list box occupies

       -1      HTTOPLEFT      The mouse cursor is on the top left corner of

                              the list box’s border

       -2      HTTOP          The mouse cursor is on the list box’s top

                              border

       -3      HTTOPRIGHT     The mouse cursor is on the top right corner of

                              the list box’s border

       -4      HTRIGHT        The mouse cursor is on the list box’s right

                              border

       -5      HTBOTTOMRIGHT  The mouse cursor is on the bottom right corner

                              of the list box’s border

       -6      HTBOTTOM       The mouse cursor is on the list box’s bottom

                              border

       -7      HTBOTTOMLEFT   The mouse cursor is on the bottom left corner

                              of the list box’s border

       -8      HTLEFT         The mouse cursor is on the list box’s left

                              border

       -1025   HTCAPTION      The mouse cursor is on the list box’s caption

       -4097   HTDROPBUTTON   The mouse cursor is on the list box’s drop

                              down button

Button.ch contains manifest constants for the ListBox:hitTest() return value.

HitTest() is a method of the ListBox class that is used for determining if the mouse cursor is within the region of the screen that the list box occupies.

Note: When a scroll bar is present, its HitTest() method is automatically called to determine if the mouse cursor is within its region. If ScrollBar:hitTest() succeeds in determining that a «hit» has been achieved, ListBox:hitTest() returns the appropriate scroll bar hit test return code.

insItem() Inserts a new item to a list


oListBox:insItem(nPosition, cText,

[expValue]) → self

nPosition is a numeric value that indicates the position at which the new item is inserted.

cText is the item’s text to display in the list.

expValue is a value that is associated with the list item. If omitted, the item’s associated data will be NIL.

insItem() is a method of the ListBox class that is used for inserting a new item to a list. When inserting an item, an optional value may be included. This enables you to associate pertinent data with the text displayed in the list.

Note: When present, the scroll bar is automatically updated to reflect the insertion of the new item.

killFocus() Takes input focus away from the ListBox object


oListBox:killFocus() → self

killFocus() is a method of the ListBox class that is used for taking input focus away from a ListBox object. Upon receiving this message, the ListBox object redisplays itself and, if present, evaluates the code block within its fBlock variable.

This message is meaningful only when the ListBox object has input focus.

nextItem() Changes selected item to next one


oListBox:nextItem() → self

nextItem() is a method of the ListBox class that is used for changing the selected item from the current item to the one immediately following it. If necessary, nextItem() will call its display() method to ensure that the newly selected item is visible.

This message is meaningful only when the ListBox object has input focus.

Note: When present, the scroll bar is automatically updated to reflect the new first visible item in the list when the call to ListBox:nextItem() causes the list to be scrolled.

open() Saves screen under drop-down list box


oListBox:open() → self

open() is a method of the ListBox class that is used for saving the screen under a drop-down list box and displaying the list.

prevItem() Changes selected item to previous one


oListBox:prevItem() → self

prevItem() is a method of the ListBox class that is used for changing the selected item from the current item to the one immediately before it. If necessary, prevItem() will call its display() method to ensure that the newly selected item is visible.

This message is meaningful only when the ListBox object has input focus.

Note: When present, the scroll bar is automatically updated to reflect the new first visible item in the list when the call to ListBox:prevItem() causes the list to be scrolled.

Scroll() Indicates manner of scroll operation


oListBox:scroll(nMethod) → self

nMethod indicates the manner in which the scroll operation is carried out. A call to ListBox:scroll() is typically issued in response to ScrollBar:hitTest returning that a hit has been established.

ListBox:Scroll Argument Values

       Value     Constant            Result

       -3074     HTSCROLLUNITDEC     Scroll down one line

       -3075     HTSCROLLUNITINC     Scroll up one line

       -3076     HTSCROLLBLOCKDEC    Scroll down one window

       -3077     HTSCROLLBLOCKINC    Scroll up one window

Scroll() is a method of the ListBox class that is used for scrolling the contents of a list box up or down.

Select() Changes the selected item in a list


oListBox:select(nPosition) → self

nPosition is a numeric value that indicates the position in the list of the item to select.

Select() is a method of the ListBox class that is used for changing the selected item in a list. Its state is typically changed when one of the arrow keys is pressed or the mouse’s left button is pressed when its cursor is within the ListBox object’s screen region. If necessary, Select() will call its display() method to ensure that the newly selected item is visible.

Note: When present, the scroll bar is automatically updated to reflect the new first visible item in the list when the call to ListBox:select() causes the list to be scrolled.

setData() Changes the data associated with a list item


oListBox:setData(nPosition, expValue) → self

nPosition is a numeric value that indicates the position of the item within the list whose data is being replaced.

expValue is the data that is being associated with the item specified by nPosition.

setData() is a method of the ListBox class that is used for changing the data that is associated with a list item.

setFocus() Gives input focus to the ListBox object


oListBox:setFocus() → self

setFocus() is a method of the ListBox class that is used for giving focus to a ListBox object. Upon receiving this message, the ListBox object redisplays itself and, if present, evaluates the code block within its fBlock variable.

This message is meaningful only when the ListBox object does not have input focus.

setItem() Replaces an item in a list


oListBox:setItem(nPosition, aItem) → self

nPosition is a numeric value that indicates the position of the item within the list which is being replaced.

aItem is the new list box item expressed as a two-element array consisting of the item’s text and data respectively.

setItem() is a method of the ListBox class that is used for replacing an item in a list.

setText() Changes the text associated with a list item


oListBox:setText(nPosition, cText) → self

nPosition is a numeric value that indicates the position of the item within the list whose text is being replaced.

cText is a character string that indicates the new text for the item specified by nPosition.

setText() is a method of the ListBox class that is used for changing the text that is associated with a list item.

Examples

■  This example shows how the user can select the screen's
   foreground color:

   function SelectFore()
   local cOldWindow, oList, nChoice
   memvar GetList
      cOldWindow := SaveScreen(5, 10, 12, 20)
      oList := ListBox(5, 10, 12, 20, { | x | iif(x == NIL,;
         nChoice, nChoice  := x })
      oList:addItem("Black", "N")
      oList:addItem("Blue", "B")
      oList:addItem("Green", "G")
      oList:addItem("Cyan", "BG")
      oList:addItem("Red", "R")
      oList:addItem("Magenta", "RB")
      oList:addItem("Brown", "GR")
      oList:addItem("White", "W")
      AAdd(GetList, oList)
      read
      RestScreen(5, 10, 12, 20, cOldWindow)
   return (oList:GetData(nChoice))

Platforms

Available on MS-DOS

LISTHarbour implementation⌃ | ☰

List records to the console

Syntax

LIST <exp list>
   [TO PRINTER] [TO FILE <xcFile>]
   [<scope>] [WHILE <lCondition>]
   [FOR <lCondition>] [OFF]

Arguments

exp list is the list of expressions to be evaluated and displayed for each record processed.

TO PRINTER echoes output to the printer.

TO FILE xcFile echoes output to the specified file name and can be specified either as a literal file name or as a character expression enclosed in parentheses. If an extension is not specified, .txt is added.

scope is the portion of the current database file to LIST. The default is ALL records.

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

FOR lCondition specifies the conditional set of records to LIST within the given scope.

OFF suppresses the display of record numbers.

Description

LIST is a console command that sequentially accesses records in the current work area, displaying the results of one or more expressions for each record accessed. The output is in tabular format with each column separated by a space. LIST is identical to DISPLAY with the exception that its default scope is ALL rather than NEXT 1.

When invoked, output is sent to the screen and, optionally, to the printer and/or a file. To suppress output to the screen while printing or echoing output to a file, SET CONSOLE OFF before the LIST invocation.

Notes

■ Interrupting LIST: So the user may interrupt a LIST, use

Inkey() as part of the FOR condition to test for an interrupt key press. See the example below.

■ Printer margin: LIST honors the current SET MARGIN for output

echoed to the printer.

Examples

■  In this example, a simple list is followed by a conditional
   list to the printer:

   USE Sales
   LIST Date(), Time(), Branch
   LIST Branch, Salesman FOR Amount > 500 TO PRINTER

■  This example interrupts LIST using Inkey() to test whether the
   user pressed the Esc key:

   #define K_ESC     27
   USE Sales INDEX Salesman NEW
   LIST Branch, Salesman, Amount WHILE Inkey() != K_ESC

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Log()Harbour implementation


⌃ | ☰

Calculate the natural logarithm of a numeric value

Syntax

Log(<nExp>) → nNaturalLog

Arguments

nExp is a numeric value greater than zero to be converted to its natural logarithm.

Returns

Log() returns the natural logarithm as a numeric value. If nExp is less than or equal to zero, Log() returns a numeric overflow (displayed as a row of asterisks).

Description

Log() is a numeric function that calculates the natural logarithm of a number and is the inverse of Exp(). The natural logarithm has a base of e which is approximately 2.7183. The Log() function returns x in the following equation,

e**x = y

where y is the numeric expression used as the Log() argument (i.e., Log(y) = x). Due to mathematical rounding, the values returned by Log() and Exp() may not agree exactly (i.e., Exp(Log(x)) may not always equal x).

Examples

■  These examples demonstrate various results of Log():

   ? Log(10)                  // Result: 2.30
   ? Log(10 * 2)            // Result: 3.00
   ? Exp(Log(1))            // Result: 1.00
   ? Log(2.71)               // Result: 1.00

■  This example is a user-defined function that returns the base
   10 logarithm:

   FUNCTION Log10( nNumber )
   IF nNumber > 0
      RETURN Log(nNumber)/Log(10)
   ELSE
      RETURN NIL
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Lower()Harbour implementation


⌃ | ☰

Convert uppercase characters to lowercase

Syntax

Lower(<cString>) → cLowerString

Arguments

cString is a character string to be converted to lowercase.

Returns

Lower() returns a copy of cString with all alphabetic characters converted to lowercase. All other characters remain the same as in the original string.

Description

Lower() is a character function that converts uppercase and mixed case strings to lowercase. It is related to Upper() which converts lowercase and mixed case strings to uppercase. Lower() is related to the IsLower() and IsUpper() functions which determine whether a string begins with a lowercase or uppercase letter.

Lower() is generally used to format character strings for display purposes. It can, however, be used to normalize strings for case- independent comparison or INDEXing purposes.

Examples

■  These examples demonstrate various results of Lower():

   ? Lower("STRING")               // Result: string
   ? Lower("1234 CHARS = ")      // Result: 1234 chars =

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

LOCAL⌃ | ☰

Declare and initialize local variables and arrays

Syntax

LOCAL <identifier> [[:= <initializer>], ... ]

Arguments

identifier is the name of a variable or array to declare local. If the identifier is followed by square brackets ([ ]), it is created as an array. If the identifier is an array, the syntax for specifying the number of elements for each dimension can be array[nElements, nElements2,…] or array[nElements][nElements2]… The maximum number of elements per dimension is 4096. The maximum number of dimensions per array is limited only by available memory.

initializer is the optional assignment of a value to a new local variable. Array identifiers, however, cannot be given values with an initializer. An initializer for a local variable consists of the inline assignment operator (:=) followed by any valid CA-Clipper expression including a literal array. If no explicit initializer is specified, the variable is given an initial value of NIL. In the case of an array, each element is NIL.

Note: The macro operator (&) cannot be used in a LOCAL declaration statement.

Description

LOCAL is a declaration statement that declares one or more variables or arrays local to the current procedure or user-defined function, and must occur before any executable statement including PRIVATE, PUBLIC, and PARAMETERS. Local variable declarations hide all inherited private variables and visible public variables with the same name. A LOCAL statement, however, that declares a variable name which is already declared causes a fatal compiler error and no object file (.OBJ) is generated. This error can happen as a result of two declarations for the same variable name in the same routine, or as the result of redeclaring a variable with filewide scope. Declaration statements include FIELD, MEMVAR, and STATIC.

Local variables are visible only within the current procedure or user- defined function and, unlike private variables, are not visible within invoked routines. Local variables are created automatically each time the procedure in which they were declared begins executing. They continue to exist and retain their values until the declaring procedure or user-defined function returns control to the code that invoked it. If a procedure or user-defined function is invoked recursively (calls itself), each recursive activation creates a new set of local variables.

The initial value of local variables and array elements is NIL if not explicitly initialized, either in the initializer list or by assignment. The initializer expression can be any valid CA-Clipper expression, including function calls. Note that an array declaration cannot have an initializer.

The maximum number of local variables in a program is limited only by available memory. Arrays, however, assigned to a local variable are still limited to 4096 elements per dimension.

For more information on variable declarations and scoping, refer to the Variables section in the «Basic Concepts» chapter of the Programming and Utilities Guide.

Notes

■ Inspecting local variables within the debugger: To access

local variable names within the CA-Clipper DOS-level debugger, you must compile program (.prg) files using the /B option so that local variable information is included in the object file.

■ Local parameters: Declare a list of local parameters as a part

of a FUNCTION or PROCEDURE declaration by enclosing the list of parameters in parentheses following the idFunction:

FUNCTION idFunction(idParam list)

Declaration of local parameters supersedes creation of private parameters with the PARAMETERS statement.

■ Macro expressions: You cannot refer to local variables within

macro variables and expressions. If you refer to a local variable within a macro variable, a private or public variable with the same name will be referenced instead. If no such variable exists, a runtime error will be generated.

■ Memory files: Local variables cannot be SAVED to or RESTOREd

from memory (.mem) files.

■ Type of a local variable: Since Type() uses the macro operator

(&) to evaluate its argument, it cannot be used to determine the type of a local or static variable or an expression containing a local or static variable reference. The ValType() function provides this facility. ValType() evaluates its argument and returns the type of the return value.

Examples

■  This example declares two local arrays and two local
   variables:

   LOCAL aArray1[20, 10], aArray2[20][10], var1, var2

■  This example declares two local variables with initializers.
   The first is initialized to a date value and the second to a literal
   array:

   LOCAL dWhen := Date()
   LOCAL aVegies := {"Tomato", "Chickadee", "Butterbean"}

Platforms

Available on MS-DOS

See also

FUNCTION, PARAMETERS, PRIVATE, PROCEDURE, PUBLIC, STATIC

LOCATEHarbour implementation⌃ | ☰

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

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

LTrim()Harbour implementation


⌃ | ☰

Remove leading spaces from a character string

Syntax

LTrim(<cString>) → cTrimString

Arguments

cString is the character string to copy without leading spaces.

Returns

LTrim() returns a copy of cString with the leading spaces removed. If cString is a null string («») or all spaces, LTrim() returns a null string («»).

Description

LTrim() is a character function that formats character strings with leading spaces. These can be, for example, numbers converted to character strings using Str().

LTrim() is related to RTrim(), which removes trailing spaces, and AllTrim(), which removes both leading and trailing spaces. The inverse of AllTrim(), LTrim(), and RTrim() are the PadC(), PadR(), and PadL() functions which center, right-justify, or left-justify character strings by padding them with fill characters.

Notes

■ Space characters: The LTrim() function treats carriage

returns, line feeds, and tabs as space characters and removes these as well.

Examples

■  These examples illustrate LTrim() used with several other
   functions:

   nNumber = 18
   ? Str(nNumber)                  // Result: 18
   ? Len(Str(nNumber))            // Result: 10

   ? LTrim(Str(nNumber))         // Result: 18
   ? Len(LTrim(Str(nNumber)))      // Result:  2

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

LUpdate()Harbour implementation


⌃ | ☰

Return the last modification date of a database (.dbf) file

Syntax

LUpdate() → dModification

Returns

LUpdate() returns the date of the last change to the open database file in the current work area. If there is no database file in USE, LUpdate() returns a blank date.

Description

LUpdate() is a database function that determines the date the database file in the current work area was last modified and CLOSEd. By default, LUpdate() 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 in the example below.

Examples

■  This example demonstrates that the modification date of the
   database file is not changed until the database file is closed:

   ? Date()                  // Result: 09/01/90
   USE Sales NEW
   ? LUpdate()               // Result: 08/31/90
   //
   APPEND BLANK
   ? LUpdate()               // Result: 08/31/90
   CLOSE DATABASES
   //
   USE Sales NEW
   ? LUpdate()               // Result: 09/01/90

■  This example uses an aliased expression to access LUpdate()
   for a database file opened in an unselected work area:

   USE Sales NEW
   USE Customer NEW
   ? LUpdate(), Sales->(LUpdate())

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

Max()Harbour implementation


⌃ | ☰

Return the larger of two numeric or date values

Syntax

Max(<nExp1>, <nExp2>) → nLarger
Max(<dExp1>, <dExp2>) → dLarger

Arguments

nExp1 and nExp2 are the numeric values to be compared.

dExp1 and dExp2 are the date values to be compared.

Returns

Max() returns the larger of the two arguments. The value returned is the same type as the arguments.

Description

Max() is a numeric and date function that ensures the value of an expression is larger than a specified minimum. The inverse of Max() is Min(), which returns the lesser of two numeric or date values.

Examples

■  In these examples Max() returns the greater of two numeric
   values:

   ? Max(1, 2)                     // Result: 2
   ? Max(2, 1)                     // Result: 2

■  In these examples Max() compares date values:

   ? Date()                           // Result: 09/01/90
   ? Max(Date(), Date() + 30)         // Result: 10/01/90
   ? Max(Date(), CToD(""))            // Result: 09/01/90

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MaxCol()Harbour implementation


⌃ | ☰

Determine the maximum visible screen column

Syntax

Returns

MaxCol() returns the column number of the rightmost visible column for display purposes.

Description

MaxCol() is a screen function that determines the maximum visible column of the screen. Row and column numbers start at zero in CA-Clipper.

If you use a C or other extended function to set the video mode, use the SetMode() function so your CA-Clipper application returns the correct value for MaxCol().

Examples

■  This example uses MaxRow() and MaxCol() to determine the area
   in which to draw a box, and then executes dbEdit() within the box
   region:

   CLS
   @ 0, 0 TO MaxRow(), MaxCol() DOUBLE
   dbEdit(1, 1, MaxRow() + 1, MaxCol() - 1)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MaxRow()Harbour implementation


⌃ | ☰

Determine the maximum visible screen row

Syntax

Returns

MaxRow() returns the row number of the bottommost visible row for display purposes.

Description

MaxRow() is a screen function that determines the maximum visible row of the screen. Row and column numbers start at zero in CA-Clipper.

If you use a C or other extended function to set the video mode, use the SetMode() function so your CA-Clipper application returns the correct value for MaxCol().

Examples

■  This user-defined function, ScreenSize(), uses MaxRow() and
   MaxCol() to return an array containing the current screen size:

   FUNCTION ScreenSize
      RETURN { MaxRow(), MaxCol() }

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MCol()Harbour implementation


⌃ | ☰

Determine the mouse cursor’s screen column position

Syntax

MCol() → nCurrentMouseColumn

Returns

MCol() returns the mouse cursor’s current screen column position.

Description

MCol() is a function that is used for determining the mouse cursor’s screen column position. This is useful when implementing a hit testing routine whose purpose is to determine if the mouse cursor is on pertinent information when the left mouse button is pressed.

Platforms

Available on MS-DOS

See also

MDblClk()Harbour implementation


⌃ | ☰

Determine the double-click speed threshold of the mouse

Syntax

MDblClk([<nNewSpeed>]) → nSpeed

Arguments

nNewSpeed is the maximum allowable amount of time between mouse key presses for a double-click to be detected. This is measured in milliseconds.

Returns

MDblClk() returns the current double-click speed threshold.

Description

MDblClk() is a function used for determining and, optionally, changing the mouse’s double-click speed threshold. This is useful when the mouse’s double-click sensitivity needs to be adjusted.

Platforms

Available on MS-DOS

MemoEdit()Harbour implementation


⌃ | ☰

Display or edit character strings and memo fields

Syntax

MemoEdit([<cString>],
   [<nTop>], [<nLeft>],
   [<nBottom>], [<nRight>],
   [<lEditMode>],
   [<cUserFunction>],
   [<nLineLength>],
   [<nTabSize>],
   [<nTextBufferRow>],
   [<nTextBufferColumn>],
   [<nWindowRow>],
   [<nWindowColumn>]) → cTextBuffer

Arguments

cString is the character string or memo field to copy to the MemoEdit() text buffer. If not specified, the text buffer is empty.

nTop, nLeft, nBottom, and nRight are the upper-left and lower-right window coordinates. Row values can range from zero to MaxRow(), and column positions can range from zero to MaxCol(). If not specified, the default coordinates are 0, 0, MaxRow(), and MaxCol().

lEditMode determines whether the text buffer can be edited or merely displayed. Specifying true (.T.) allows the user to make changes to the text buffer, while specifying false (.F.) only allows the user to browse the text buffer. If not specified, the default value is true (.T.).

cUserFunction is the name of a user-defined function that executes when the user presses a key not recognized by MemoEdit() and when no keys are pending in the keyboard buffer. cUserFunction is specified as a character value without parentheses or arguments. Specifying false (.F.) for this argument displays cString and causes MemoEdit() to immediately terminate. If this argument is specified, the automatic behavior of MemoEdit() changes. Refer to the discussion below.

nLineLength determines the length of lines displayed in the MemoEdit() window. If a line is greater than nLineLength, it is word wrapped to the next line in the MemoEdit() window. If nLineLength is greater than the number of columns in the MemoEdit() window, the window will scroll if the cursor moves past the window border. If nLineLength is not specified, the default line length is (nRightnLeft).

nTabSize determines the tab stops that will be used when the user presses Tab. If nTabSize is not specified, tab stops will be placed at every four characters.

nTextBufferRow and nTextBufferColumn define the display position of the cursor within the text buffer when MemoEdit() is invoked. nTextBufferRow begins with one (1) and nTextBufferColumn begins with zero (0). If these arguments are not specified, the cursor is placed at row one (1) and column zero (0) of the MemoEdit() window.

nWindowRow and nWindowColumn define the initial position of the cursor within the MemoEdit() window. Row and column positions begin with zero (0). If these arguments are not specified, the initial window position is row zero (0) and the current cursor column position.

Returns

MemoEdit() returns the text buffer if the user terminates editing with Ctrl+W or a copy of cString if user terminates with Esc.

Description

MemoEdit() is a user interface and general purpose text editing function that edits memo fields and long character strings. Editing occurs within a specified window region placed anywhere on the screen. Like the other user interface functions (AChoice() and dbEdit()), MemoEdit() supports a number of different modes and includes a user function that allows key reconfiguration and other activities relevant to programming the current text editing task.

■ The text buffer: When you invoke MemoEdit() and specify

cString, it is copied to the text buffer. The user actually edits the text buffer. If the cString is not specified, the user is presented with an empty text buffer to edit.

When the user exits MemoEdit() by pressing Ctrl+W, the contents of the text buffer are returned. If the user exits by pressing Esc, the text buffer is discarded and the original cString value is returned. In either case, the return value can then be assigned to a variable or memo field, or passed as an argument to another function.

■ Editing modes: MemoEdit() supports two editing modes depending

on the value of lEditMode. When lEditMode is true (.T.), MemoEdit() enters edit mode and the user can change the contents of the MemoEdit() text buffer. When lEditMode is false (.F.), MemoEdit() enters browse mode and the user can only navigate about the text buffer but cannot edit or insert new text. To make browsing easier for the user, the scrolling is disabled so Up arrow and Down arrow scroll the text buffer up or down one line within the MemoEdit() window.

■ Entering and editing text: Within MemoEdit(), the user can

enter and edit text by positioning the cursor, adding, or deleting characters. To facilitate editing the text, there are a number of different navigation and editing keys:

MemoEdit() Navigation and Editing Keys

       Key                      Action

       Up arrow/Ctrl+E          Move up one line

       Down arrow/Ctrl+X        Move down one line

       Left arrow/Ctrl+S        Move left one character

       Right arrow/Ctrl+D       Move right one character

       Ctrl+Left arrow/Ctrl+A   Move left one word

       Ctrl+Right arrow/Ctrl+F  Move right one word

       Home                     Move to beginning of current line

       End                      Move to end of current line

       Ctrl+Home                Move to beginning of current window

       Ctrl+End                 Move to end of current window

       PgUp                     Move to previous edit window

       PgDn                     Move to next edit window

       Ctrl+PgUp                Move to beginning of memo

       Ctrl+PgDn                Move to end of memo

       Return                   Move to beginning of next line

       Delete                   Delete character at cursor

       Backspace                Delete character to left of cursor

       Tab                      Insert tab character or spaces

       Printable characters     Insert character

       Ctrl+Y                   Delete the current line

       Ctrl+T                   Delete word right

       Ctrl+B                   Reform paragraph

       Ctrl+V/Ins               Toggle insert mode

       Ctrl+W                   Finish editing with save

       Esc                      Abort edit and return original

When the user is entering text, there are two text entry modes, insert and overstrike. When MemoEdit() is invoked, the default mode is overstrike. Edit mode changes in MemoEdit() when the user presses Ins which toggles between the insert and overstrike. It also changes in a user function using ReadInsert() or RETURNing 22. In insert mode, characters are entered into the text buffer at the current cursor position and the remainder of the text moves to the right. Insert mode is indicated in the scoreboard area. In overstrike mode, characters are entered at the current cursor position overwriting existing characters while the rest of the text buffer remains in its current position.

As the user enters text and the cursor reaches the edge of the MemoEdit() window, the current line wraps to the next line in the text buffer and a soft carriage return (Chr(141)) is inserted into the text. If the nLineLength argument is specified, text wraps when the cursor position is the same as nLineLength. If nLineLength is greater than the width of the MemoEdit() window, the window scrolls. To explicitly start a new line or paragraph, the user must press Return.

■ The edit screen: When MemoEdit() displays, it overwrites the

specified area of the screen and does not save the underlying screen. Additionally, it does not display a border or a title. To provide these facilities, you must create a procedure or user-defined function that performs these actions, and then calls MemoEdit(). See the example below.

■ The user function: cUserFunction, a user-defined function

specified as an argument, handles key exceptions and reconfigures special keys. The user function is called at various times by MemoEdit(), most often in response to keys it does not recognize. Keys that instigate a key exception are all available control keys, function keys, and Alt keys. Since these keys are not processed by MemoEdit(), they can be reconfigured. Some of these keys have a default action assigned to them. In the user function, you perform various actions depending on the current MemoEdit() mode, and then RETURN a value telling MemoEdit() what to do next.

When the user function argument is specified, MemoEdit() defines two classes of keys: nonconfigurable and key exceptions. When a nonconfigurable key is pressed, MemoEdit() executes it; otherwise, a key exception is generated and the user function is called. When there are no keys left in the keyboard buffer for MemoEdit() to process, the user function is called once again.

When MemoEdit() calls the user function, it automatically passes three parameters indicating the MemoEdit() mode, the current text buffer line, and the current text buffer column. The mode indicates the current state of MemoEdit() depending on the last key pressed or the last action taken prior to executing the user function. The following modes are possible:

MemoEdit() Modes

       Mode    Memoedit.ch    Description

       0       ME_IDLE        Idle, all keys processed

       1       ME_UNKEY       Unknown key, memo unaltered

       2       ME_UNKEYX      Unknown key, memo altered

       3       ME_INIT        Initialization mode

A mode value of 3 indicates that MemoEdit() is in initialization mode. When you specify cUserFunction, MemoEdit() makes a call to the user function immediately after being invoked. At this point, you RETURN a request to set MemoEdit()‘s various text formatting modes: word wrap, scroll, or insert. MemoEdit() calls the user function repeatedly, remaining in the initialization mode until you RETURN 0. The text buffer is then displayed, and the user enters the edit mode set by lEditMode. Note that if word wrap is on when MemoEdit() changes from initialization to edit mode, the entire text buffer is formatted with nLineLength. To prevent this initial formatting, toggle word wrap off during initialization. Note also that the toggles for scroll and word wrap are not assigned to any key, but can be assigned to a key from the user function.

Modes 1 and 2 indicate that MemoEdit() has fetched an unrecognizable or configurable key from the keyboard buffer. Configurable keys are processed by RETURNing 0 to execute the MemoEdit() default action. RETURNing a different value executes another key action, thereby redefining the key. If the key is an unrecognizable key, you can define an action for it by RETURNing a value requesting a key action or perform an action of your own definition.

Mode 0 indicates that MemoEdit() is now idle with no more keys to process. Whenever MemoEdit() becomes idle, it always make a call to the user function. At this point, you generally update line and column number displays.

The other two parameters, current line and column, indicate the current cursor position in the text buffer when the user function is called. The line parameter begins with position one (1), and column begins with position zero (0).

When the mode is either 1, 2, or 3, you can return a value instructing MemoEdit() what action to perform next. The following table summarizes the possible return values and their consequences:

MemoEdit() User Function Return Values

       Value   Memoedit.ch         Action

       0       ME_DEFAULT          Perform default action

       1-31    ME_UNKEY            Process requested action corresponding to

                                   key value

       32      ME_IGNORE           Ignore unknown key

       33      ME_DATA             Treat unknown key as data

       34      ME_TOGGLEWRAP       Toggle word wrap mode

       35      ME_TOGGLESCROLL     Toggle scroll mode

       100     ME_WORDRIGHT        Perform word-right operation

       101     ME_BOTTOMRIGHT      Perform bottom-right operation

■ Header files: To make the mode and request values easier to

remember and use, the header file memoedit.ch is supplied in CLIP53INCLUDE. Additionally, inkey.ch, which contains manifest constants for all the Inkey() values, is also located in the same directory.

Notes

■ Configuring keys: If the cUserFunction is specified, the

keys in the table below are configurable.

MemoEdit() Configurable Keys

       Key            Default Action

       Ctrl+Y         Delete the current line

       Ctrl+T         Delete word right

       Ctrl+B         Reform Paragraph

       Ctrl+V/Ins     Toggle insert mode

       Ctrl+W         Finish editing with save

       Esc            Abort edit and return original

If the key is configurable, RETURNing 0 executes the MemoEdit() default action. RETURNing a different value, however, executes another key action thereby redefining the key. If the key is not a configurable key recognized by MemoEdit(), you can define an action for it also by RETURNing a value requesting a key action from the table above.

■ Word wrap: Word wrap is a formatting mode you can toggle by

RETURNing 34 from the user function. When word wrap is on (the default setting), MemoEdit() inserts a soft carriage return/line feed at the closest word break to the window border or line length, whichever occurs first. When word wrap is off, MemoEdit() scrolls text buffer beyond the edge of the window until the cursor reaches the end of line. At this point, the user must press Return (inserting a hard carriage return/line feed) to advance to the next line.

■ Reforming paragraphs: Pressing Ctrl+B or RETURNing a 2 from a

user function reformats the text buffer until a hard carriage return (end of paragraph) or the end of the text buffer is reached. This happens regardless of whether word wrap is on or off.

■ Soft carriage returns: In CA-Clipper, the insertion of soft

carriage return/linefeed characters is never allowed to change the significant content of the text. That is, when a soft carriage return/linefeed is inserted between two words, the space characters between the two words are preserved. When text is reformatted, any soft carriage return/linefeed characters are removed. This leaves the text in its original form and properly handles the case where a soft carriage return/linefeed has been inserted in the middle of a word.

In the Summer ’87 version of MemoEdit(), when a soft carriage return/line feed is inserted, a single space character is removed from the text at that point. If the text is later reformatted using a different line width, each soft carriage return/linefeed is replaced by a single space. However, if the text string is reformatted using any of the CA-Clipper text handling functions, words that were separated by a soft carriage return/linefeed will be run together because the soft carriage return/linefeed is not replaced with a space.

To prevent this, text that was formatted using Summer ’87 MemoEdit() should be processed to change any soft carriage return/linefeed pairs into space characters. This can be accomplished using the StrTran() function as follows:

StrTran( text, Chr(141)+Chr(10), » » )

To convert memo values in an existing database, the following two line program can be used:

USE xcDatabase REPLACE ALL idMemo WITH ;

StrTran( idMemo, Chr(141)+Chr(10), » » )

Because of the .dbt file format, replacing all occurrences of a memo field can cause the .dbt file to grow significantly. The .dbt file can be reduced by copying the .dbf to a new file.

For very large .dbt files, it may not be feasible to perform the above procedure. The supplied utility program, DBT50.EXE located in CLIP53BIN, may be useful in these cases. DBT50 scans an entire .dbt file, replacing any soft carriage return/line feed pairs with two spaces. Although this has the undesirable effect of causing certain words to be separated by two spaces instead of one, it allows the file to be processed in place without using additional disk space. DBT50 modifies only soft carriage return/linefeed pairs in the target file. Other text is unaffected.

■ Editing text files: MemoEdit() edits text files if the text

file can be read into a CA-Clipper character variable. This can be done with the MemoRead() function. After editing the contents of the text file held in the character variable, write it back to the file using MemoWrit().

Examples

■  This example lets you browse a memo field but prevents any
   changes to the text buffer:

   USE Customer NEW
   SET CURSOR OFF
   MemoEdit(CustNotes, 5, 10, 20, 69, .F.)
   SET CURSOR ON

■  This example allows editing of a memo field, assigning the
   changes back to the memo field:

   USE Customer NEW
   REPLACE CustNotes WITH ;
         MemoEdit(CustNotes, 5, 10, 20, 69)

■  This example creates a character string using MemoEdit():

   LOCAL cNotes
   cNotes = MemoEdit()

■  This example is a user-defined function that edits a character
   string in a boxed window displayed with a title:

FUNCTION EditMemo( cString, cTitle,;
            nTop, nLeft, nBottom, nRight )
      LOCAL cScreen := SaveScreen(nTop, nLeft,;
            nBottom, nRight)
      @ nTop - 1, nLeft - 2 CLEAR TO nBottom + 1,;
            nRight + 2
      @ nTop - 1, nLeft - 2 TO nBottom + 1, nRight + 2
      @ nTop - 1, nLeft SAY "[" + cTitle + "]"
      cString = MemoEdit(cString, nTop, nLeft,;
            nBottom, nRight)
      RestScreen(nTop, nLeft, nBottom, nRight, cScreen)

      RETURN (cString)

■  This example reads the contents of a text file into a
   character variable, edits it, and then writes it back to disk:

   LOCAL cString := MemoRead("Text.txt")
   cString := MemoEdit(cString)
   IF !MemoWrit("Text.txt", cString)
      ? "Write error"
      BREAK
   ENDIF
   RETURN

■  This example contains a user-defined function that displays a
   message describing the current MemoEdit() mode.  Additionally, while
   in ME_UNKEY mode, the function will perform either a ME_WORDRIGHT or
   ME_BOTTOMRIGHT action depending on which associated function key is
   pressed:

   #include "Memoedit.ch"
   #include "Inkey.ch"

   PROCEDURE Main()
      USE Customer NEW
      REPLACE CustNotes WITH;
      MemoEdit( CustNotes, 5, 5, 15, 75, .T., "MemoUDF" )
   RETURN

   FUNCTION MemoUDF( nMode, nLine, nCol )
      LOCAL nKey := LastKey()
      LOCAL nRetVal := ME_DEFAULT         // Default return action

      DO CASE
      CASE nMode == ME_IDLE
         @ 20, 5 SAY "MemoMode is ME_IDLE  "
      CASE nMode == ME_UNKEY
         @ 20, 5 SAY "MemoMode is ME_UNKEY "
         DO CASE
         CASE nKey == K_F2
            nRetVal := ME_WORDRIGHT
         CASE nKey == K_F3
            nRetVal := ME_BOTTOMRIGHT
         ENDCASE
         CASE nMode == ME_UNKEYX
         @ 20, 5 SAY "MemoMode is ME_UNKEYX"
      OTHERWISE
         @ 20, 5 SAY "MemoMode is ME_INIT  "
      ENDCASE

   RETURN nRetVal

Platforms

Available on MS-DOS

File

See also

MemoLine()Harbour implementation


⌃ | ☰

Extract a line of text from a character string or memo field

Syntax

MemoLine(<cString>,
   [<nLineLength>],
   [<nLineNumber>],
   [<nTabSize>],
   [<lWrap>]) → cLine

Arguments

cString is the memo field or character string from which a line of text is to be extracted.

nLineLength specifies the number of characters per line and can be between four and 254. If not specified, the default line length is 79.

nLineNumber is the line number to be extracted. If not specified, the default value is one.

nTabSize defines the tab size. If not specified, the default value is four. If nTabSize is greater than or equal to nLineLength, then the tab size is automatically converted to nLineLength — 1.

lWrap toggles word wrap on and off. Specifying true (.T.) toggles word wrap on; false (.F.) toggles it off. If not specified, the default value is true (.T.).

Returns

MemoLine() returns the line of text specified by nLineNumber in cString as a character string. If the line has fewer characters than the indicated length, the return value is padded with blanks. If the line number is greater than the total number of lines in cString, MemoLine() returns a null string («»).

If lWrap is true (.T.) and the indicated line length breaks the line in the middle of a word, that word is not included as part of the return value but shows up at the beginning of the next line extracted with MemoLine().

If lWrap is false (.F.), MemoLine() returns only the number of characters specified by the line length. The next line extracted by MemoLine() begins with the character following the next hard carriage return, and all intervening characters are not processed.

Description

MemoLine() is a memo function used with MLCount() to extract lines of text from character strings and memo fields based on the number of characters per line. It is the most basic facility provided by CA-Clipper to display memo fields and long strings.

The basic method of operation is to determine the number of lines in the memo field or character string using MLCount() with the same number of characters per line, tab size, and wrapping behavior as you intend to use with MemoLine(). Using this value as the upper boundary of a FOR...NEXT, each line of the memo field or character string can be extracted with MemoLine() and processed with any combination of output commands and functions required.

Examples

■  This example demonstrates the general method for displaying
   memo fields and long character strings using the combination of
   MLCount() and MemoLine():

   LOCAL nLineLength := 40, nTabSize := 3, lWrap := .T.
   LOCAL nLines, nCurrentLine
   USE Customer INDEX CustName NEW
   //
   nLines := MLCount(CustNotes, nLineLength,;
         nTabSize, lWrap)
   //
   SET PRINTER ON
   FOR nCurrentLine := 1 TO nLines
      ? MemoLine(CustNotes, nLineLength, nCurrentLine,;
             nTabSize, lWrap)
   NEXT
   SET PRINTER OFF

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

Memory()Harbour implementation


⌃ | ☰

Determine the amount of available free pool memory

Syntax

Arguments

nExp is a numeric value that determines the type of value Memory() returns as follows:

Memory() Argument Values

    Value     Meaning

    0         Estimated total space available for character values

    1         Largest contiguous block available for character values

    2         Area available for RUN commands

Returns

Memory() returns an integer numeric value representing the amount of memory available, in one -kilobyte increments.

Description

Memory() is an environment function that reports various states of free pool memory. (Free pool is the dynamic region of memory that stores character strings and executes RUN commands.)

Examples

■  This example uses Memory() before a RUN command to determine
   if there is enough memory available to execute the external program:

   #define MEM_CHAR   0
   #define MEM_BLOCK   1
   #define MEM_RUN      2
   //
   IF Memory(MEM_RUN) >= 128
      RUN MYPROG
   ELSE
      ? "Not enough memory to RUN"
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

MemoRead()Harbour implementation


⌃ | ☰

Return the contents of a disk file as a character string

Syntax

MemoRead(<cFile>) → cString

Arguments

cFile is the name of the file to read from disk. It must include an extension, if there is one, and can optionally include a path.

Returns

MemoRead() returns the contents of a text file as a character string. The maximum file size that can be read is 65,535 characters (64K)—the maximum size of a character string. If cFile cannot be found, MemoRead() returns a null string («»).

Description

MemoRead() is a memo function that reads a disk file into memory where it can be manipulated as a character string or assigned to a memo field. MemoRead() is used with MemoEdit() and MemoWrit() to edit an imported disk file, and then write it back to disk. MemoRead() searches for cFile beginning with the current DOS directory. If the file is not found, MemoRead() searches the DOS path. MemoRead() does not use the CA-Clipper DEFAULT or PATH to search for cFile.

In a network environment, MemoRead() attempts to open the specified file shared and read—only. If the file is opened exclusive by another process, MemoRead() returns a null string («»).

Examples

■  This example uses MemoRead() to assign the contents of a text
   file to the Notes memo field and to a character variable:

   REPLACE Notes WITH MemoRead("Temp.txt")
   cString = MemoRead("Temp.txt")

■  This example defines a function that edits a disk file:

   FUNCTION Editor( cFile )
      LOCAL cString
      IF (cString := MemoRead(cFile)) == ""
         ? "Error reading " + cFile
         RETURN .F.
      ELSE
         MemoWrit(cFile, MemoEdit(cString))
         RETURN .T.
      ENDIF

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

MemoTran()Harbour implementation


⌃ | ☰

Replace carriage return/linefeeds in character strings

Syntax

MemoTran(<cString>,
   [<cReplaceHardCR>],
   [<cReplaceSoftCR>]) → cNewString

Arguments

cString is the character string or memo field to be searched.

cReplaceHardCR is the character with which to replace a hard carriage return/line feed pair. If not specified, the default value is a semicolon (;).

cReplaceSoftCR is the character with which to replace a soft carriage return/line feed pair. If not specified, the default value is a space.

Returns

MemoTran() returns a copy of cString with the specified carriage return/line feed pairs replaced.

Description

MemoTran() is a memo function that converts a memo field or long character string containing hard and soft carriage return/line feed characters into a form that can be displayed. These two character combinations are end of line formatting indicators placed in the string by MemoEdit(). Soft carriage returns (Chr(141)) are inserted when a line longer than the width of the MemoEdit() window wraps. Hard carriage returns (Chr(13)) are inserted when the user explicitly presses Return.

MemoTran() is particularly useful when displaying a memo field in a REPORT FORM which does not wrap when a soft carriage return is encountered. MemoTran() resolves this by converting soft carriage returns to spaces. Note, however, that you must declare MemoTran() as external using the REQUEST statement if it is used in a REPORT FORM and not specified anywhere else in the current program.

Examples

■  This example strips all end of line characters from a memo
   field:

   REPLACE Notes WITH MemoTran(Notes)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

MemoWrit()Harbour implementation


⌃ | ☰

Write a character string or memo field to a disk file

Syntax

MemoWrit(<cFile>, <cString>) → lSuccess

Arguments

cFile is the name of the target disk file including the file extension and optional path and drive designator.

cString is the character string or memo field to write to cFile.

Returns

MemoWrit() returns true (.T.) if the writing operation is successful; otherwise, it returns false (.F.).

Description

MemoWrit() is a memo function that writes a character string or memo field to a disk file. If a path is not specified, MemoWrit() writes cFile to the current DOS directory and not the current DEFAULT directory. If cFile already exists, it is overwritten.

MemoWrit() is generally used with MemoRead() to load text files into memory where they can be edited, displayed, and written back to disk. You can also use MemoWrit() as a quick way of exporting a memo field to a text file.

Examples

■  This example uses MemoWrit() with MemoRead() to allow editing
   of memo fields with an external editor:

   LOCAL cEditor := "MYEDIT.EXE"
   USE Sales NEW
   IF MemoWrit("Cliptmp.txt", Notes)
      RUN (cEditor + " Cliptmp.txt")
      REPLACE Notes WITH MemoRead("Cliptmp.txt")
   ELSE
      ? "Error while writing Cliptmp.txt"
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

MemVarBlock()Harbour implementation


⌃ | ☰

Return a set-get code block for a given memory variable

Syntax

MemVarBlock(<cMemvarName>) → bMemvarBlock

Arguments

cMemvarName is the name of the variable referred to by the set-get block, specified as a character string.

Returns

MemVarBlock() returns a code block that when evaluated sets (assigns) or gets (retrieves) the value of the given memory variable. If cMemvarName does not exist, MemVarBlock() returns NIL.

Description

The code block created by MemVarBlock() has two operations depending on whether an argument is passed to the code block when it is evaluated. If evaluated with an argument, it assigns the value of the argument to cMemvarName. If evaluated without an argument, the code block retrieves the value of cMemvarName.

Notes

MemVarBlock() creates set-get blocks only for variables whose

names are known at runtime. MemVarBlock(), therefore, cannot be used to create set-get blocks for local or static variables. The same restriction applies to creating blocks using the macro operator (&).

Examples

■  This example compares MemVarBlock() to a code block created
   using the macro operator (&).  Note that using MemVarBlock() allows
   you to avoid the speed and size overhead of the macro operator:

   PRIVATE var := "This is a string"
   //
   // Set-Get block defined using macro operator
   bSetGet := &( "{ |setVal|;
         IF( setVal == NIL, var, var := setVal ) }" )
   // Set-Get block defined using MemVarBlock()

   // bSetGet created here is the functional
   // equivalent of bSetGet above
   bSetGet := MemVarBlock("var")

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MenuItem class⌃ | ☰

Create a menu item

Description

MenuItem objects are the basis for which both top bar and pop-up menus are built upon.

Methods link

MenuItem() Create a new MenuItem object


MenuItem(cCaption, expData, [nShortcut],

[cMessage], [nID]) → oMenuItem

Arguments

cCaption is a character string that contains either a text string that concisely describes the menu option or a menu separator specifier. This value is assigned to the MenuItem:caption instance variable.

expData is a value that contains either a code block or a PopUpMenu object. This argument is ignored when cCaption contains a menu separator specifier. This value is assigned to the MenuItem:data instance variable.

nShortcut is an optional numeric inkey value that indicates the shortcut key combination that selects and launches the menu selection. The default is 0. This value is assigned to the MenuItem:shortcut instance variable. Constant values for various key combinations are defined in inkey.ch.

cMessage is an optional character string that indicates the text to display on the status bar when the menu item is selected. The default is an empty string. This value is assigned to the MenuItem:message instance variable.

nID is an optional numeric value that uniquely identifies the menu item. The default is 0. This value is assigned to the MenuItem:id instance variable.

Returns

Returns a MenuItem object when all of the required arguments are present; otherwise, MenuItem() returns NIL.

Exported Instance Variables


caption Describes menu option or menu separator


caption (Assignable)

Contains either a text string that concisely describes the menu option or a menu separator specifier. MenuItem:caption is the text that appears in the actual menu.

A menu separator is a horizontal line in a pop-up menu that separates menu items into logical groups. Use the constant MENU_SEPARATOR in button.ch to assign the menu separator specifier to MenuItem:caption.

When present, the & character specifies that the character immediately following it in the caption is the menu item’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to select a menu item when the menu that it is contained within has input focus. When the menu is a member of a TopBarMenu object, the user selects the menu item by pressing the Alt key in combination with the accelerator key. When the menu is a member of a PopUpMenu object, the user selects the menu item by simply pressing the accelerator key. The accelerator key is not case sensitive.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the MenuItem object. MenuItem:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a MenuItem object and retrieved later.

checked Logical value which indicates a check mark


checked (Assignable)

Contains a logical value that indicates whether a check mark appears to the left of the menu item’s caption. A value of true (.T.) indicates that a check mark should show; otherwise, a value of false (.F.) indicates that it should not.

data Contains code block or a PopUpMenu object


data (Assignable)

Contains either a code block or a PopUpMenu object or, when the menu item’s Caption property contains a menu separator specifier, MenuItem:data contains NIL. When the menu item is selected, its code block, if present, is evaluated; otherwise, its PopUpMenu object is opened.

enabled Logical value indicating if menu item is selected


enabled (Assignable)

Contains a logical value that indicates whether the menu item can be selected or not. MenuItem:enabled contains true (.T.) to permit user access; otherwise, it contains false (.F.) to deny user access. When disabled, the item will be shown in its disabled color.

id Numeric value which identifies the menu item


id (Assignable)

Contains an optional numeric value that uniquely identifies the menu item. The default is 0. This value is returned by MenuModal() to indicate the selected menu item.

message String that describes the menu item


message (Assignable)

Contains an optional string that describes the menu item. This is the text that appears on the screen’s status bar line. The default is an empty string. The MenuModal() function defines the row and width for the area on the screen where messages are displayed.

shortcut Numeric value indicating the key to activate menu selection


shortcut (Assignable)

Contains an optional numeric inkey value indicating the key that activates the menu selection. The default is 0. Shortcut keys are available only for menu items on a PopUpMenu. TopBarMenu items cannot have shortcut keys associated with them.

The shortcut key name automatically appears to the right of the MenuItem:caption. Unlike with an accelerator key, the menu need not be open for the shortcut key to be active.

style String indicating the characters used by PopUpMenu:display()


style (Assignable)

Contains a character string that indicates the delimiter characters that are used by the PopUpMenu:display() method. The string must contain two characters. The first is the character associated with the MenuItem:checked property. Its default value is the square root character. The second is the submenu indicator. Its default is the right arrow character.

isPopUp() Indicates whether MenuItem:data contains a PopUpMenu object


oMenuItem:isPopUp() → lPopUpStatus

Returns a logical value that indicates whether the menu item’s data property contains a pop-up menu. A value of true (.T.) indicates that MenuItem:data contains a PopUpMenu object; otherwise, a value of false (.F.) indicates that it does not.

isPopUp() is a method of the MenuItem class that is used for determining whether a menu item is a branch in a menu tree. When a menu item is selected, typically one of two results will occur. If it is a menu tree branch, its pop-up menu is opened; otherwise, its code block will be evaluated.

Examples

See the Menu.prg sample file in the CLIP53SOURCESAMPLE directory.
This example demonstrates combining TopBarMenu, PopUpMenu, and MenuItem
objects to create a menu with a number of available choices.  See
"Introduction to the Menu System" in the Programming and Utilities Guide
for more information about using this class.

Platforms

Available on MS-DOS

See also

MenuModal()Harbour implementation


⌃ | ☰

Activate a top bar menu

Syntax

MenuModal(<oTopBar>, <nSelection>, <nMsgRow>,
   <nMsgLeft>, <nMsgRight>, <cMsgColor>) → MenuID

Arguments

oTopBar is a TopBarMenu object created from the TopBarMenu class.

nSelection is the TopBarMenu item selected by default.

nMsgRow is the row number where menu item messages will appear.

nMsgLeft specifies the left border for menu item messages.

nMsgRight specifies the right border for menu item messages.

cMsgColor defines the color string for the menu item messages. It consists of a single foreground/background pair.

Returns

MenuModal() returns the menu ID of the chosen menu item. Menu IDs are assigned using the MenuItem class.

Description

MenuModal() is a user-interface function that implements the pull-down menu system in CA-Clipper. It is part of the open architecture Get system of CA-Clipper. MenuModal() is similar to the READ command in that it waits for the user to perform an action. However, the MenuModal() function will only respond to menu actions.

To implement a menu object at the same time as other objects, use the ReadModal() function which has one of its arguments as TopBarMenu object.

When the user chooses a menu item, control is passed to the code block associated with that particular menu item. Code blocks are defined using the MenuItem class.

The menu items can be selected by using either the keyboard or the mouse. To select a menu item with the mouse, simply select its TopBarMenu item with the mouse and then choose the appropriate PopUp menu item.

Note: The MenuModal() function will take one menu event from the user and then terminate. To avoid this, the following can be used, and the same will allow the program to continuously accept menu events:

DO WHILE (MenuModal(themenu,…) <> ExitMenu) ENDDO

The following table lists the active keys that can be used during MenuModal():

MenuModal() Navigation Keys

    Key                 Action

    Left arrow, Ctrl+S  Move to the next TopBarMenu item to the left.  If

                        there are no more items to the left, the rightmost

                        TopBarMenu item will be selected.

    Right arrow, Ctrl+D Move to the next TopBarMenu item to the right.  If

                        there are no more items to the right, the leftmost

                        TopBarMenu will be selected.

    Up arrow, Ctrl+E    Move to the previous PopUp menu item.  If there are

                        no more items above the current item, the menu item

                        on the bottom will be selected.

    Down arrow, Ctrl+X  Move to the next PopUp menu item.  If there are no

                        more items below the current item, the menu item on

                        the top will be selected.

Examples

See the Menu.prg sample file in the CLIP53SOURCESAMPLE directory.
This example demonstrates combining TopBarMenu, PopUpMenu, and MenuItem
objects to create a menu with a number of available choices.  See
"Introduction to the Menu System" in the Programming and Utilities Guide
for more information about using this function.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is SOURCE/SYS/MENUSYS.PRG

See also

MEMOSETSUPER()


⌃ | ☰

Set an RDD inheritance chain for the DBFMEMO database driver

Syntax

MEMOSETSUPER([<cSuperRDD>]) → cOldSuperName

Arguments

cSuperRDD is a character string representing the name of the RDD from which DBFMEMO will inherit.

Returns

MEMOSETSUPER() always returns NIL.

Description

The DBFMEMO driver is only capable of handling commands and functions that relate to memo fields. Therefore, it must inherit the non-memo database characteristics (such as SKIP, REPLACE, SEEK, etc.) from a «super» driver (such as DBFNTX).

For example, the DBFCDX RDD is nothing more than the DBFMEMO RDD hardwired to inherit database characteristics from the _DBFCDX RDD. That is, when you use the DBFCDX RDD, you are using the DBFMEMO driver to handle the memo field operations and you are using the _DBFCDX driver to handle the other database and index operations as the «super» driver.

At times, you may want to use a database driver such as DBFNTX instead of DBFCDX but, at the same time, have the efficient and enhanced memo field capabilities of the DBFMEMO RDD instead of the DBT memo file format. In order to do this, you would use MEMOSETSUPER().

Warning! The MEMOSETSUPER() function can only set one inheritance chain per application instance. That is, once you have set MEMOSETSUPER() in an application, MEMOSETSUPER() cannot be changed. Doing so will have unpredictable results.

Examples

■  This example uses MEMOSETSUPER() to create a database (.dbf)
   file with an .fpt/.dbv memo field:

   REQUEST DBFMEMO
   // Set the default to DBFMEMO
   rddSetDefault( "DBFMEMO" )
   // Make DBFMEMO inherit from DBFNTX
   MEMOSETSUPER( "DBFNTX" )

   // Create a DBF with an FPT/DBV not DBT
   dbCreate( "test.dbf", {{"notes", "M", 10, 0}} )

   // Open DBF with FPT/DBV
   // Indexes created would be NTX if created
   USE test NEW

Platforms

Available on MS-DOS

MEMVAR⌃ | ☰

Declare private and public variable names

Syntax

Arguments

idMemvar list is a list of public and private variable names to declare to the compiler.

Description

MEMVAR is a declaration statement that causes the compiler to resolve references to variables specified without an explicit alias by implicitly assuming the memory variable alias (MEMVAR->). Only explicit, unaliased references to the specified variables are affected. MEMVAR, like all declaration statements, has no effect on references made within macro expressions or variables.

The MEMVAR statement neither creates the variables nor verifies their existence. Its primary effect is to ensure correct references to variables whose existence is known to be guaranteed at runtime. At runtime, the specified variables must be created using the PRIVATE, PARAMETERS or PUBLIC statements. This can occur in the procedure containing the MEMVAR declaration or in a higher -level procedure. Attempting to access the variables before they are created will cause an error.

The scope of the MEMVAR declaration is the procedure or function in which it occurs, or the entire source file if it precedes any PROCEDURE or FUNCTION statements and the /N compiler option is used. The /N option suppresses automatic definition of a procedure with the same name as the program (.prg) file.

Like other declaration statements, MEMVAR must precede any executable statements, including PARAMETERS, PUBLIC, and PRIVATE statements in a procedure or function definition, or the program (.prg) file if the declaration has filewide scope.

MEMVAR can be used in conjunction with the /W compiler option—which generates warning messages for ambiguous variable references—to perform compile—time checking for undeclared variables.

For more information on variable declarations and scoping, refer to the Variables section in the «Basic Concepts» chapter of the Programming and Utilities Guide.

Examples

■  This example demonstrates the relationship between a private
   and field variable with the same name.  The private variable is
   declared with the MEMVAR statement:

   FUNCTION Example
      MEMVAR amount, address
      PRIVATE amount := 100
      USE Customer NEW
      //
      ? amount                // Refers to amount private variable
      ? Customer->Amount      // Refers to Amount field variable
      //
      RETURN NIL

Platforms

Available on MS-DOS

See also

MENU TOHarbour implementation⌃ | ☰

Execute a lightbar menu for defined PROMPTs

Syntax

Arguments

idVar is the name of the variable to be assigned the result of the menu selection. If the specified variable is not visible or does not exist, a private variable is created and assigned the result.

Description

MENU TO is the selection mechanism for the CA-Clipper lightbar menu system. Before invoking MENU TO, first define the menu items and associated MESSAGEs with a series of @...PROMPT commands. Then, activate the menu with MENU TO idVar. If idVar does not exist or is not visible, MENU TO creates it as a private variable and places the highlight on the first menu item. If idVar does exist, its initial value determines the first menu item highlighted.

Notes

■ Color: Menu items are painted in the current standard color

with the highlighted menu item appearing in the current enhanced color.

■ Navigation and selection: Pressing the arrow keys moves the

highlight to the next or previous menu item. As each menu item is highlighted the associated MESSAGE displays on the row specified with SET MESSAGE. If WRAP is ON, an Up arrow from the first menu item moves the highlight to the last menu item. Also, a Down arrow from the last menu item moves the highlight to the first.

To make a selection, press Return or the first character of a menu item. MENU TO then returns the position of the selected menu item as a numeric value into the specified memory variable. Pressing Esc aborts the menu selection and returns zero. The table below summarizes the active keys within MENU TO.

SET KEY procedures: A MENU TO command can be nested within a

SET KEY procedure invoked within a menu without clearing the pending PROMPTs.

MENU TO Active Keys

       Key            Action

       Up arrow       Move to previous menu item

       Down arrow     Move to next menu item

       Home           Move to first menu item

       End            Move to last item menu item

       Left arrow     Move to previous menu item

       Right arrow    Move to next menu item

       PgUp           Select menu item, returning position

       PgDn           Select menu item, returning position

       Return         Select menu item, returning position

       Esc            Abort selection, returning zero

       First letter   Select first menu item with same first letter,

                      returning position

Examples

■  This example creates a simple vertical lightbar menu with
   messages appearing centered on line 23.  When invoked, the highlight
   defaults to the second menu item based on the initial value of
   nChoice:

   LOCAL nChoice := 2
   SET WRAP ON
   SET MESSAGE TO 23 CENTER
   @ 6, 10 PROMPT "Add"  MESSAGE "New Acct"
   @ 7, 10 PROMPT "Edit" MESSAGE "Change Acct"
   @ 9, 10 PROMPT "Quit" MESSAGE "Return to DOS"
   MENU TO nChoice
   //
   DO CASE
   CASE nChoice = 0
      QUIT
   CASE nChoice = 1
      NewAccount()
   CASE nChoice = 2
      ChangeAccount()
   CASE nChoice = 3
      QUIT
   ENDCASE
   RETURN

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MHide()Harbour implementation


⌃ | ☰

Hide the mouse pointer

Syntax

Returns

MHide() always returns NIL.

Description

MHide() hides the mouse pointer. This function should be used together with MShow() when updating the screen. It is important to hide the mouse pointer before changing the screen display and then show it again after the change.

Note: The MSetCursor() function should be used in place of MShow() and MHide(). It is kept here for compatibility.

Examples

■  This example uses the mouse pointer:

   MHide()
   @ 10, 20 say "Hi there, folks!!!"
   MShow()

■  You can automate calls to MHide()/MShow() by modifying parts
   of your header files (*.ch).  For example:

   #command @ <row>, <col> SAY <xpr>;[PICTURE <pic>];
      [COLOR <color>];
      => DevPos(<row>, <col>);
      DevOutPict(<xpr>, <pic> [, <color>])
      // Can be changed to
   #command @ <row>, <col> SAY <xpr>;
      [PICTURE <pic>];

      [COLOR <color>];

      => MHide();
      DevPos(<row>, <col>);
      DevOutPict(<xpr>, <pic> [, <color>]);
      MShow()

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

Min()Harbour implementation


⌃ | ☰

Return the smaller of two numeric or date values

Syntax

Min(<nExp1>, <nExp2>) → nSmaller
Min(<dExp1>, <dExp2>) → dSmaller

Arguments

nExp1 and nExp2 are the numeric values to be compared.

dExp1 and dExp2 are the date values to be compared.

Returns

Min() returns the smaller of the two arguments. The value returned is the same data type as the arguments.

Description

Min() is a numeric and date function that ensures the value of an expression is smaller than a specified minimum. The inverse of Min() is Max() which returns the greater of two numeric or date values.

Examples

■  In these examples Min() returns the smaller of two numeric
   values:

   ? Min(99, 100)                  // Result: 99
   ? Min(100, 99)                  // Result: 99

■  In these examples Min() compares date values:

   ? Date()                        // Result: 09/01/90
   ? Min(Date(), Date() + 30)      // Result: 09/01/90

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MLCount()Harbour implementation


⌃ | ☰

Count the number of lines in a character string or memo field

Syntax

MLCount(<cString>, [<nLineLength>],
   [<nTabSize>], [<lWrap>]) → nLines

Arguments

cString is the character string or memo field to be counted.

nLineLength specifies the number of characters per line and can range from four to 254. If not specified, the default line length is 79.

nTabSize defines the tab size. If not specified, the default value is four. If nTabSize is greater than or equal to nLineLength, then the tab size is automatically converted to nLineLength — 1.

lWrap toggles word wrap on and off. Specifying true (.T.) toggles word wrap on; false (.F.) toggles it off. If not specified, the default value is true (.T.).

Returns

MLCount() returns the number of lines in cString depending on the nLineLength, the nTabSize, and whether word wrapping is on or off.

Description

MLCount() is a memo function used with MemoLine() to print character strings and memo fields based on the number of characters per line. In the basic operation, use MLCount() to return the number of lines in the character string or memo field. Then, using MemoLine() to extract each line, loop through the memo field until there are no lines left.

If lWrap is true (.T.) and an end of line position breaks a word, it is word wrapped to the next line and the next line begins with that word. If lWrap is false (.F.), MLCount() counts the number of characters specified by nLineLength as the current line. The next line begins with the character following the next hard or soft carriage return. Intervening characters are ignored.

Examples

■  This example displays the contents of each Notes memo field in
   the Sales database file, one line at a time:

   USE Sales NEW
   nLineLength = 65
   //
   DO WHILE !Eof()
      nLines = MLCount(Sales->Notes, nLineLength)
      FOR nCurrLine = 1 TO nLines

         ? MemoLine(Sales->Notes, nLineLength, nCurrLine)
      NEXT
      SKIP
      ?
   ENDDO

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

MLCToPos()Harbour implementation


⌃ | ☰

Return the byte position of a formatted string based on line and column position

Syntax

MLCToPos(<cText>, <nWidth>, <nLine>,
   <nCol>, [<nTabSize>], [<lWrap>]) → nPosition

Arguments

cText is the text string to be scanned.

nWidth is the line length formatting width.

nLine is the line number counting from 1.

nCol is the column number counting from 0.

nTabSize is the number of columns between tab stops. If not specified, the default is 4.

lWrap is the word wrap flag. If not specified, the default is

true (.T.).

Returns

MLCToPos() returns the byte position within cText counting from 1.

Description

MLCToPos() is a memo function that determines the byte position that corresponds to a particular line and column within the formatted text. Note that the line number is one-relative and the column number is zero-relative. This is compatible with MemoEdit(). The return value is one-relative, making it suitable for use in SubStr() or other string functions.

MLCToPos() is used with MPosToLC() to create search routines or other text processing for MemoEdit(). Refer to the source code for the program editor (PE.EXE) found in the CLIP53SOURCEPE directory.

Examples

■  This example determines the byte position of line 5, column 3
   in the cText string:

   cText := "Note the side on which the bread ;
               is buttered."
   //
   ? MLCToPos(cText, 5, 3, 0)         // Result: 10

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MLeftDown()Harbour implementation


⌃ | ☰

Determine the press status of the left mouse button

Syntax

Returns

MLeftDown() returns true (.T.) if the left mouse button is currently pressed; otherwise, it returns false (.F.).

Description

MLeftDown() determines the button press status of the left mouse button. This is particularly useful for mouse-oriented routines when the status of its left button is critical, such as dragging and dropping or floating menu bars.

Platforms

Available on MS-DOS

See also

MLPos()Harbour implementation


⌃ | ☰

Determine the position of a line in a character string or memo field

Syntax

MLPos(<cString>, <nLineLength>,
   <nLine>, [<nTabSize>], [<lWrap>]) → nPosition

Arguments

cString is a character string or memo field.

nLineLength specifies the number of characters per line.

nLine specifies the line number.

nTabSize defines the tab size. The default is four. If nTabSize is greater than or equal to nLineLength, then the tab size is adjusted to nLineLength — 1.

lWrap toggles word wrap on and off. Specifying true (.T.) toggles word wrap on, and false (.F.) toggles it off. The default is true (.T.).

Returns

MLPos() returns the character position of nLine in cString as an integer numeric value. If nLine is greater than the number of lines in cString, MLPos() returns the length of cString.

Examples

■  This example uses MLPos() to find the position of a specific
   line, given a line length:

   cString = MemoRead("Temp.txt")
   nLineLength = 40
   nLine = 5
   nPosition = MLPos(cString, nLineLength, nLine)
   ? SubStr(cString, nPosition, 12)

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

Mod()*Harbour implementation


⌃ | ☰

Return the dBASE III PLUS modulus of two numbers

Syntax

Mod(<nDividend>, <nDivisor>) → nRemainder

Arguments

nDividend is the dividend of the division operation.

nDivisor is the divisor of the division operation.

Returns

Mod() returns a number representing the remainder of nDividend divided by nDivisor.

Description

Mod() is a numeric function that emulates the dBASE III PLUS Mod() function. It is implemented using the CA-Clipper modulus operator (%). Note that there are differences between the dBASE III PLUS Mod() function and the CA-Clipper modulus operator which are described in the following table:

Differences Between dBASE III PLUS Mod() Function and the CA-Clipper Modulus Operator

    Dividend     Divisor   Modulus Operator    Mod()     dBASE III PLUS

                                                         Mod() function

     3             0            Error          Error           3

     3            -2             1             -1             -1

    -3             2            -1              1              1

    -3             0            Error          Error          -3

    -1             3            -1              2              2

    -2             3            -2              1              1

     2            -3             2             -1             -1

     1            -3             1             -2             -2

Mod() is supplied as a compatibility function and therefore not recommended. It is superseded entirely by the modulus operator (%).

Notes

■ Zero divisor in dBASE III PLUS: In dBASE III PLUS, a zero

divisor returns the dividend for every value of the dividend. In CA-Clipper, by contrast, the modulus of any dividend using a zero divisor causes a runtime error.

■ Zero divisor in earlier versions: In versions of CA-Clipper

prior to Summer ’87, a modulus operation with a zero divisor returned zero for all dividends. In Summer ’87 and later versions, it returns a runtime error.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/MOD.PRG.

Month()Harbour implementation


⌃ | ☰

Convert a date value to the number of the month

Syntax

Arguments

dDate is the date value to be converted.

Returns

Month() returns an integer numeric value in the range of zero to 12. Specifying a null date (CToD(«»)) returns zero.

Description

Month() is a date conversion function that is useful when you require a numeric month value during calculations for such things as periodic reports. Month() is a member of a group of functions that return components of a date value as numeric values. The group includes Day() and Year() to return the day and year values as numerics. CMonth() is a related function that allows you to return the name of the month from a date value.

Examples

■  These examples return the month of the system date:

   ? Date()                        // Result: 09/01/90
   ? Month(Date())                 // Result: 9
   ? Month(Date()) + 1             // Result: 10

■  This example demonstrates Month() acting on a null date:

   #define NULL_DATE   (CToD(""))
   ? Month(NULL_DATE)              // Result: 0

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MPosToLC()Harbour implementation


⌃ | ☰

Return line and column position of a formatted string based on a specified byte position

Syntax

MPosToLC(<cText>, <nWidth>, <nPos>,
   [<nTabSize>], [<lWrap>]) → aLineColumn

Arguments

cText is a text string.

nWidth is the length of the formatted line.

nPos is the byte position within text counting from one (1).

nTabSize is the number of columns between tab stops. If not specified, the default is four (4).

lWrap is the word wrap flag. If not specified, the default is true (.T.).

Returns

MPosToLC() returns an array containing the line and the column values for the specified byte position, nPos.

Description

MPosToLC() is a memo function that determines the formatted line and column corresponding to a particular byte position within cText. Note that the line number returned is one-relative and the column number is zero-relative. This is compatible with MemoEdit(). nPos is one-relative, compatible with At(), RAt(), and other string functions.

MPosToLC(), used with MLCToPos(), can create search routines or other text processing for MemoEdit(). Refer to the source code for the program editor (PE.EXE) found in CLIP53SOURCEPE directory.

Examples

■  This example determines, for the text string shown, the line
   and column corresponding to the tenth character of the text, assuming
   a formatting width of five columns.  A formatting width of five would
   cause each of the first three words to be placed on a line by itself.
   The tenth character of the text is the "s" in "side".  The word
   "side" would be at the leftmost column of the third line of the
   formatted text, so the return value is {3, 0}.

   cText := "Note the side on which the bread ;
         is buttered."
   //
   aLC := MPosToLC(cText, 5, 10)         // Result: {3, 0}

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

MPresent()Harbour implementation


⌃ | ☰

Determine if a mouse is present

Syntax

Returns

MPresent() returns true (.T.) if a mouse is present; otherwise, it returns false (.F.).

Description

MPresent() determines whether a mouse is available or not. For a mouse to be available, it must be physically installed in addition to loading the appropriate mouse device driver.

Platforms

Available on MS-DOS

MRestState()Harbour implementation


⌃ | ☰

Re-establish the previous state of a mouse

Syntax

MRestState( <cSaveState> ) → NIL

Returns

MRestState() always returns NIL.

Description

MRestState() is a function that is used for re-establishing a previously saved mouse state. This includes the mouse’s screen position, visibility, and boundaries.

Platforms

Available on MS-DOS

See also

MRightDown()Harbour implementation


⌃ | ☰

Determine the status of the right mouse button

Syntax

MRightDown() → lIsPressed

Returns

MRightDown() returns true (.T.) if the mouse’s right button is currently pressed; otherwise, it returns false (.F.) .

Description

MRightDown() determines the button press status of the right mouse button. This function is provided in the interest of completeness since, on the PC, the right mouse button is typically reserved for single-click oriented activities such as activating a pop-up menu.

Platforms

Available on MS-DOS

See also

MRow()Harbour implementation


⌃ | ☰

Determine a mouse cursor’s screen row position

Syntax

MRow() → nCurrentMouseRow

Returns

MRow() returns the mouse cursor’s current screen row position.

Description

MRow() is a function that is used for determining the mouse cursor’s screen row position. This is useful when implementing a hit testing routine whose purpose is to determine if the mouse cursor is on pertinent information when the left mouse button is pressed.

Platforms

Available on MS-DOS

See also

MSaveState()Harbour implementation


⌃ | ☰

Save the current state of a mouse

Syntax

MSaveState() → cSaveState

Returns

MSaveState() returns a character string that describes the mouse’s current state.

Description

MSaveState() is a function that is used for storing the mouse’s current state. This includes the mouse’s screen position, visibility, and boundaries.

Platforms

Available on MS-DOS

See also

MSetBounds()Harbour implementation


⌃ | ☰

Set screen boundaries for the mouse cursor

Syntax

MSetBounds( [<nTop>], [<nLeft>], [<nBottom>],
   [<nRight>] ) → NIL

Arguments

nTop defines the uppermost allowable screen row for the mouse cursor or 0 if omitted. This value may range from 0 to the value of nBottom.

nLeft defines the leftmost allowable screen column for the mouse or 0 if omitted. This value may range from 0 to the value of nRight.

nBottom defines the bottommost screen row for the mouse cursor or MaxRow() if omitted. This value may range from the value of nTop to MaxRow().

nRight defines the rightmost allowable screen column for the mouse or MaxCol() if omitted. This value may range from the value of nLeft to MaxCol().

Returns

MSetBounds() always returns NIL.

Description

MSetBounds() is a function that is used for setting the region of the screen that the mouse cursor is restricted to. The default at startup is the entire screen. This setting is automatically maintained by the runtime’s mouse subsystem when the screen mode is changed, for example, from the 50-line mode to the 25-line mode.

Platforms

Available on MS-DOS

MSetCursor()Harbour implementation


⌃ | ☰

Determine a mouse’s visibility

Syntax

MSetCursor( [<lVisible>] ) → lIsVisible

Arguments

lVisible determines if the mouse should be visible. Set to true (.T.) to show the mouse cursor and set to false (.F.) to hide it.

Returns

MSetCursor() returns the mouse cursor’s previous visibility state if lVisible is passed; otherwise, it returns its current visibility state.

Description

MSetCursor() is a function that determines whether the mouse cursor is visible or not.

Platforms

Available on MS-DOS

MSetPos()Harbour implementation


⌃ | ☰

Set a new position for the mouse cursor

Syntax

MSetPos( <nRow>, <nCol> ) → NIL

Returns

MSetPos() always returns NIL.

Description

MSETPOS () is a function that moves the mouse cursor to a new position on the screen. After the mouse cursor is positioned, MRow() and MCol() are updated accordingly. To control the visibility of the mouse cursor, use MSetCursor().

Platforms

Available on MS-DOS

See also

MSETCLIP()


⌃ | ☰

Define an inclusion region

Syntax

MSETCLIP([<nCoord list>], [<nMode>])

Arguments

nCoord List contains the coordinates of the inclusion region which is represented as a comma-separated list of four coordinates whose interpretation differs depending on mode. If nMode is LLM_COOR_TEXT, the coordinates look like this: nTop, nLeft, nBottom, nRight. If nMode is LLM_COOR_GRAPH, the coordinates are nX1, nY1, nX2, nY2.

nMode is one of the following two constants:

Coordinate Type Constants

    Constant       Description

    LLM_COOR_TEXT  Specifies that the coordinates are given in lines and

                   columns of text

    LLM_COOR_GRAPH Specifies that the coordinates are given in pixels

Returns

MSETCLIP() returns an array of coordinate information. The coordinates of the inclusion area are given in pixels and then in row/col format:

aRegions := {nIncX1, nIncY1, nIncX2, nIncY2,;

nIncR1, nIncC1, nIncR2, nIncC2,; nCoorType}

Description

MSETCLIP() controls mouse pointer movements. It allows you to restrict movement to a region. When an inclusion is defined and the user tries to move the mouse pointer out of the rectangle, it remains stuck at the edge of the area, but is still visible. This mode should be used to restrict the range of user choices for moving or clicking the mouse.

Notes

The inclusion area is initialized to be the entire screen. To eliminate an inclusion region you just pass the value LLM_INCLUDE as the first parameter or pass the four parameters for maximum screen values 0, 0, MaxCol(), MaxRow().

Examples

■  This example shows how the MSETCLIP() function works:

   // Define an inclusion region and save the current
   // inclusion region in the array aOldInc

      aOldInc := MSETCLIP(5, 5, 20, 75,LLM_COOR_TEXT)
   // Code for selecting objects and buttons
   // Restore old inclusion region
   MSETCLIP(aOldInc[5],;
      aOldInc[6],;
      aOldInc[7],;
      aOldInc[8],;
   LLG_VIDEO_TEXT)

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

MShow()Harbour implementation


⌃ | ☰

Display the mouse pointer

Syntax

MShow([<nCol>, <nRow>, <nStyle>])
    → nOldCursorShape

MShow([<nCursorShape>]) → nOldCursorShape

MShow([<nCursorShape>] | [<nCol>, <nRow>, <nMode>])
    → nOldCursorShape

Arguments

nCol and nRow define mouse pointer coordinates.

nStyle defines the style of mouse pointer using one of the constants listed in the table below:

Text and Graph Constants

    Constant       Description

    LLM_COOR_TEXT  Specifies that the coordinates are passed in rows and

                   columns of text

    LLM_COOR_GRAPH Specifies that the coordinates are passed in pixels

nCursorShape is a numeric value representing the mouse cursor shape. The following are the possible values predefined for this parameter:

Cursor Shape Constants

    Constant                 Description

    LLM_CURSOR_ARROW         Standard pointer

    LLM_CURSOR_SIZE_NS       North South arrow

    LLM_CURSOR_SIZE_WE       West East arrow

    LLM_CURSOR_SIZE_NW_SE    North-West South-East arrow

    LLM_CURSOR_SIZE_NE_SW    North-East South-West arrow

    LLM_CURSOR_HAND          Hand

    LLM_CURSOR_FINGER        Hand with one pointing finger

    LLM_CURSOR_CROSS         Cross

    LLM_CURSOR_WAIT          Hourglass

Returns

MShow() returns the previously used cursor shape. See nCurorShape above for further information.

Description

MShow() displays the mouse pointer. It is generally used without parameters to simply redisplay the mouse pointer at the position where MHide() hid it (assuming the user has not moved the mouse).

It is possible to use two sets of parameters with this function.

■ Specify the coordinates where the pointer should appear. In

this case, three parameters must be passed: the mode and its coordinates. In text mode, coordinates are passed as row and column. In graphic mode, you can pass either text or graphic coordinates. Conversion is done automatically based on the font size of the current characters.

■ You can also specify the mouse cursor shape to be displayed

when the mouse is visible. This feature is available in graphic mode only.

It is important to hide the mouse pointer before any new screen display, and then show it again. See MHide() for further information on how to do this.

Note: The MSetCursor() function should be used in place of MShow() and MHide(). It is kept here for compatibility.

Examples

■  The following example hides the mouse pointer before using an
   @...SAY command and then redisplays it.  Next, the mouse pointer is
   repositioned, hidden, changed to an hour-glass, and then restored to
   its previous shape:

   LOCAL nOldShape := 0
   MHide()
      @ 10, 20 say "Hello world!!!"
   MShow()
   // Position the pointer at the center of the screen
   MShow(MaxCol() / 2, MaxRow() / 2, LLM_COOR_TEXT)
   MHide()
      @ 10, 20 say "Please wait ..."
   // Display an hour glass cursor
   nOldShape := MShow(LLM_CURSOR_WAIT)
   // Your code
   // Restore previously used cursor
   MShow(nOldShape)

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

MSTATE()


⌃ | ☰

Return the current mouse state

Syntax

Returns

MSTATE() Return Array

    Position                 Description

    LLM_STATE_X              State of X position.

    LLM_STATE_Y              State of Y position.

    LLM_STATE_ROW            State of column position.

    LLM_STATE_COL            State of line position.

    LLM_STATE_LEFT           State of left mouse button.  LLM_BUTTON_DOWN

                             means down and LLM_BUTTON_UP means up.

    LLM_STATE_RIGHT          State of right mouse button.  LLM_BUTTON_DOWN

                             means down and LLM_BUTTON_UP means up.

    LLM_STATE_VISIBLE        State of mouse pointer.  True (.T) means

                             visible and false (.F) means invisible.  (See

                             MShow() and MHide() for more information.)

    LLM_STATE_DRIVER         Indicates version of mouse driver.

    LLM_STATE_SHAPE          Mouse cursor shape.  (See note below.)

    LLM_STATE_CLICKS_LEFT    Number of left clicks since last MSTATE() call.

    LLM_STATE_CLICKS_RIGHT   Number of right clicks since last MSTATE()

                             call.

Note: The following are the possible values predefined for this return array position: LLM_CURSOR_ARROW, LLM_CURSOR_SIZE_NS, LLM_CURSOR_SIZE_WE, LLM_CURSOR_SIZE_NW_SE, LLM_CURSOR_SIZE_NE_SW, LLM_CURSOR_HAND, LLM_CURSOR_FINGER, LLM_CURSOR_CROSS, LLM_CURSOR_WAIT. For a description of these values see the MShow() table of Cursor Shape Constants.

If the mouse is missing, 0 is returned.

The number of clicks (i.e., aState[LLM_STATE_CLICKS_LEFT] and aState[LLM_STATE_CLICKS_RIGHT]) is reset each time MSTATE() is called. Use MSTATE() to reset the mouse settings when needed.

Description

MSTATE() returns information on the mouse state, i.e., the current screen position of the pointer, the state of the left and right mouse buttons, the visibility status of the mouse pointer, and the version of the mouse driver.

Notes

If the version of the mouse driver (i.e., aState[LLM_STATE_DRIVER]) is NULL («»), this indicates that the mouse is not connected or is configured incorrectly. Do not hesitate to insert a version check such as the following:

IF MSTATE()[LLM_STATE_DRIVER]<=500

// Consider the mouse to be absent

ELSE

// Consider the mouse to be present

ENDIF

Warning! Old mouse drivers are usually unreliable and can cause odd behavior in your application, such as a poorly drawn pointer and unsatisfactory saves and restores of the pointer and underlying pixels.

Examples

■  This example shows how to use MSTATE() function:

   // Show the mouse pointer
   MShow()
   DO WHILE Inkey() != K_ESC
                  // Retrieve mouse state
      aState := MSTATE()
                  // Line position
      @ 24,  0 SAY aState[LLM_STATE_ROW]
                  // Column position
      @ 24, 10 SAY aState[LLM_STATE_COL]
                  // State of left button
      @ 24, 20 SAY "Left" + If(aState[LLM_STATE_LEFT]==LLM_BUTTON_DOWN,;
      "Down"  ,;
      "Up")
                  // State of right button
      @ 24, 40 SAY "Right " + If(aState[LLM_STATE_RIGHT]==    ;
      LLM_BUTTON_DOWN ,;
      "Down"  ,;
      "Up")
   ENDDO
      // Hide the mouse pointer
   MHide()

Platforms

Available on MS-DOS

File

Library is LLIBG.LIB, header file is Llibg.ch.

See also

NetErr()Harbour implementation


⌃ | ☰

Determine if a network command has failed

Syntax

NetErr([<lNewError>]) → lError

Arguments

lNewError, if specified, sets the value returned by NetErr() to the specified status. lNewError can be either true (.T.) or false (.F.). Setting NetErr() to a specified value allows the runtime error handler to control the way certain file errors are handled. For more information, refer to Errorsys.prg.

Returns

NetErr() returns true (.T.) if a USE or APPEND BLANK fails. The initial value of NetErr() is false (.F.). If the current process is not running under a network operating system, NetErr() always returns false (.F.).

Description

NetErr() is a network function. It is a global flag set by USE, USE...EXCLUSIVE, and APPEND BLANK in a network environment. It is used to test whether any of these commands have failed by returning true (.T.) in the following situations:

NetErr() Causes

    Command             Cause

    USE                 USE EXCLUSIVE by another process

    USE…EXCLUSIVE     USE EXCLUSIVE or USE by another process

    APPEND BLANK        FLock() or RLock() of LastRec() + 1 by another user

NetErr() is generally applied in a program by testing it following a USE or APPEND BLANK command. If it returns false (.F.), you can perform the next operation. If the command is USE, you can open index files. If it is APPEND BLANK, you can assign values to the new record with a REPLACE or @...GET command. Otherwise, you must handle the error by either retrying the USE or APPEND BLANK, or terminating the current operation with a BREAK or RETURN.

Examples

■  This example demonstrates typical usage of NetErr().  If the
   USE succeeds, the index files are opened and processing continues.
   If the USE fails, a message displays and control returns to the
   nearest BEGIN SEQUENCE construct:

   USE Customer SHARED NEW
   IF !NetErr()
      SET INDEX TO CustNum, CustOrders, CustZip
   ELSE
      ? "File is in use by another"
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

NetName()Harbour implementation


⌃ | ☰

Return the current workstation identification

Syntax

NetName() → cWorkstationName

Returns

NetName() returns the workstation identification as a character string up to 15 characters in length. If the workstation identification was never set or the application is not operating under the IBM PC Network, it returns a null string («»).

Examples

■  This example demonstrates the NetName() result when a
   workstation is started as a network node with a station identifier of
   "STATION 1":

   ? NetName()               // Result: STATION 1

■  This example demonstrates the NetName() result when a
   workstation is started as a stand-alone unit:

   ? NetName()               // Result: ""

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

NextKey()Harbour implementation


⌃ | ☰

Read the pending key in the keyboard buffer

Syntax

Returns

NextKey() returns an integer numeric value ranging from -39 to 386 for keyboard events and integer values from 1001 to 1007 for mouse events. This value identifies either the key extracted from the keyboard buffer or the mouse event that last occurred. If the keyboard buffer is empty and no mouse events are taking place, NextKey() returns zero. If SET TYPEAHEAD is zero, NextKey() always returns zero.

Description

NextKey() is a function that reads the keystroke pending in the keyboard buffer or the next mouse event without removing it. The value returned is the Inkey() code of the key pressed—the same value as returned by Inkey() and LastKey(). NextKey() returns values for all ASCII characters as well as function, Alt+function, Ctrl+function, Alt+letter, and Ctrl+letter key combinations.

NextKey() is like the Inkey() function but differs in one fundamental respect. Inkey() removes the pending key from the keyboard buffer and updates LastKey() with the value of the key. by contrast NextKey() reads, but does not remove the key from the keyboard buffer, and does not update LastKey().

Since NextKey() does not remove the key from the keyboard buffer, it can be used to poll the keyboard, and then pass control to a routine that uses a wait state or Inkey() to actually fetch the key from the buffer.

For a complete list of Inkey() codes and inkey.ch constants, refer to the «CA-Clipper Inkey Codes Appendix» in the Error Messages and Appendices Guide.

Examples

■  This example places an Esc key in the keyboard buffer, and
   then shows the differences between Inkey(), LastKey(), and NextKey():

   #include "Inkey.ch"
   //
   CLEAR TYPEAHEAD
   KEYBOARD CHR(K_ESC)
   //
   ? NextKey(), LastKey()            // Result: 27 0
   ? Inkey(), LastKey()              // Result: 27 27
   ? NextKey()                       // Result: 0

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, header file is inkey.ch.

See also

NoSnow()Harbour implementation


⌃ | ☰

Toggle snow suppression

Syntax

Arguments

lToggle is a logical value that toggles the current state of snow suppression. A value of true (.T.) enables the snow suppression on, while a value of false (.F.) disables snow suppression.

Description

NoSnow() is used to suppress snow on CGA monitors. Typically, use NoSnow() in the configuration section of your application to give the user the option to suppress snow.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

NOTE*Harbour implementation⌃ | ☰

Place a single-line comment in a program file

Syntax

Arguments

commentText is a string of characters placed after the comment indicator.

Description

NOTE is command synonym for the single-line comment indicator (*). All characters after NOTE are ignored until the CA-Clipper compiler encounters an end of line (carriage return/line feed). This means a single-line comment cannot be continued with the semicolon (;) onto a new line.

If you need a multi-line or inline comment, begin the comment block with a slash-asterisk (/*) symbol and end the comment block with an asterisk-slash (*/) symbol. If you need to comment out a block of code, use the conditional compilation directives #ifdef…#endif instead of multiline comments. This is important since nested comments are illegal.

NOTE is a compatibility command and therefore not recommended. It is superseded by the C-style comment symbols slash-asterisk (/*) and asterisk-slash (*/), as well as the double-slash (//). It is also superseded by the dBASE-style comment symbols, asterisk (*) and the double-ampersand (&&).

For a complete discussion on comment indicators, refer to the «Basic Concepts» chapter in the Programming and Utilities Guide.

Examples

■  These examples show the various comment symbols supported by
   CA-Clipper:

   // This is a comment
   /* This is a comment */
   * This is a comment
   && This is a comment
   NOTE This is a comment

Platforms

Available on MS-DOS

ordBagExt()Harbour implementation


⌃ | ☰

Return the default order bag RDD extension

Syntax

Returns

ordBagExt() returns a character expression.

Description

ordBagExt() is an order management function that returns a character expression that is the default order bag extension of the current or aliased work area. cBagExt is determined by the RDD active in the current work area.

Notes

ordBagExt() supersedes the IndexExt() function, which is not

recommended.

ordBagExt() returns the default index extension of the driver

loaded, not the actual index file extension.

Examples

USE sample VIA "DBFNTX"
? ordBagExt()      //  Returns .ntx

Platforms

Available on MS-DOS

See also

ordBagName()Harbour implementation


⌃ | ☰

Return the order bag name of a specific order

Syntax

ordBagName(<nOrder> | <cOrderName>) → cOrderBagName

Arguments

nOrder is an integer that identifies the position in the order list of the target order whose order bag name is sought.

cOrderName is a character string that represents the name of the target order whose order bag name is sought.

Returns

ordBagName() returns a character string, the order bag name of the specific order.

Description

ordBagName() is an order management function that lets you access the name of the order bag in which cOrderName resides. You may identify the order as a character string or with an integer that represents its position in the order list. In case of duplicate names, ordBagName() only recognizes the first matching name.

Note: ordBagName(0) works as ordBagName(IndexOrd())

Examples

■  The following example uses ordBagName() with the default
   DBFNTX driver:

   USE Customer VIA "DBFNTX" NEW
   SET INDEX TO CuAcct, CuName, CuZip
   ordBagName(2)               // Returns: CuName
   ordBagName(1)               // Returns: CuAcct
   ordBagName(3)               // Returns: CuZip

■  In this example, Customer.cdx contains three orders named
   CuAcct, CuName, CuZip:

   USE Customer VIA "DBFCDX" NEW
   SET INDEX TO Customer
   ordBagName("CuAcct")      // Returns: Customer
   ordBagName("CuName")      // Returns: Customer
   ordBagName("CuZip")      // Returns: Customer

Platforms

Available on MS-DOS

See also

ordCondSet()Harbour implementation


⌃ | ☰

Set the condition and scope for an order

Syntax

ordCondSet([<cForCondition>],
   [<bForCondition>],
   [<lAll>],
   [<bWhileCondition>],
   [<bEval>],
   [<nInterval>],
   [<nStart>],
   [<nNext>],
   [<nRecord>],
   [<lRest>],
   [<lDescend>],
   [<lAdditive>],
   [<lCurrent>],
   [<lCustom>],
   [<lNoOptimize>]) → lSuccess

Arguments

cForCondition is a string that specifies the FOR condition for the order. This string is returned by dbOrderInfo(DBOI_CONDITION, [cIndexFile], cOrder). If you do not need this information, you can specify a null string («»).

bForCondition is a code block that defines a FOR condition that each record within the scope must meet in order to be processed. If a record does not meet the specified condition, it is ignored and the next record is processed. Duplicate key values are not added to the index file when a FOR condition is used. The default is NIL.

This condition (not cForCondition) is the one that is actually used to create the order. Unlike the WHILE condition and other scoping information, the FOR condition is stored as part of the index file and is used when updating or rebuilding the order with dbReindex(). Any limitations on the FOR condition are determined by the RDD (see the «Replaceable Database Driver Architecture» chapter in the Drivers Guide for information about RDD limitations).

lAll is specified as true (.T.) to define a scope of all records. Use false (.F.) if you want to indicate other record scoping conditions (i.e., nNext, nRecord, or lRest). The default is false (.F.).

bWhileCondition is a code block that defines a condition that each record must meet in order to be processed. If no scope is specified, using a bWhileCondition changes the default scope to lRest. As soon as a record is encountered that causes the condition to fail, the operation terminates.

The WHILE condition is used only to create the order. It is not stored in the index file or used for updating or reindexing purposes. The default is NIL.

bEval is a code block that is evaluated at intervals specified by nInterval. This is useful in producing a status bar or odometer that monitors the ordering progress. The return value of bEval must be a logical value. If bEval returns false (.F.), indexing halts. The default is NIL.

nInterval is a numeric expression that determines the number of times bEval is evaluated. This argument offers a performance enhancement by evaluating the condition at intervals instead of evaluating every record processed. To step through every record, you can specify a value of 0. The default is 0.

nStart is the starting record number. To start at the beginning of the file, specify a value of 0. The default is 0.

You define the scope using one of these three, mutually exclusive arguments (use 0 or false (.F.) for the others). The default is all records. Record scoping information is used only to create the order. It is not stored in the index file or used for index updates and reindexing purposes.

nNext is the number of records to process, starting at nStart. Specify 0 to ignore this argument.

nRecord is a single record number to process. Specify 0 to ignore this argument.

lRest is specified as true (.T.) to process only records from nStart to the end of the file. False (.F.) processes all records.

lDescend specifies whether the keyed pairs should be sorted in decreasing or increasing order of value. True`.T.) results in descending order and false (.F.) results in ascending order. The default is false (.F.).

lAdditive specifies whether open orders should remain open while the new order is being created. True (.T.) specifies that they should remain open. False (.F.) is the default and it specifies that all open orders should be closed.

lCurrent specifies whether only records in the controlling order— and within the current range as specified by ORDSETSCOPE()—will be included in this order. True (.T.) specifies that the controlling order and range should be used to limit the scope of the newly created order. False (.F.) is the default and it specifies that all records in the database file are included in the order.

lCustom specifies whether the new order will be a custom built order (for RDDs that use this feature). True (.T.) specifies that a custom built order will be created. A custom built order is initially empty, giving you complete control over order maintenance. The system does not automatically add and delete keys from a custom built order. Instead, you explicitly add and delete keys using ordKeyAdd() and ordKeyDel(). False (.F.) specifies a standard, system-maintained order. The default is false (.F.).

lNoOptimize specifies whether the FOR condition will be optimized (for RDDs that support this feature). True (.T.) optimizes the FOR condition, and false (.F.) does not. The default is false (.F.).

Returns

ordCondSet() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

By default ordCondSet() operates on the currently selected work area. This function can be made to operate on an unselected work area by specifying it within an aliased expression.

Unless you specify otherwise with ordCondSet(), new orders that you create will use default scoping rules, processing all records in the work area. ordCondSet() allows you to specify conditions and scoping rules that records must meet in order to be included in the next order created. Creating a new order automatically resets the work area to use the default scoping rules. Thus, if scoping is required, you must reset ordCondSet() each time you create a new order.

This function is essential if you want to create conditional orders using dbCreateIndex() because this function does not support arguments to do this.

Examples

■  The following example sets the condition for the creation of
   orders:

   LOCAL cFor AS STRING
   LOCAL lAll, lRest, lDescend AS LOGIC
   LOCAL bForCondition, bWhileCondition, ;
      bEval AS USUAL
   LOCAL nStep, nStart, nNext, nRecord AS SHORTINT
   // For condition string format
   cFor := 'Upper(Name) = "MELISSA"'
   // Actual for condition
   bForCondition := {|| Upper(Name) = "MELISSA"}
   lAll := .T.
   bWhileCondition := {|| .T.}         // While all
   bEval := {|| Name + City}           // Indexing code
                                       // block
   nStep := 0                          // Step through all
   nStart := 0                         // From top
   nNext := 0                          // All
   nRecord := 0                        // All records

   lRest := .F.                        // All
   lDescend :=  .F.                    // Ascending
   ordCondSet(cFor, bForCondition, lAll, ;
      bWhileCondition, bEval, nStep, nStart, ;
      nNext, nRecord, lRest, lDescend)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordCreate()Harbour implementation


⌃ | ☰

Create an order in an order bag

Syntax

ordCreate(<cOrderBagName>,[<cOrderName>],
   <cExpKey>, <bExpKey>, [<lUnique>]) → NIL

Arguments

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or extension. Without the extension, CA-Clipper uses the default extension of the current RDD.

cOrderName is the name of the order to be created.

Note: Although both cOrderBagName and cOrderName are both optional, at least one of them must be specified.

cExpKey is an expression that returns the key value to place in the order for each record in the current work area. cExpKey can represent a character, date, logical, or numeric data type. The database driver determines the maximum length of the index key expression.

bExpKey is a code block that evaluates to a key value that is placed in the order for each record in the current work area. If you do not supply bExpKey, it is macro-compiled from cExpKey.

lUnique is an optional logical value that specifies whether a unique order is to be created. If lUnique is omitted, the current global _SET_UNIQUE setting is used.

Returns

ordCreate() always returns NIL.

Description

ordCreate() is an order management function that creates an order in the current work area. It works like dbCreateIndex() except that it lets you create orders in RDDs that recognize multiple-order bags. ordCreate() supersedes the dbCreateIndex() function because of this capability, and it is the preferred function.

The active RDD determines the order capacity of an order bag. The default DBFNTX and DBFNDX drivers only support single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBFMDX drivers).

In RDDs that support production or structural indices (e.g., DBFCDX, DBPX), 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.

If cOrderBagName does not exist, it is created in accordance with the RDD in the current or specified work area.

If cOrderBagName exists and the RDD specifies that order bags can only contain a single order, cOrderBagName is erased and the new order is added to the order list in the current or specified work area.

If cOrderBagName exists and the RDD specifies that order bags can contain multiple tags, cOrderName is created if it does not already exist; otherwise cOrderName is replaced in cOrderBagName and the order is added to the order list in the current or specified work area.

Examples

■  The following example demonstrates ordCreate() with the DBFNDX
   driver:

   USE Customer VIA "DBFNDX" NEW
   ordCreate("CuAcct",, "Customer->Acct")


■  The following example demonstrates ordCreate() with the
   default DBFNTX driver:

   USE Customer VIA "DBFNTX" NEW
   ordCreate("CuAcct", "CuAcct", "Customer->Acct", ;
         {|| Customer->Acct })

■  The following example demonstrates ordCreate() with the FoxPro
   driver, DBFCDX:

   USE Customer VIA "DBFCDX" NEW
   ordCreate("Customer", "CuAcct", "Customer->Acct")

■  This example creates the order "CuAcct" and adds it to the
   production index (order bag) "Customer."  The production index will
   be created if it does not exist:

USE Customer VIA "DBFMDX" NEW

   ordCreate(, "CuAcct", "Customer->Acct")

Platforms

Available on MS-DOS

See also

ordDescend()Harbour implementation


⌃ | ☰

Return and optionally change the descending flag of an order

Syntax

ordDescend([<cOrder> | <nPosition>],[<cIndexFile>],
   [<lNewDescend>]) → lCurrentDescend

Arguments

cOrder | nPosition is the name of the order or a number representing its position in the order list. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. If omitted or NIL, the controlling order is assumed.

Specifying an invalid value will raise a runtime error.

cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.

If cIndexFile is not open by the current process, a runtime error is raised.

lNewDescend is a logical value that if true (.T.) dynamically turns on the descending flag for the order, resulting in descending order. False (.F.) dynamically turns the flag off, resulting in ascending order.

Returns

If lNewDescend is not specified, ordDescend() returns the current setting. If lNewDescend is specified, the previous setting is returned.

Description

ordDescend() changes the ascending/descending flag at runtime only—it does not change the descending flag stored in the actual index file. To change the descending flag in the index file, see the INDEX command in the Reference Guide, Volume 1.

By default, this function 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.

Examples

■  The following example illustrates ordDescend().  Every order
   can be both ascending and descending:

   USE Customer VIA "DBFCDX"
   INDEX ON LastName TAG Last
   INDEX ON FirstName TAG First DESCENDING

   SET ORDER TO TAG Last
   // Last was originally created in ascending order

   // Swap it to descending
   ordDescend(,, .T.)
   // Last will now be processed in descending order

   SET ORDER TO TAG First
   // First was originally created in descending order

   // Swap it to ascending
   ordDescend(,, .F.)
   // First will now be processed in ascending order

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordDestroy()Harbour implementation


⌃ | ☰

Remove a specified order from an order bag

Syntax

ordDestroy(<cOrderName> [, <cOrderBagName>]) → NIL

Arguments

cOrderName is the name of the order to be removed from the current or specified work area.

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.

Returns

ordDestroy() always returns NIL.

Description

ordDestroy() is an order management function that removes a specified order from multiple-order bags.

The active RDD determines the order capacity of an order bag. The default DBFNTX and the DBFNDX drivers only support single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBPX drivers).

Note: RDD suppliers may define specific behaviors for this command.

Warning! ordDestroy() is not supported for DBFNDX and DBFNTX.

Examples

■  This example demonstrates ordDestroy() with the FoxPro driver,
   DBFCDX:

   USE Customer VIA "DBFCDX" NEW
   SET INDEX TO Customer, CustTemp
   ordDestroy("CuAcct", "Customer")

Platforms

Available on MS-DOS

See also

ordFor()Harbour implementation


⌃ | ☰

Return the FOR expression of an order

Syntax

ordFor(<cOrderName> | <nOrder> [, <cOrderBagName>])
   → cForExp

Arguments

cOrderName is the name of the target order whose cForExp is sought.

nOrder is an integer that identifies the position in the order list of the target order whose cForExp is sought.

cOrderBagName is the name of an order bag containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.

Returns

ordFor() returns a character expression, cForExp, that represents the FOR condition of the specified order. If the order was not created using the FOR clause, the return value will be an empty string («»). If the database driver does not support the FOR condition, it may either return an empty string («») or raise an «unsupported function» error, depending on the driver.

Description

ordFor() is an order management function that returns the character string, cForExp, that represents the logical FOR condition of cOrderName or nOrder.

Note: ordFor(0) works as ordFor(IndexOrd()).

Examples

■  This example retrieves the FOR condition from an order:

   USE Customer NEW
   INDEX ON  Customer->Acct   ;
      TO  Customer      ;
      FOR Customer->Acct > "AZZZZZ"

   ordFor("Customer")      // Returns: Customer->Acct > "AZZZZZ"

Platforms

Available on MS-DOS

See also

ordIsUnique()Harbour implementation


⌃ | ☰

Return the status of the unique flag for a given order

Syntax

ordIsUnique([<cOrder> | <nPosition>],
   [<cIndexFile>]) → lUnique

Arguments

cOrder | nPosition is the name of the order or a number representing its position in the order list. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. If omitted or NIL, the controlling order is assumed.

Specifying an invalid order will raise a runtime error.

cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.

If cIndexFile is not open by the current process, a runtime error is raised.

Returns

ordIsUnique() returns the status of the indicated order’s unique flag as a logical value.

Description

By default, this function 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.

Examples

■  This example shows the return value of ordIsUnique() using
   various orders:

   USE Customer VIA "DBFCDX"
   INDEX ON LastName TAG Last UNIQUE
   INDEX ON FirstName TAG First
   INDEX ON Age TO j:testtmpage UNIQUE

   SET ORDER TO TAG Last

   ? ordIsUnique()                // Result: .T. for Last
   ? ordIsUnique("First")         // Result: .F.
   ? ordIsUnique("Age")           // Result: .T.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordKey()Harbour implementation


⌃ | ☰

Return the key expression of an order

Syntax

ordKey(<cOrderName> | <nOrder>
   [, <cOrderBagName>]) → cExpKey

Arguments

cOrderName is the name of an order, a logical ordering of a database.

nOrder is an integer that identifies the position in the order list of the target order whose cExpKey is sought.

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.

Returns

Returns a character string, cExpKey.

Description

ordKey() is an order management function that returns a character expression, cExpKey, that represents the key expression of the specified order.

You may specify the order by name or with a number that represents its position in the order list. Using the order name is the preferred method.

The active RDD determines the order capacity of an order bag. The default DBFNTX and the DBFNDX drivers only support single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBFMDX drivers).

Note: ordKey(0) works as ordKey(IndexOrd()).

Examples

■  This example retrieves the index expression from an order:

   USE Customer NEW
   INDEX ON  Customer->Acct   ;
      TO  Customer      ;
      FOR Customer->Acct > "AZZZZZ"

   ordKey("Customer")      // Returns: Customer->Acct

Platforms

Available on MS-DOS

See also

ordKeyAdd()Harbour implementation


⌃ | ☰

Add a key to a custom built order

Syntax

ordKeyAdd([<cOrder> | <nPosition>],
   [<cIndexFile>],[<expKeyValue>]) → lSuccess

Arguments

cOrder | nPosition is the name of the order or a number representing its position in the order list. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. If omitted or NIL, the controlling order is assumed.

Specifying an invalid order, such as one that is not custom built, will raise a runtime error.

cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.

If cIndexFile is not open by the current process, a runtime error is raised.

expKeyValue is a specific key value that you want to add for the current record. The data type must match that of the order. If not specified, the order’s key expression is evaluated for the current record and added to the order.

Returns

ordKeyAdd() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

ordKeyAdd() adds keys to a custom built order which is an order that is not automatically maintained by the DBFCDX driver. You can determine if an order is custom built using dbOrderInfo(DBOI_CUSTOM, …). When you create such an order, it is initially empty. You must then manually add and delete keys using ordKeyAdd() and ordKeyDel().

Note: An existing order can be changed to a custom built order by using the dbOrderInfo() function.

ordKeyAdd() evaluates the key expression (or expKeyValue, if specified), and then adds the key for the current record to the order. If the order has a for condition, the key will be added only if that condition is met, and then only if it falls within the current scoping range.

Note: You can add several keys for the same record with consecutive calls to ordKeyAdd().

ordKeyAdd() will fail if:

■ The record pointer is positioned on an invalid record (i.e.,

at Eof())

■ The specified order is not custom built

■ The specified order does not exist

■ No order was specified and there is no controlling order

By default, this function 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.

Examples

■  This example creates a custom index and adds every fiftieth
   record to it:

   USE Customer VIA "DBFCDX"
   // Create custom-built order that is initially empty
   INDEX ON LastName TO Last CUSTOM

   // Add every 50th record
   FOR n := 1 TO RecCount() STEP 50
      GOTO n
      ordKeyAdd()
   NEXT

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordKeyCount()Harbour implementation


⌃ | ☰

Return the number of keys in an order

Syntax

ordKeyCount([<cOrder> | <nPosition>],
   [<cIndexFile>]) → nKeys

Arguments

cOrder | nPosition is the name of the order or a number representing its position in the order list. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. If omitted or NIL, the controlling order is assumed.

Specifying an invalid order will raise a runtime error.

cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.

If cIndexFile is not open by the current process, a runtime error is raised.

Returns

ordKeyCount() returns the number of keys in the specified order.

Description

ordKeyCount() counts the keys in the specified order and returns the result as a numeric value. If the order is not conditional and no scope has been set for it, ordKeyCount() is identical to RecCount(), returning the number of records in the database file. However, for a conditional order, there may be fewer keys than there are records, since some records may not meet the order’s for condition or may not fall inside the scope specified by ordScope()—in counting the keys, ordKeyCount() respects the currently defined scope and for condition.

By default, this function 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.

Examples

■  This example demonstrates using ordKeyCount() with various
   orders:

   USE customer
   // Assume 1000 total records,
   // 500 less than thirty years old, and
   // 895 making less than 50,000

   INDEX ON Age TO Age

   INDEX ON First TO First FOR Age < 30
   INDEX ON Last TO Last FOR Salary < 50000

   // Age is the controlling order
   SET INDEX TO Age, First, Last

   ? RecCount()                     // Result: 1000
   ? ordKeyCount()                  // Result: 1000

   ? ordKeyCount("First")         // Result: 500
   ? ordKeyCount(3)               // Result: 895

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordKeyDel()Harbour implementation


⌃ | ☰

Delete a key from a custom built order

Syntax

ordKeyDel([<cOrder> | <nPosition>],
   [<cIndexFile>],
   [<expKeyValue>]) → lSuccess

Arguments

cOrder | nPosition is the name of the order or a number representing its position in the order list. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. If omitted or NIL, the controlling order is assumed.

Specifying an invalid order, such as one that is not custom built, will raise a runtime error.

cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.

If cIndexFile is not open by the current process, a runtime error is raised.

expKeyValue is a specific key value that you want to delete for the current record. The data type must match that of the order. If not specified, the order’s key expression is evaluated for the current record and deleted from the order.

Returns

ordKeyDel() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

ordKeyDel() deletes a key from a custom built order which is an order that is not automatically maintained by the DBFCDX driver. You can determine if an order is custom built using dbOrderInfo(DBOI_CUSTOM, …). When you create such an order, it is initially empty. You must then manually add and delete keys using ordKeyAdd() and ordKeyDel().

Note: An existing order can be changed to a custom built order by using the dbOrderInfo() function.

ordKeyDel() evaluates the key expression (or expKeyValue, if specified), and then deletes the key for the current record from the order.

ordKeyDel() will fail if:

■ The record pointer is positioned on an invalid record (for

example, Eof() returns true (.T.) or the record pointer is positioned on a record that falls outside the order’s scope or for condition)

■ The specified order is not custom built

■ The specified order does not exist

■ No order was specified and there is no controlling order

By default, this function 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.

Examples

■  This example creates a custom index, adds every fiftieth
   record to it, and deletes every hundredth record:

   USE Customer VIA "DBFCDX"
   // Create custom-built order that is initially empty
   INDEX ON LastName TO Last CUSTOM

   // Add every 50th record
   FOR n := 1 TO RecCount() STEP 50
      GOTO n
      ordKeyAdd()
   NEXT

   // Remove every 100th record
   FOR n := 1 TO RecCount() STEP 100
      GOTO n
      ordKeyDel()
   NEXT

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordKeyGoto()Harbour implementation


⌃ | ☰

Move to a record specified by its logical record number in the controlling order

Syntax

ordKeyGoto(<nKeyNo>) → lSuccess

Arguments

nKeyNo is the logical record number. If the value specified does not satisfy the scope or for condition for the order, the record pointer is positioned at the end of file.

Returns

ordKeyGoto() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

ordKeyGoto() is the complement to ordKeyNo(). ordKeyNo() returns the logical record number (i.e., its position in the controlling order) of the current record, and ordKeyGoto() moves the record pointer to the specified logical record.

Tip: This function can be useful when displaying scroll bars. If the user clicks on a certain position on the scroll bar, you can move to the corresponding record by calling ordKeyGoto().

By default, this function 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.

Examples

■  This example shows the difference between physical and logical
   record number:

   USE Customer
   SET INDEX TO First   // Make records in first name
                        // order
   ordKeyGoto(100)      // Go to the 100th logical record
   ? RecNo()            // Returns the physical record
                        // number
   ? ordKeyNo()         // Returns 100, the logical
                        // record no

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordKeyNo()Harbour implementation


⌃ | ☰

Get the logical record number of the current record

Syntax

ordKeyNo([<cOrder> | <nPosition>],
   [<cIndexFile>]) → nKeyNo

Arguments

cOrder | nPosition is the name of the order or a number representing its position in the order list. Using the order name is the preferred method since the position may be difficult to determine using multiple-order index files. If omitted or NIL, the controlling order is assumed.

Specifying an invalid order will raise a runtime error.

cIndexFile is the name of an index file, including an optional drive and directory (no extension should be specified). Use this argument with cOrder to remove ambiguity when there are two or more orders with the same name in different index files.

If cIndexFile is not open by the current process, a runtime error is raised.

Returns

ordKeyNo() returns the relative position of the current record in the specified order as a numeric value. ordKeyNo() respects the scope and for condition of the order by returning zero if the record pointer is positioned on an invalid record or if Eof() is true (.T.).

Description

ordKeyNo() returns the logical record number of a key in an order. This is in contrast to the physical record number (returned using the RecNo() function), which is the relative position of the record in the physical database file.

Tip: This function can be useful for displaying scroll bars and messages, such as «Record 9 of 123,» when viewing records in a browser.

By default, this function 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.

Examples

■  This example shows the difference between physical and logical
   record number:

   USE Customer            // Assuming 1000 records
   SET INDEX TO First      // Make records in first order


   GO TOP                  // Position the data pointer at
                           // the first record

   ? ordKeyNo()            // Result: 1

   dbSkip(10)
   ? ordKeyNo()            // Result: 11
   ? RecNo()               // Result: Physical record number

   dbGoBottom()
   ? ordKeyNo()            // Result: 1000
   ? RecNo()               // Result: Physical record number

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordKeyVal()Harbour implementation


⌃ | ☰

Get the key value of the current record from the controlling order

Syntax

Returns

ordKeyVal() returns the current record’s key value. The data type of the return value is the same as that of the key expression used to create the order. Use ValType() to determine the data type.

ordKeyVal() returns NIL if:

■ There is no controlling order

■ The record pointer is at the end of file (Eof() returns true

(.T.))

■ There is no key defined for this record (for example, you have

positioned the record pointer to a record that does not meet the order’s for condition or that lies outside of its specified scope)

Description

The key value is retrieved from the controlling order, not the database file. This makes the retrieval faster because no time is spent reading in the actual record.

Tip: ordKeyVal() is fast, but if you are going to use the value more than once, it is faster to store the result in a local variable. Then use the local variable rather than calling ordKeyVal() repeatedly for the same record.

By default, this function 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.

Examples

■  This example displays the values for all keys in an order
   without ever reading the individual records into memory:

   FUNCTION DISPLAYKEYS()
      LOCAL cKey, cFirst, cLast

      USE Customer
      // Assuming both LastName and FirstName are
      // 20 characters
      INDEX ON LastName + FirstName TO LastFir

      DO WHILE !Customer->Eof()
         cKey := Customer->ordKeyVal()          // Get key
                                                // value
         cLast := Left(cKey, 20)                // Get last
                                                // name
         cFirst := Right(cKey, 20)              // Get first
                                                // name
         ? cLast, cFirst
         Customer->dbSkip()
      ENDDO

      CLOSE

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ordListAdd()Harbour implementation


⌃ | ☰

Add orders to the order list

Syntax

ordListAdd(<cOrderBagName> [, <cOrderName>]) → NIL

Arguments

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.

cOrderName the name of the specific order from the order bag to be added to the order list of the current work area. If you do not specify cOrderName, all orders in the order bag are added to the order list of the current work area.

Returns

ordListAdd() always returns NIL.

Description

ordListAdd() is an order management function that adds the contents of an order bag, or a single order in an order bag, to the order list. This function lets you extend the order list without issuing a SET INDEX command that, first, clears all the active orders from the order list.

Any orders already associated with the work area continue to be active. If the newly opened order bag contains the only order associated with the work area, it becomes the controlling order; otherwise, the controlling order remains unchanged.

After the new orders are opened, the work area is positioned to the first logical record in the controlling order.

ordListAdd() is similar to the SET INDEX command or the INDEX clause of the USE command, except that it does not clear the order list prior to adding the new order(s).

ordListAdd() supersedes the dbSetIndex() function.

The active RDD determines the order capacity of an order bag. The default DBFNTX and the DBFNDX drivers only support single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX driver). 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 first order.

Examples

■  In this example Customer.cdx contains three orders, CuAcct,
   CuName, and CuZip.  ordListAdd() opens Customer.cdx but only uses the
   order named CuAcct:

   USE Customer VIA "DBFCDX" NEW
   ordListAdd("Customer", "CuAcct")

Platforms

Available on MS-DOS

See also

INDEX, SET INDEX, USE

ordListClear()Harbour implementation


⌃ | ☰

Clear the current order list

Syntax

Returns

ordListClear() always returns NIL.

Description

ordListClear() is an order management function that removes all orders from the order list for the current or aliased work area. When you are done, the order list is empty.

This function supersedes the function dbClearIndex().

Examples

USE Sales NEW
SET INDEX TO SaRegion, SaRep, SaCode
.
. <statements>
.
ordListClear()      // Closes all the current indexes

Platforms

Available on MS-DOS

See also

ordListRebuild()Harbour implementation


⌃ | ☰

Rebuild all orders in the order list of the current work area

Syntax

Returns

ordListRebuild() always returns NIL.

Description

ordListRebuild() is an order management function that rebuilds all the orders in the current or aliased order list.

To only rebuild a single order use the function ordCreate().

Unlike ordCreate(), this function rebuilds all orders in the order list. It is equivalent to REINDEX.

Examples

USE Customer NEW
SET INDEX TO CuAcct, CuName, CuZip
ordListRebuild()     // Causes CuAcct, CuName, CuZip to
                     // be rebuilt

Platforms

Available on MS-DOS

See also

ordName()Harbour implementation


⌃ | ☰

Return the name of an order in the order list

Syntax

ordName(<nOrder>[,<cOrderBagName>]) → cOrderName

Arguments

nOrder is an integer that identifies the position in the order list of the target order whose database name is sought.

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of xcOrderBagName, CA-Clipper uses the default extension of the current RDD.

Returns

ordName() returns the name of the specified order in the current order list or the specified order bag if opened in the current order list.

Description

ordName() is an order management function that returns the name of the specified order in the current order list.

If cOrderBagName is an order bag that has been emptied into the current order list, only those orders in the order list that correspond to cOrderBagName order bag are searched.

The active RDD determines the order capacity of an order bag. The default DBFNTX and the DBFNDX drivers only support single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBPX drivers).

Note: ordName(0) works as ordName(IndexOrd()).

Examples

■  This example retrieves the name of an order using its position
   in the order list:

   USE Customer NEW
   SET INDEX TO CuAcct, CuName, CuZip
   ordName(2)                     // Returns: CuName

■  This example retrieves the name of an order given its position
   within a specific order bag in the order list:

   USE Customer NEW
   SET INDEX TO Temp, Customer
   // Assume Customer contains CuAcct, CuName, CuZip
   ordName(2, "Customer")      // Returns: CuName

Platforms

Available on MS-DOS

See also

ordNumber()Harbour implementation


⌃ | ☰

Return the position of an order in the current order list

Syntax

ordNumber(<cOrderName>[, <cOrderBagName>]) → nOrderNo

Arguments

cOrderName the name of the specific order whose position in the order list is sought.

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.

Returns

ordNumber() returns an integer that represents the position of the specified order in the order list.

Description

ordNumber() is an order management function that lets you determine the position in the current order list of the specified order. ordNumber() searches the order list in the current work area and returns the position of the first order that matches cOrderName. If cOrderBagName is the name of an order bag newly emptied into the current order list, only those orders in the order list that have been emptied from cOrderBagName are searched.

If cOrderName is not found, ordNumber() raises a recoverable runtime error.

The active RDD determines the order capacity of an order bag. The default DBFNTX driver only supports single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBPX drivers).

Examples

USE Customer VIA "DBFNTX" NEW
SET INDEX TO CuAcct, CuName, CuZip
ordNumber("CuName")            // Returns: 2

Platforms

Available on MS-DOS

ordScope()Harbour implementation


⌃ | ☰

Set or clear the boundaries for scoping key values in the controlling order

Syntax

ordScope(<nScope>,   [<expNewValue>]) → uCurrentValue

Arguments

nScope is a number specifying the top (TOPSCOPE) or bottom (BOTTOMSCOPE) boundary.

Note: To use the TOPSCOPE and BOTTOMSCOPE constants, you must include (#include) the ord.ch header file in your application.

expNewValue is the top or bottom range of key values that will be included in the controlling order’s current scope. expNewValue can be an expression that matches the data type of the key expression in the controlling order or a code block that returns the correct data type.

Omitting expNewValue or specifying it as NIL has the special effect of resetting the specified scope to its original default. The default top range is the first logical record in the controlling order, and the default bottom range is the last logical record.

Returns

If expNewValue is not specified, ordScope() returns and clears the current setting. If expNewValue is specified, the function sets it and the previous setting is returned.

Description

The range of values specified using ordScope() is inclusive. In other words, the keys included in the scope will be greater than or equal to the top boundary and less than or equal to the bottom boundary.

Note: To return current settings without changing them, call the dbOrderInfo() function using the DBOI_SCOPETOP and DBOI_SCOPEBOTTOM constants.

Examples

■  This example illustrates using ordScope() to set various
   scoping limitations on an order:

   USE Friends
   SET INDEX TO Age

   // Make 25 the lowest age in range
   ordScope(TOPSCOPE, 25)

   // Make 30 the highest age in range
   ordScope(BOTTOMSCOPE, 30)
   LIST Age                         // Shows records with
                                    // 25 <= Age <= 30

   // Change highest age to 35
   ordScope(BOTTOMSCOPE, 35)
   LIST Age                         // Shows records with
                                    // 25 <= Age <= 35

   // Reset top boundary
   ordScope(TOPSCOPE, NIL)
   LIST Age                         // Shows records with
                                    // Age <= 35


   // Reset bottom boundary
   ordScope(BOTTOMSCOPE, NIL)
   LIST Age                         // Shows all records

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is ord.ch.

See also

ordSetFocus()Harbour implementation


⌃ | ☰

Set focus to an order in an order list

Syntax

ordSetFocus([<cOrderName> | <nOrder>]
   [,<cOrderBagName>]) → cPrevOrderNameInFocus

Arguments

cOrderName is the name of the selected order, a logical ordering of a database. ordSetFocus() ignores any invalid values of cOrderName.

nOrder is a number representing the position in the order list of the selected order.

cOrderBagName is the name of a disk file containing one or more orders. You may specify cOrderBagName as the file name with or without the path name or appropriate extension. If you do not include the extension as part of cOrderBagName, CA-Clipper uses the default extension of the current RDD.

Returns

ordSetFocus() returns the order name of the previous controlling order.

Description

ordSetFocus() is an order management function that returns the order name of the previous controlling order and, optionally, sets the focus to an new order.

If you do not specify cOrderName or nOrder, the name of the currently controlling order is returned and the controlling order remains unchanged.

All orders in an order list are properly updated no matter what cOrderName is the controlling order. After a change of controlling orders, the record pointer still points to the same record.

The active RDD determines the order capacity of an order bag. The default DBFNTX driver only supports single-order bags, while other RDDs may support multiple-order bags (e.g., the DBFCDX and DBPX drivers).

Note: ordSetFocus() supersedes IndexOrd().

Examples

USE Customer VIA "DBFNTX" NEW
SET INDEX TO CuAcct, CuName, CuZip
? ordSetFocus("CuName")      // Displays: "CuAcct"
? ordSetFocus()              // Displays: "CuName"

Platforms

Available on MS-DOS

See also

ordSetRelation()Harbour implementation


⌃ | ☰

Relate a specified work area to the current work area

Syntax

ordSetRelation(<nArea> | <cAlias>,<bKey>, [<cKey>])
    → NIL

Arguments

nArea is the number of the child work area.

cAlias is the alias of the child work area.

bKey is a code block that expresses the relational expression in executable form.

cKey is an optional string value that expresses the relational expression in textual form. If cKey is supplied, it must be equivalent to bKey. If cKey is omitted, ordSetRelation() returns a null string («») for the relation.

Returns

ordSetRelation() always returns NIL.

Description

ordSetRelation() relates the work area specified by nArea or cAlias (the child work area) to the current work area (the parent work area). Any existing relations remain active.

Relating work areas synchronizes the child work area with the parent work area. This is achieved by automatically repositioning the child work area whenever the parent work area moves to a new record. If there is a controlling order in the child work area, moving the parent work area causes an automatic seek operation in the child work area; the seek key is based on the expression specified by bKey and/or cKey. If the child work area has no controlling order, moving the parent work area causes an automatic «go to» in the child work area; the record number for the «go to» is based on the expression specified by bKey and/or cKey.

ordSetRelation() is identical to dbSetRelation() (and the SET RELATION command), but it also sets up a scope on the order in the child work area. This means that whenever you select the child work area, only the records related to the current parent record will be visible. This allows straightforward handling of one-to-many relationships. Refer to dbSetRelation() for more information.

Examples

■  This example displays each invoice with its related line
   items:

   USE LineTtem NEW VIA "DBFCDX"
   SET ORDER TO TAG InvNo

   USE Invoice NEW VIA "DBFCDX"

   // Set a selective relation from Invoice into
   // LineItem
   ordSetRelation("LineItem", {|| Invoice->InvNo}, ;
      "Invoice->InvNo")

   GO TOP
   DO WHILE !Eof()
      ? InvNo, InvDate            // Display invoice fields

      SELECT LineItem
      // Only records for current invoice # are visible
      LIST "   ", PartNo, Qty, Price
      SELECT Invoice               // On to next invoice
      SKIP
   ENDDO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

ordSkipUnique()Harbour implementation


⌃ | ☰

Move the record pointer to the next or previous unique key in the controlling order

Syntax

ordSkipUnique([<nDirection>]) → lSuccess

Arguments

nDirection specifies whether the function will skip to the next or previous key. Omitting this value or specifying it as 1 causes the record pointer to skip to the next unique key. Specifying a negative value makes it skip to the previous key.

Returns

ordSkipUnique() returns true (.T.) if successful; otherwise, it returns false (.F.).

Description

ordSkipUnique() allows you to make a non-unique order look like a unique order. Each time you use ordSkipUnique(), you are moved to the next (or previous) unique key exactly as if you were skipping through a unique order. This function eliminates the problems associated with maintaining a unique order, while providing you with fast access to unique keys.

By default, this function 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.

Examples

■  This example uses ordSkipUnique() to build an array of unique
   last names beginning with the letter "J":

   FUNCTION LASTUNIQUE()
      LOCAL aLast[0]
      SET INDEX TO Last          // Use the last name order
      ? ordIsUnique()            // Result: .F.
      SET SCOPE TO "J"           // Only look at the J's

      GO TOP
      DO WHILE !Eof()            // Add all the unique J
         AAdd(aLast, Last)       // last names to aLast
         ordSkipUnique()
      ENDDO

      SET SCOPE TO               // Clear the scope
      RETURN aLast               // Return array of
                                 // unique J names

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ORDCOND()


⌃ | ☰

Specify conditions for ordering

Syntax

ORDCOND([FOR <lCondition>]
   [ALL] [WHILE <;lCondition>]
   [EVAL <bBlock> [EVERY <nInterval>]]
   [RECORD <nRecord>] [NEXT <nNumber>]
   [REST] [DESCENDING])

Arguments

FOR lCondition specifies the conditional set of records on which to create the order. Only those records that meet the condition are included in the resulting order. lCondition is an expression that may be no longer than 250 characters under the DBFNTX and DBFNDX drivers. The maximum value for these expressions is determined by the RDD. The FOR condition is stored as part of the order bag and used when updating or recreating the index using the ordCreate() or ORDREBUILD() functions. Duplicate key values are not added to the order bag.

Drivers that do not support the FOR condition produce an «unsupported» error.

The FOR clause provides the only scoping that is maintained for all database changes. All other scope conditions create orders that do not reflect database updates.

ALL specifies all orders in the current or specified work area. ALL is the default scope for ORDCOND().

WHILE lCondition specifies another condition that must be met by each record as it is processed. As soon as the record is encountered that causes the condition to fail, the ordCreate() function terminates. If a WHILE clause is specified, the data is processed in the controlling order. The WHILE condition is transient (i.e., it is not stored in the file, not used for index updates, and not used for index updates and ORDREBUILD() purposes). The WHILE clause creates temporary orders, but these orders are not updated.

Drivers that do not support the WHILE condition produce an «unsupported» error.

Using the WHILE clause is more efficient and faster than using the FOR clause. The WHILE clause only processes data for which lCondition is true from the current position. The FOR clause, however, processes all data in the data source.

EVAL bBlock evaluates a code block every nInterval, where nInterval is a value specified by the EVERY clause. The default value is 1. This is useful in producing a status bar or odometer that monitors the indexing progress. The return value of bBlock must be a logical data type. If bBlock returns false (.F.), indexing halts.

EVERY nInterval is a clause containing a numeric expression that modifies how often bBlock is EVALuated. The EVERY option of the EVAL clause offers a performance enhancement by evaluating the condition for every nth record instead of evaluating every record ordered. The EVERY keyword is ignored if you specify no EVAL conditions.

RECORD nRecord specifies the processing of the specified record.

NEXT nNumber specifies the portion of the database to process. If you specify NEXT, the database is processed in the controlling order for the nNumber number of identities. The scope is transient (i.e., it is not stored in the order and not used for ORDREBUILDing purposes).

REST specifies the processing of all records from the current position of the record pointer to the end of file (EOF).

DESCENDING specifies that the keyed pairs be sorted in decreasing order of value. If you create a DESCENDING index, you will not need to use the Descend() function during a SEEK. DESCENDING is an attribute of the file, where it is stored and used for ORDREBUILDing purposes.

Description

ORDCOND() is designed to set up the conditions for creating a new order (using the ordCreate() function) or rebuilding an existing order (using the ORDREBUILD() function). Do not use the ORDCOND() function if you wish to create or rebuild an entire index file; it is only used for setting particular conditions for the order.

ordCreate() or ORDREBUILD() should be used immediately following the ORDCOND() function.

If the DESCENDING clause is not specified, the order is then assumed to be ascending.

The EVAL clause lets you specify a code block to be evaluated as each record is placed in the order. The EVERY clause lets you modify how often bBlock is called. Instead of evaluating each record as it is placed in the order, evaluation only occurs as every nInterval records are placed in the order. This can be used, for example, to create a gauge that displays how far the ordCreate() or ORDREBUILD() has progressed so far.

The FOR clause provides the only order scoping that is permanent and that can be maintained across the life of the application. The string passed as the FOR condition is stored within the order for later use in maintaining the order. Though only accessing part of the database, orders created using this clause exist as long as the database is active. The FOR clause lets you create maintainable scoped orders.

The WHILE, NEXT, REST, and RECORD clauses process data from the current position of the database cursor in the default or specified work area. If you specify these clauses, the order list remains open and the active order is used to organize the database while it is being created. These clauses let you create temporary (non-maintainable) orders. orders created using these clauses contain records in which lCondition is true(.T.) at the location of the record pointer.

Examples

■  The following example creates a conditional order based on a
   FOR clause.  This index contains only records whose field TransDate
   contains a date greater than or equal to January 1, 1992:

   USE Invoice NEW
   ORDCOND(FOR (Invoice->TransDate >= CTOD
   ("01/01/92")))
   ordCreate("InvDate" , , "Invoice->TransDate")

■  The following example creates an order that calls a routine,
   "MyMeter," during its creation:

   USE Invoice NEW
   ORDCOND(EVAL { | | MyMeter() } EVERY MTR_INCREMENT)
   ordCreate("Invoice" , , "Invoice->Customer")

Platforms

Available on MS-DOS

See also

OS()Harbour implementation


⌃ | ☰

Return the operating system name

Syntax

Returns

OS() returns the operating system name as a character string.

Description

OS() is an environment function that returns the name of the disk operating system under which the current workstation is operating. The name is returned in the form of the operating system name followed by the version number.

Examples

■  This example uses OS() to report the operating system under
   which the current workstation is running:

   ? OS()                  // Result: DOS 6.0

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

OutErr()Harbour implementation


⌃ | ☰

Write a list of values to the standard error device

Syntax

Arguments

exp list is a list of values to display and can consist of any combination of data types including memo.

Returns

OutErr() always returns NIL.

Description

OutErr() is identical to OutStd() except that it writes to the standard error device rather than the standard output device. Output sent to the standard error device bypasses the CA-Clipper console and output devices as well as any DOS redirection. It is typically used to log error messages in a manner that will not interfere with the standard screen or printer output.

Examples

■  This example displays an error message along with the date and
   time of occurrence to the screen:

   OutErr("File lock failure", Date(), Time())

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

OutStd()Harbour implementation


⌃ | ☰

Write a list of values to the standard output device

Syntax

Arguments

exp list is a list of values to display and can consist of any combination of data types including memo.

Returns

OutStd() always returns NIL.

Description

OutStd() is a simple output function similar to QOut() except that it writes to the STDOUT device (instead of to the CA-Clipper console output stream). Programs with very simple output requirements (i.e., that perform no full-screen input or output) can use this function to avoid loading the terminal output subsystems. The header file Simplio.ch redefines the ? and ?? commands to use the OutStd() function.

Since OutStd() sends its output to the standard output device, the output can be redirected using the DOS redirection symbols (>, >, |). This lets you redirect output from a CA-Clipper program to a file or pipe. Refer to your PC/MS-DOS documentation for more information about this operating system facility.

Examples

■  This example uses OutStd() to display a list of expressions:

   OutStd(Name, PadR(RTrim(City) + "," + ;
         State, 20), ZipCode)

■  This example redirects the output of a CA-Clipper program to a
   new file using the DOS redirection operator (>):

   C>MYPROG > FILE.TXT

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is Simplio.ch.

See also

Pad()→ PadR()Harbour implementation


⌃ | ☰

Pad character, date, and numeric values with a fill character

Syntax

PadL(<exp>, <nLength>, [<cFillChar>])
   → cPaddedString
PadC(<exp>, <nLength>, [<cFillChar>])
   → cPaddedString
PadR(<exp>, <nLength>, [<cFillChar>])
   → cPaddedString

Arguments

exp is a character, numeric, or date value to be padded with a fill character.

nLength is the length of the character string to be returned.

cFillChar is the character with which to pad exp. If not specified, the default is a space character.

Returns

PadC(), PadL(), and PadR() return the result of exp as a character string padded with cFillChar to a total length of nLength.

Description

PadC(), PadL(), and PadR() are character functions that pad character, date, and numeric values with a fill character to create a new character string of a specified length. PadC() centers exp within nLength adding fill characters to the left and right sides; PadL() adds fill characters on the left side; and PadR() adds fill characters on the right side. If the length of exp exceeds nLength, all of the Pad() functions truncate cPaddedString to nLength.

PadC(), PadL(), and PadR() display variable length strings within a fixed length area. They can be used, for instance, to ensure alignment with consecutive ?? commands. Another use is to display text to a fixed- width screen area assuring that previous text is completely overwritten.

PadC(), PadL(), and PadR() are the inverse of the AllTrim(), RTrim(), and LTrim() functions which trim leading and trailing space from character strings.

Examples

■  This example uses PadR() to format a record number display on
   a status line filling the allocated space:

   IF Eof()
      @ 23, 45 PadR("EOF/" + LTrim(Str(LastRec())), 20)
   ELSEIF Bof()
      @ 23, 45 PadR("BOF/" + LTrim(Str(LastRec())), 20)
   ELSE
      @ 23, 45 SAY PadR("Record " + LTrim(Str(RecNo()) ;
            + "/" + LTrim(Str(LastRec())), 20)
   ENDIF

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

PACKHarbour implementation⌃ | ☰

Remove deleted records from a database file

Syntax

Description

PACK is a database command that removes all records marked for deletion from the current database file, REINDEXes all active indexes in the current work area, and recovers all the physical space occupied by the deleted records. During its operation, PACK does not create any backup files, although the associated REINDEX operation may. After the PACK command terminates, the record pointer is reset to the first logical record in the current work area.

In a network environment, PACK requires that the current database be USEd EXCLUSIVEly. If this condition is not met when PACK is invoked, CA-Clipper generates a runtime error.

Note that PACKing large database files can be a time-consuming process and may not be feasible in a high-volume transaction system on a network. By modifying the system design, you can remove the necessity of physically removing records from the database file altogether. See the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Examples

■  The following example shows the result of a simple PACK:

   USE Sales NEW
   ? LastRec()                  // Result: 84
   //
   DELETE RECORD 4
   PACK
   ? LastRec()                  // Result: 83

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

PARAMETERS⌃ | ☰

Create private parameter variables

Syntax

PARAMETERS <idPrivate list>

Arguments

idPrivate list is one or more parameter variables separated by commas. The number of receiving variables does not have to match the number of arguments passed by the calling procedure or user-defined function.

Description

The PARAMETERS statement creates private variables to receive passed values or references. Receiving variables are referred to as parameters. The values or references actually passed by a procedure or user-defined function invocation are referred to as arguments.

When a PARAMETERS statement executes, all variables in the parameter list are created as private variables and all public or private variables with the same names are hidden until the current procedure or user-defined function terminates. A PARAMETERS statement is an executable statement and, therefore, can occur anywhere in a procedure or user-defined function, but must follow all compile-time variable declarations, such as FIELD, LOCAL, MEMVAR, and STATIC.

Parameters can also be declared as local variables if specified as a part of the PROCEDURE or FUNCTION declaration statement (see the example). Parameters specified in this way are referred to as formal parameters. Note that you cannot specify both formal parameters and a PARAMETERS statement with a procedure or user-defined function definition. Attempting to do this results in a fatal compiler error and an object file is not generated.

In CA-Clipper the number of arguments and parameters do not have to match. If you specify more arguments than parameters, the extra arguments are ignored. If you specify fewer arguments than parameters, the extra parameters are created with a NIL value. If you skip an argument, the corresponding parameter is initialized to NIL. The PCount() function returns the position of the last argument passed in the list of arguments. This is different from the number of parameters passed since it includes skipped parameters.

For more information on passing parameters, refer to the Functions and Procedures section in the «Basic Concepts» chapter of the Programming and Utilities Guide.

Examples

■  This user-defined function receives values passed into private
   parameters with a PARAMETERS statement:

   FUNCTION MyFunc
      PARAMETERS cOne, cTwo, cThree
      ? cOne, cTwo, cThree
      RETURN NIL

■  This example is similar, but receives values passed into local
   variables by declaring the parameter variables within the FUNCTION
   declaration:

   FUNCTION MyFunc( cOne, cTwo, cThree )
      ? cOne, cTwo, cThree
      RETURN NIL

Platforms

Available on MS-DOS

See also

PCol()Harbour implementation


⌃ | ☰

Return the current column position of the printhead

Syntax

Returns

PCol() returns an integer numeric value representing the last printed column position, plus one. The beginning column position is zero.

Description

PCol() is a printer function that reports the column position of the printhead after the last print operation. PCol() is updated only if either SET DEVICE TO PRINTER or SET PRINTER ON is in effect. PCol() is the same as Col() except that it relates to the printer rather than the screen. PCol() is updated in the following ways:

■ Application startup sets PCol() to zero

EJECT resets PCol() to zero

■ A print operation sets PCol() to the last column print

position plus one

SetPRC() sets PCol() to the specified column position

PCol(), used with PRow(), prints a value relative to the last value printed on the same line. This makes it easier to align columns when printing a columnar report. A value is printed in the next column by specifying its position as PCol() + column offset. Note that PCol() is effective for alignment only if the column values are fixed-width. To guarantee fixed-width column values, format the output using Transform(), the PICTURE clause of @...SAY, or any of the Pad() functions.

Notes

■ Printer control codes: Sending control codes to the printer

causes PCol() to become out of sync with the printhead position. Although control codes do not print, this discrepancy happens because CA-Clipper counts all characters sent to the printer regardless of how the printer treats them. To make the necessary adjustment, save the current PRow() and PCol() values, send the control codes, and then use SetPRC() to restore the original PRow() and PCol() values.

SET MARGIN: PCol() cannot reliably be used with SET MARGIN to

print with @...SAY. When printing with @...SAY, the current MARGIN value is always added to the specified column position before output is sent to the printer. This effectively adds the MARGIN value to PCol() for each invocation of @...SAY to the same print line.

Examples

■  In this example, PCol() creates a simple report that prints a
   listing of Customer names, addresses, and phone numbers:

   LOCAL nLine := 99, nPage := 1
   USE Customer INDEX CustName NEW
   SET DEVICE TO PRINTER
   DO WHILE !Eof()
      IF nLine > 55
         PageTop(nPage)
         nLine := 1
         nPage++
      ENDIF
      @ nLine, 10 SAY CustName
      @ nLine, PCol() + 2;
         SAY RTrim(City) + ", " + RTrim(State) + ZipCode;
               PICTURE Replicate("X", 35)
      @ nLine, PCol() + 2;
         SAY Phone;
               PICTURE "@R (999) 999-9999"
      nLine++
      SKIP
   ENDDO
   SET DEVICE TO SCREEN
   CLOSE

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

PCount()Harbour implementation


⌃ | ☰

Determine the position of the last actual parameter passed

Syntax

PCount() → nLastArgumentPos

Returns

PCount() returns, as an integer numeric value, the position of the last argument passed. If no arguments are passed, PCount() returns zero.

Description

PCount() reports the position of the last argument in the list of arguments passed when a procedure or user-defined function is invoked. This information is useful when determining whether arguments were left off the end of the argument list. Arguments skipped in the middle of the list are still included in the value returned.

To determine if a parameter did not receive a value, test it for NIL. Skipped parameters are uninitialized and, therefore, return NIL when accessed. Another method is to test parameters with the ValType() function. This can establish whether the argument was passed and enforce the correct type at the same time. If a parameter was not supplied, a default value can be assigned.

For more information on passing parameters, refer to the «Basic Concepts» chapter in the Programming and Utilities Guide.

Examples

■  This example is a user-defined function that opens a database
   file and uses PCount() to determine whether the calling procedure
   passed the name of the database file to be opened.  If the name was
   not passed, OpenFile() asks for the name:

   FUNCTION OpenFile( cFile )
      IF PCount() = 0
         ACCEPT "File to use: " TO cFile
      ENDIF
      USE (cFile)
      RETURN (NetErr())

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

PopUpMenu class⌃ | ☰

Create a pop-up menu

Description

Place items on the top bar menu or another pop-up menu.

Methods link

Popup() Create a new PopUp object


Popup([nTop], [nLeft], [nBottom], [nRight])

→ oPopUp

Arguments

nTop is a numeric value that indicates the top screen row of the pop-up menu. If omitted, PopUpMenu:top is set to an appropriate value relative to nBottom that allows as many items as possible to show. If nBottom is also omitted, PopUpMenu:top is set to center the menu vertically on the screen. The default value is determined the first time the pop-up menu is displayed.

When the pop-up menu is a child of another menu, its top variable will be automatically set by the parent menu regardless of whether nTop is omitted.

nLeft is a numeric value that indicates the left screen column of the pop-up menu. If omitted, PopUpMenu:left is set to an appropriate value relative to nRight that allows as many menu columns as possible to show. If nRight is also omitted, PopUpMenu:left is set to center the menu horizontally on the screen. The default value is determined the first time the pop-up menu is displayed.

When the pop-up menu is a child of another menu, its left variable will be automatically set by the parent menu regardless of whether nLeft is omitted.

nBottom is a numeric value that indicates the bottom screen row of the pop-up menu. If omitted, PopUpMenu:bottom is set to an appropriate value relative to nTop that allows as many items as possible to show. If nTop is also omitted, PopUpMenu:bottom is set to center the menu vertically on the screen. The default value is determined the first time the pop-up menu is displayed.

When the pop-up menu is a child of another menu, its bottom variable will be automatically set by the parent menu regardless of whether nBottom is omitted.

nRight is a numeric value that indicates the right screen column of the pop-up menu. If omitted, PopUpMenu:right is set to an appropriate value relative to nLeft that allows as many menu columns as possible to show. If nLeft is also omitted, PopUpMenu:right is set to center the menu horizontally on the screen. The default value is determined the first time the pop-up menu is displayed.

When the pop-up menu is a child of another menu, its right variable will be automatically set by the parent menu regardless of whether nRight is omitted.

Returns

Returns a PopUpMenu object when all of the required arguments are present; otherwise, Popup() returns NIL.

Exported Instance Variables


border An optional string used when drawing the menu’s border


border (Assignable)

Contains an optional string that is used when drawing a border around the pop-up menu. Its default value is B_SINGLE + SEPARATOR_SINGLE. The string must contain either zero or exactly eleven characters. The first eight characters represent the border of the pop-up menu and the final three characters represent the left, middle, and right characters for the menu item separators. The eight characters which represent the pop-up menu border begin at the upper-left corner and rotate clockwise as follows: upper-left corner, top, upper-right corner, right, bottom, bottom-left corner, and left.

bottom A numeric value indicating bottommost screen row


bottom (Assignable)

Contains a numeric value that indicates the bottommost screen row where the pop-up menu is displayed. If not specified when the PopUpMenu object is instantiated, PopUpMenu:bottom contains NIL until the first time it is displayed.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the PopUpMenu object. PopUpMenu:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a PopUpMenu object and retrieved later.

colorSpec Display attributes string


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the pop-up menu’s display() method. The string must contain six color specifiers.

PopUpMenu Color Attributes

       Position     Applies To                          Default Value from

       in colorSpec                                     System Color Setting

       1            The pop-up menu items that are not        Unselected

                    selected

       2            The selected pop-up menu item             Enhanced

       3            The accelerator key for unselected        Background

                    pop-up menu items

       4            The accelerator key for the selected      Enhanced

                    pop-up menu item

       5            Disabled pop-up menu items                Standard

       6            The pop-up menu’s border                  Border

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Workbench Properties window for that item.

current Numeric value indicating the selected item


current

Contains a numeric value that indicates which item is selected. PopUpMenu:current contains 0 when the pop-up menu is not open.

itemCount Numeric value indicating the number of items in the object


itemCount

Contains a numeric value that indicates the total number of items in the PopUpMenu object.

left Numeric value indicating the leftmost screen row


left (Assignable)

Contains a numeric value that indicates the leftmost screen row where the pop-up menu is displayed. If not specified when the PopUpMenu object is instantiated, PopUpMenu:left contains NIL until the first time it is displayed.

right Numeric value indicating the rightmost screen row


right (Assignable)

Contains a numeric value that indicates the rightmost screen row where the pop-up menu is displayed. If not specified when the PopUpMenu object is instantiated, PopUpMenu:right contains NIL until the first time it is displayed.

top Numeric value indicating the topmost screen row


top (Assignable)

Contains a numeric value that indicates the topmost screen row where the pop-up menu is displayed. If not specified when the PopUpMenu object is instantiated, PopUpMenu:top contains NIL until the first time it is displayed.

width Numeric value indicating width requirements


width

Contains a numeric value that indicates the width required to display all of the pop-up menu’s items in their entirety. This includes check marks and submenu indicators.

addItem() Appends new item to pop-up menu


oPopUp:addItem(oMenuItem) → self

oMenuItem is a MenuItem object.

addItem() is a method of the PopUpMenu class that is used for appending a new item to a pop-up menu.

close() Deactivates a pop-up menu


oPopUp:close([lCloseChild]) → self

lCloseChild is a logical value that indicates whether PopUpMenu:close() should deactivate the pop-up menu in its selected item, which in turn deactivates the pop-up menu in its selected item and so on. This is useful for nested menus where multiple levels of choices are presented. A value of true (.T.) indicates that child pop-up menu items should be closed. A value of false (.F.) indicates that child pop-up menu items should not be closed. The default value is true.

close() is a method of the PopUpMenu class that is used for deactivating a pop-up menu. When called, PopUpMenu:close() performs three operations. First, if the value of lCloseChild is not false (.F.) , close() determines if its selected menu item contains a PopUpMenu object. If so, it calls its selected menu item’s close() method. Second, close() restores the previous contents of the region of the screen that it occupies. Third, close() sets its selected item to 0.

Note: This message only has meaning when the pop-up menu is open.

delItem() Removes an item from a pop-up menu


oPopUp:delItem(nPosition) → self

nPosition is a numeric value that indicates the position in the pop-up menu of the item to be deleted.

delItem() is a method of the PopUpMenu class that is used for removing an item from a pop-up menu.

display() Shows a pop-up menu including its items on the screen


oPopUp:display() → self

display() is a method of the PopUpMenu class that is used for showing a pop-up menu including its items on the screen. display() uses the values of the following instance variables to correctly show the list in its current context, in addition to providing maximum flexibility in the manner a pop-up menu appears on the screen:

■ MenuItem:checked ■ MenuItem:enabled ■ MenuItem:isPopUp ■ PopUpMenu:bottom ■ PopUpMenu:colorSpec ■ PopUpMenu:current ■ PopUpMenu:itemCount ■ PopUpMenu:left ■ PopUpMenu:right ■ PopUpMenu:top ■ PopUpMenu:width

getAccel() Determines if a key press is interpreted as a user request


oPopUp:getAccel(nInkeyValue) → nPosition

nInkeyValue is a numeric value that indicates the inkey value to be checked.

Returns a numeric value that indicates the position in the pop-up menu of the first item whose accelerator key matches that which is specified by nInkeyValue. The accelerator key is defined using the & character in MenuItem:caption.

getAccel() is a method of the PopUpMenu class that is used for determining whether a key press should be interpreted as a user request to evoke the Data variable of a particular pop-up menu item.

getFirst() Determines position of first selectable item in a menu


oPopUp:getFirst() → nPosition

getFirst() is a method of the PopUpMenu class that is used for determining the position of the first selectable item in a pop-up menu. The term selectable is defined as a menu item that is enabled and whose caption is not a menu separator.

Returns a numeric value that indicates the position within the pop-up menu of the first selectable item. getFirst() returns 0 in the event that the pop-up menu does not contain a selectable item.

Note: getFirst() does not change the currently selected menu item. In order to change the currently selected pop-up menu item, you must call the PopUpMenu:select() method.

getItem() Access a MenuItem object after it has been added to a menu


oPopUp:getItem(nPosition) → oMenuItem

nPosition is a numeric value that indicates the position in the pop-up menu of the item that is being retrieved.

Returns the MenuItem object at the position in the pop-up menu specified by nPosition or NIL when nPosition is invalid.

getItem() is a method of the PopUpMenu class that is used for accessing a MenuItem object after it has been added to a pop-up menu.

getLast() Determines position of last selectable item in a menu


oPopUp:getLast() → nPosition

Returns a numeric value that indicates the position within the pop-up menu of the last selectable item. getLast() returns 0 in the event that the pop-up menu does not contain a selectable item.

getLast() is a method of the PopUpMenu class that is used for determining the position of the last selectable item in a pop-up menu. The term selectable is defined as a menu item that is enabled and whose caption is not a menu separator.

Note: getLast() does not change the currently selected menu item. In order to change the currently selected pop-up menu item, you must call the PopUpMenu:select() method.

getNext() Determines position of next selectable item in a menu


oPopUp:getNext() → nPosition

Returns a numeric value that indicates the position within the pop-up menu of the next selectable item. getNext() returns 0 in the event that the current item is the last selectable item or the pop-up menu does not contain a selectable item.

getNext() is a method of the PopUpMenu class that is used for determining the position of the next selectable item in a pop-up menu. getNext() searches for the next selectable item starting at the item immediately after the current item. The term selectable is defined as a menu item that is enabled and whose caption, is not a menu separator.

Note: getNext() does not change the currently selected menu item. In order to change the currently selected pop-up menu item, you must call the PopUpMenu:select() method.

getPrev() Determines position of previous selectable item in a menu


oPopUp:getPrev() → nPosition

Returns a numeric value that indicates the position within the pop-up menu of the previous selectable item. getPrev() returns 0 in the event that the current item is the first selectable item or the pop- up menu does not contain a selectable item.

getPrev() is a method of the PopUpMenu class that is used for determining the position of the previous selectable item in a pop-up menu. getPrev() searches for the previous selectable item starting at the item immediately before the current item. The term selectable is defined as a menu item that is enabled and whose caption is not a menu separator.

Note: getPrev() does not change the currently selected menu item. In order to change the currently selected pop-up menu item, you must call the PopUpMenu:select() method.

getShortct() Determines if a key press is interpreted as a user request


oPopUp:getShortct(nInkeyValue) → nPosition

nInkeyValue is a numeric value that indicates the inkey value to be checked.

Returns a numeric value that indicates the position in the pop-up menu of the first item whose shortcut key matches that which is specified by nInkeyValue. The shortcut key is defined using the MenuItem:shortcut instance variable.

getShortct() is a method of the PopUpMenu class that is used for determining whether a keystroke should be interpreted as a user request to select a particular pop-up menu item.

HitTest() Indicates position of mouse cursor relative to pop-up menu


oPopUp:hitTest(nMouseRow, nMouseCol)

→ nHitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the relationship of the mouse cursor with the pop-up menu.

Applicable Hit Test Return Values

       Value   Constant       Description

       > 0     Not Applicable The position in the pop-up menu of the item

                              whose region the mouse is within

       0       HTNOWHERE      The mouse cursor is not within the region of

                              the screen that the menu occupies

       -1      HTTOPLEFT      The mouse cursor is on the top left corner of

                              the pop-up menu’s border

       -2      HTTOP          The mouse cursor is on the pop-up menu’s top

                              border

       -3      HTTOPRIGHT     The mouse cursor is on the top right corner of

                              the pop-up menu’s border

       -4      HTRIGHT        The mouse cursor is on the pop-up menu’s right

                              border

       -5      HTBOTTOMRIGHT  The mouse cursor is on the bottom right corner

                              of the pop-up menu’s border

       -6      HTBOTTOM       The mouse cursor is on the pop-up menu’s bottom

                              border

       -7      HTBOTTOMLEFT   The mouse cursor is on the bottom left corner

                              of the pop-up menu’s border

       -8      HTLEFT         The mouse cursor is on the pop-up menu’s left

                              border

       -4098   HTSEPARATOR    The mouse is on a menu separator line

Button.ch contains manifest constants for the PopUpMenu:hitTest() return value.

HitTest() is a method of the PopUpMenu class that is used for determining if the mouse cursor is within the region of the screen that the pop-up menu occupies.

insItem() Inserts a new item to a pop-up menu


oPopUp:insItem(nPosition, oMenuItem) → self

nPosition is a numeric value that indicates the position at which the new menu item is inserted.

oMenuItem is a MenuItem object.

insItem() is a method of the PopUpMenu class that is used for inserting a new item within a pop-up menu.

isOpen() Determines if a pop-up menu is open


oPopUp:isOpen() → lIsOpen

Returns a logical value that indicates whether the pop-up menu is open or not. A value of true (.T.) indicates that the pop-up menu is open, a value of false (.F.) indicates that it is closed.

isOpen() is a method of the PopUpMenu class that is used for determining if a pop-up menu is open. A pop-up menu is considered open during the period after calling its open() method and before calling its close() method

open() Activates a pop-up menu


oPopUp:open() → self

open() is a method of the PopUpMenu class that is used for activating a pop-up menu. When called, open() performs two operations. First, open() saves the previous contents of the region of the screen that the pop-up menu occupies. Second, open() calls its pop-up menu’s display() method.

Note: This message only has meaning when the pop-up menu is closed.

Select() Changes the selected item


oPopUp:select(nPosition) → self

nPosition is a numeric value that indicates the position in the pop-up menu of the item to be selected.

Select() is a method of the PopUpMenu class that is used for changing the selected item. Its state is typically changed when one of the arrow keys is pressed or the mouse’s left button is pressed when its cursor is within the pop-up menu’s screen region.

setItem() Replaces a MenuItem object after it has been added to a menu


oPopUp:setItem(nPosition, oMenuItem) → self

nPosition is a numeric value that indicates the position in the pop-up menu of the item that is being retrieved.

oMenuItem is the MenuItem object that replaces the one in the pop- up menu specified by nPosition.

setItem() is a method of the PopUpMenu class that is used for replacing a MenuItem object after it has been added to a pop-up menu. After the setItem() method is called, the display()method needs to be called in order to refresh the menu. It is not allowed to call the display() method for the currently opened pop-up menu in the code block of the menu items. Otherwise, there are screen refresh problems especially if the code block has also increased the number of items in the pop-up menu.

Examples

See the Menu.prg sample file in the CLIP53SOURCESAMPLE directory.
This example demonstrates combining TopBarMenu, PopUpMenu, and MenuItem
objects to create a menu with a number of available choices.  See
"Introduction to the Menu System" in the Programming and Utilities Guide
for more information about using this class.

Platforms

Available on MS-DOS

See also

ProcLine()Harbour implementation


⌃ | ☰

Return the source line number of the current or previous activation

Syntax

ProcLine([<nActivation>]) → nSourceLine

Arguments

nActivation is a numeric value that specifies which activation to query. Zero refers to the current activation, one refers to the previous activation, etc. If not specified, the default value is zero.

Returns

ProcLine() returns the line number of the last line executed in a currently executing procedure, function, or code block as an integer numeric value. If the /L compiler option suppresses line number information, ProcLine() always returns zero.

Description

ProcLine() queries the CA-Clipper activation stack to determine the last line executed in a currently executing procedure, user-defined function, or code block. The activation stack is an internal structure that maintains a record of each procedure, function, or code block invocation. A line number is relative to the beginning of the original source file. A line includes a comment, blank line, preprocessor directive, and a continued line. A multistatement line is counted as a single line.

For the current activation, ProcLine() returns the number of the current line. For a previous activation, ProcLine() returns the number of the line that invoked the procedure or a user-defined function in which ProcLine() is invoked.

If the activation being queried is a code block evaluation, ProcLine() returns the line number of the procedure in which the code block was originally defined.

ProcLine() is used with ProcName() to report debugging information.

Examples

■  In this example, ProcLine() returns the line number for the
   current activation, followed by the line number of the previous
   activation:

   // First line of source file
   MyFunction()
      RETURN

   FUNCTION MyFunction
      ? ProcLine()      // Result: 6 (current activation)
      ? ProcLine(1)      // Result: 2 (previous activation)
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ProcName()Harbour implementation


⌃ | ☰

Return the name of the current or previous procedure or user-defined function

Syntax

ProcName([<nActivation>]) → cProcedureName

Arguments

nActivation specifies which activation to query. A value of zero refers to the current activation, a value of one refers to the previous activation, etc. If unspecified, the default value is zero.

Returns

ProcName() returns the name of a currently executing procedure, function, or code block, as a character string.

Description

ProcName() queries the CA-Clipper activation stack to determine the name of a currently executing procedure, user-defined function, or code block. The activation stack is an internal structure that maintains a record of each procedure, function, or code block invocation.

For the current activation, ProcName() returns the name of the current procedure or user-defined function. For a previous activation, ProcName() returns the name of the procedure or user-defined function that invoked the current procedure.

If the activation being queried is a code block evaluation, ProcName() returns the name of the procedure or user-defined function that defined the code block, preceded by «b». If the activation being queried is a memvar, ProcName() returns the name preceded by «M->».

ProcName() is used with ProcLine() to report debugging information.

Examples

■  This example is a user-defined function you can call during a
   debugging phase of program development in order to display the
   activation stack with line numbers:

   FUNCTION ListStack( cMessage )
      LOCAL nActivation := 1
      ? cMessage
      DO WHILE !(ProcName(nActivation) == "")
         ? "Called from:", ProcName(nActivation),;
            "(" + LTrim(Str(ProcLine(nActivation))) + ")"
         nActivation++
      ENDDO
      QUIT
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

PRIVATE⌃ | ☰

Create and initialize private memory variables and arrays

Syntax

PRIVATE <identifier> [[:= <initializer>], ... ]

Arguments

identifier is the name of a private variable or array to create. If the identifier is followed by square brackets ([ ]), an array is created and assigned to the identifier. When the identifier specification indicates an array, the syntax for specifying the number of elements for each dimension can be array[nElements, nElements2,…] or array[nElements][nElements2]… The maximum number of elements per dimension is 4096. The maximum number of dimensions is limited only by available memory.

initializer is the optional assignment of a value to a new private variable. An array cannot be given values with an initializer. An initializer for a private variable consists of the inline assignment operator (:=) followed by any valid CA-Clipper expression including a literal array. If no explicit initializer is specified, the variable is initialized to NIL. In the case of an array, each element is initialized to NIL.

You can create and, optionally, initialize a list of variables and arrays with one PRIVATE statement if the definitions are separated by commas.

Description

The PRIVATE statement creates variables and arrays visible within the current and invoked procedures or user-defined functions. This class of variable is said to have dynamic scope. Private variables exist for the duration of the active procedure or until explicitly released with CLEAR ALL, CLEAR MEMORY, or RELEASE. When a private variable or array is created, existing and visible private and public variables of the same name are hidden until the current procedure or user-defined function terminates.

Attempting to specify a PRIVATE variable that conflicts with a previous FIELD, LOCAL, or STATIC declaration of the same name results in a fatal compiler error. This is true regardless of the scope of the declaration.

PRIVATE statements are executable statements and, therefore, must be specified within the body of a procedure or user-defined function and must follow all variable declarations, such as FIELD, LOCAL, MEMVAR, and STATIC.

In addition to the PRIVATE statement, private variables are also created in two other ways:

■ Assignment to a variable that does not exist or is not visible

will create a private variable

■ Parameters received using the PARAMETERS statement are created

as private variables with the same lifetime and visibility

No more than 2048 private and public variables and arrays can simultaneously exist in a single program.

For more information on variable declarations and scoping, refer to the Variables section in the «Basic Concepts» chapter of the Programming and Utilities Guide.

Notes

■ Compatibility: The ALL, LIKE, and EXCEPT clauses of the

PRIVATE statement supported by other dBASE dialects are not supported by CA-Clipper.

Examples

■  This example creates two PRIVATE arrays and three other
   PRIVATE variables:

   PRIVATE aArray1[10], aArray2[20], var1, var2, var3

■  This example creates a multidimensional private array using
   each element addressing convention:

   PRIVATE aArray[10][10][10], aArray2[10, 10, 10]

■  This example uses PRIVATE statements to create and initialize
   arrays and variables:

   PRIVATE aArray := { 1, 2, 3, 4 }, ;
         aArray2 := Array(12, 24)
   PRIVATE cChar := Space(10), cColor := SetColor()

Platforms

Available on MS-DOS

See also

PRow()Harbour implementation


⌃ | ☰

Return the current row position of the printhead

Syntax

Returns

PRow() returns an integer numeric value that represents the number of the current line sent to the printer. The beginning row position is zero.

Description

PRow() is a printer function that reports the row position of the printhead after the last print operation. PRow() is updated only if either SET DEVICE TO PRINTER or SET PRINTER ON is in effect. PRow() is like Row() except that it relates to the printer rather than the screen. PRow() is updated in the following ways:

■ Application startup sets PRow() to zero

EJECT resets PRow() to zero

■ A print operation sets PRow() to the last row print position

SetPRC() sets PRow() to the specified row position

PRow() used with PCol() prints a value to a new row relative to the last row printed. If the printhead is positioned to a new row with a control code, a line feed (Chr(10)), or form feed (Chr(12)), PRow() is not updated and, therefore, will not return the expected value. To prevent this discrepancy, reset PRow() to the correct value with SetPRC() after sending any of these characters to the printer.

Examples

■  This example uses PRow() and SetPRC() to create a simple one-
   across label program that prints with @...SAY instead of ?:

   USE Customer INDEX CustName NEW
   SET DEVICE TO PRINTER
   SetPRC(2, 0)
   DO WHILE !Eof()
      @ PRow(), 3 SAY CustName
      @ PRow() + 1, 3 SAY RTrim(City) + ",;
             " + RTrim(State) + ZipCode
      @ PRow() + 1, 3 SAY Phone PICTURE "@R ;
            (999) 999-9999"
      SetPRC(2, 0)
      SKIP
   ENDDO
   SET DEVICE TO SCREEN
   CLOSE

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

PROCEDURE⌃ | ☰

Declare a procedure name and formal parameters

Syntax

[STATIC] PROCEDURE <idProcedure> [(<idParam list>)]
   [FIELD <idField list> [IN <idAlias>]
   [LOCAL <identifier> [[:= <initializer>], ... ]]
   [MEMVAR <identifier list>]
   [STATIC <identifier> [[:= <initializer>], ... ]]
   .
   . <executable statements>
   .
   [RETURN]

Arguments

idProcedure is the name of the procedure to be declared. Procedure names can be any length, but only the first 10 characters are significant. Names can contain any combination of characters, numbers, or underscores, but leading underscores are reserved.

idParam list is the declaration of one or more parameter variables. Variables specified in this list are declared local.

STATIC PROCEDURE declares a procedure that can be called only by procedures and user-defined functions declared in the same program (.prg) file.

FIELD declares a list of identifiers, idField list, to use as field names whenever encountered. If the IN clause is specified, referring to the declared name, idAlias is a reference to the appropriate work area of the specified database.

LOCAL declares and optionally initializes a list of variables or arrays whose visibility and lifetime is the current procedure.

identifier, identifier list is a label or labels used as variable or array names. If the identifier is followed by square brackets ([ ]), it is created as an array. If the identifier is an array, the syntax for specifying the number of elements for each dimension can be array[nElements, nElements2,…] or array[nElements][nElements2]… The maximum number of elements per dimension is 4096. The maximum number of dimensions per array is limited only by available memory.

initializer is the value to which an optional inline assignment sets the identifier variable—essentially, the assignment operator, (:=) —followed by any valid CA-Clipper expression, including a literal array. If no initializer is specified, variables are initialized to NIL. In the case of arrays, all element are initialized to NIL.

MEMVAR declares a list of identifiers, identifier list, to use as private or public memory variables or arrays whenever encountered.

STATIC declares and, optionally, initializes a list of variables or arrays whose visibility is the current procedure and whose lifetime is the duration of the program.

RETURN passes control back to the calling procedure or user-defined function. If a RETURN is not specified, control passes back to the calling routine when the procedure definitions ends. In all cases, the compiler terminates the procedure definition when it encounters another PROCEDURE statement, FUNCTION statement, or end of file character.

Description

The PROCEDURE statement declares a procedure and an optional list of local variables to receive parameters passed from a calling routine. A procedure is a subprogram comprised of a set of declarations and statements executed whenever you refer to idProcedure, followed by an open and close parentheses pair or with the DO statement. A procedure definition begins with a PROCEDURE statement and ends with the next PROCEDURE statement, FUNCTION statement, or end of file.

Procedures that encapsulate computational blocks of code provide readability and modularity, isolate change, and help manage complexity.

A procedure in CA-Clipper is the same as a user-defined function, with the exception that it always returns NIL. Each procedure must begin with a PROCEDURE statement and may, optionally, contain a RETURN statement to return control to the calling procedure or user-defined function. A RETURN statement, however, is not required. Procedure declarations cannot be nested within other procedure definitions.

The visibility of procedure names falls into two classes. Procedures that are visible anywhere in a program are referred to as public procedures and declared with a PROCEDURE statement. Procedures that are visible only within the current program (.prg) file are referred to as static procedures and declared with a STATIC PROCEDURE statement. Static procedures have filewide scope.

Static procedures are quite useful for a number of reasons. First, they limit visibility of a procedure name thereby restricting access to the procedure. Because of this, subsystems defined within a single program (.prg) file can provide an access protocol with a series of public procedures and conceal the implementation details of the subsystem within static procedures and functions. Second, since the static procedure references are resolved at compile time, they preempt references to public procedures and functions which are resolved at link time. This ensures that, within a program file, a reference to a static procedure executes that procedure if there is a name conflict with a public procedure or function.

For more information on procedures, variable declarations, and parameter passing, refer to the «Basic Concepts» chapter in the Programming and Utilities Guide.

Notes

■ Calling a procedure: There are two ways to call a procedure

in CA-Clipper. The first and preferred way is the function-calling convention. Here you call the procedure as you would a CA-Clipper function on a line by itself:

idProcedure([argument list])

The second and obsolete way is the command-calling convention using the DO...WITH command. The two methods of calling procedures differ only in the default method of passing parameters. The function- calling convention passes variables by value as a default, whereas the command-calling convention passes them by reference as a default.

A procedure can also be called as an aliased expression if it is prefaced with an alias and invoked using the function-calling convention, like this:

idAlias ->(idProcedure(argument list))

When called as an aliased expression, the work area associated with idAlias is selected, the procedure is executed, and then the original work area is reselected. Like an expression or function, an aliased procedure can be specified on a line by itself.

A procedure in CA-Clipper may call itself recursively. This means you can call a procedure in the same procedure definition.

■ Parameters: Procedures like user-defined functions can

receive parameters passed from a calling procedure, user-defined function, or the DOS command line. A parameter is a place for a value or reference. In CA-Clipper there are two ways to receive parameters: a list of local variable names can be declared as a part of the PROCEDURE declaration (referred to as formal parameters), or a list of private variables can be specified in a separate PARAMETERS statement. Note that you cannot mix a declaration of formal parameters with a PARAMETERS statement. Attempting this will cause a fatal compiler error.

Procedures receive parameters in the order passed. In CA-Clipper the number of parameters need not match the number of arguments passed. Arguments can be skipped or left off the end of the argument list. A parameter not receiving a value or reference is initialized to NIL. If arguments are specified, PCount() returns the position of the last argument passed.

Parameters specified in a procedure can receive arguments passed by value or by reference. The default method for expressions and variables depends on the calling convention. With the function-calling convention, the default passing method for expressions and variables is by value. This includes variables containing references to arrays and objects. With the command- calling convention, the default method for passing variables is by reference except for field variables, which are always passed by value. Whenever a field variable is passed, it must be specified enclosed in parentheses unless declared with the FIELD statement. Failure to do so will generate a runtime error.

Examples

■  This example shows a skeleton of a typical CA-Clipper
   procedure that uses lexical variables:

   PROCEDURE Skeleton( cName, cClassRoom, nBones, ;
                           nJoints )
      LOCAL nCrossBones, aOnHand := {"skull", ;
                                    "metacarpals"}
      STATIC nCounter := 0
      .
      . <executable statements>
      .
      RETURN

■  This example determines whether an argument was skipped by
   comparing the parameter to NIL:

   PROCEDURE MyProc( param1, param2, param3 )
      IF param2 != NIL
         param2 := "default value"
      ENDIF
      .
      . <statements>
      .
      RETURN

■  This example invokes the procedure, UpdateAmount(), as an
   aliased expression:

   USE Invoices NEW
   USE Customer NEW
   Invoices->(UpdateAmount(Amount + Amount * nInterest))

Platforms

Available on MS-DOS

See also

PushButton class⌃ | ☰

Create a push button

Description

Places a push button at the indicated position on the screen.

Methods link

PushButton() Create a new PushButton object


PushButton(nRow, nColumn, [cCaption])

→ oPushButton

Arguments

nRow is a numeric value that indicates the screen row of the push button.

nColumn is a numeric value that indicates the screen column of the push button.

cCaption is an optional character string that describes the push button on the screen. If omitted, the default is an empty string.

Returns

Returns a PushButton object when all of the required arguments are present; otherwise PushButton() returns NIL.

Exported Instance Variables


bitmap The bitmap file to display on the button


bitmap (Assignable)

Contains a character string that indicates a bitmap file to be displayed on the button. Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .BML extension.

CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed. This instance variable only affects applications running in graphic mode and is ignored in text mode.

bmpXOff Indicates the horizontal offset where the bitmap is displayed


bmpXOff (Assignable)

Contains a numeric value that indicates the offset where the bitmap is displayed. This instance variable represents the number of pixels in the x direction (horizontally) from the left edge of the button where the bitmap will be displayed. If this instance variable is not supplied, the bitmap will be placed at the left edge of the button. This instance variable only affects applications running in graphic mode and is ignored in text mode.

bmpYOff Indicates the vertical offset where the bitmap is displayed


bmpYOff (Assignable)

Contains a numeric value that indicates the offset where the bitmap is displayed. This instance variable represents the number of pixels in the y direction (vertically) from the top edge of the button where the bitmap will be displayed. If this instance variable is not supplied, the bitmap will be placed at the top edge of the button. This instance variable only affects applications running in graphic mode and is ignored in text mode.

buffer Logical value indicating the push button has been pushed


buffer

Contains a logical value indicating that the push button has been pushed. A value of true (.T.) indicates that the push button has been pushed; otherwise, a value of false (.F.) indicates that it has not.

caption Character string describing the push button on the screen


caption (Assignable)

Contains a character string that describes the push button on the screen.

When present, the & character specifies that the character immediately following it in the caption is the push button’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to a push button. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.

capXOff Indicates the horizontal offset where caption is displayed


capXOff (Assignable)

Contains a numeric value that indicates the offset where the caption is displayed. This instance variable represents the number of pixels in the x direction (horizontally) from the left edge of the button where the caption will be displayed. If this instance variable is not supplied, the caption will be centered horizontally. This instance variable only affects applications running in graphic mode and is ignored in text mode.

capYOff Indicates the vertical offset where caption is displayed


capYOff (Assignable)

Contains a numeric value that indicates the offset where the caption is displayed. This instance variable represents the number of pixels in the y direction (vertically) from the top edge of the button where the caption will be displayed. If this instance variable is not supplied, the caption will be centered vertically. This instance variable only affects applications running in graphic mode and is ignored in text mode.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is not used by the PushButton object. PushButton:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a PushButton object and retrieved later.

col Indicates screen column where push button is displayed


col (Assignable)

Contains a numeric value that indicates the screen column where the push button is displayed.

colorSpec Indicates colors used by the push button’s display() method


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the push button’s display() method. The string must contain four color specifiers.

Note: The background colors of the PushButton Color Attributes are ignored in graphic mode.

PushButton Color Attributes

       Position        Applies To                       Default Value from

       in colorSpec                                     System Color Setting

       1               The push button when it does not     Unselected

                       have input focus

       2               The push button when it has input    Enhanced

                       focus and is not pressed

       3               The push button when it has input    Enhanced

                       focus and is pressed

       4               The push button caption’s            Background

                       accelerator key

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Workbench Properties window for that item.

fBlock Code block evaluated at each input focus change


fBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the PushButton object receives or loses input focus. The code block takes no implicit arguments. Use the PushButton:hasFocus variable to determine if the push button is receiving or losing input focus. A value of true (.T.) indicates that it is receiving input focus; otherwise, a value of false (.F.) indicates that it is losing input focus.

This code block is included in the PushButton class to provide a method of indicating when an input focus change event has occurred. The name «fBlock» refers to focus block.

hasFocus Logical value indicating the input focus


hasFocus

Contains a logical value that indicates whether the PushButton object has input focus. PushButton:hasFocus contains true (.T.) if it has input focus; otherwise, it contains false (.F.).

message Character string describing the push button


message (Assignable)

Contains a character string that describes the push button. It is displayed on the screen’s status bar line.

row Numeric value indicating row where push button is displayed


row (Assignable)

Contains a numeric value that indicates the screen row where the push button is displayed.

sBlock Code block evaluated at every state change


sBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the PushButton object’s state changes. The code block takes no implicit arguments. Use the PushButton:buffer variable to determine if the push button is pressed or released. A value of true (.T.) indicates that it is being pressed; otherwise a value of false (.F.) indicates that it is being released.

This code block is included in the PushButton class to provide a method of indicating when a state change event has occurred. The name «sBlock» refers to state block.

sizeX Size of the button in pixels on the X-coordinate


sizeX (Assignable)

Contains a numeric value that indicates the size of the button in pixels on the X-coordinate (horizontally). This instance variable only affects applications running in graphic mode and is ignored in text mode.

sizeY Size of the button in pixels on the Y-coordinate


sizeY (Assignable)

Contains a numeric value that indicates the size of the button in pixels on the Y-coordinate (vertically). This instance variable only affects applications running in graphic mode and is ignored in text mode.

style Indicates characters used by push button’s display() method


style (Assignable)

Contains a character string that indicates the delimiter characters that are used by the push button’s display() method. The string must contain either zero, two or eight characters. The default is two characters. The first is the left delimiter. Its default value is the less than () character. The second character is the right delimiter. Its default value is the greater than () character.

When the string is empty the button has no delimiters.

When the string length is two, the button has left and right delimiters and occupies one row on the screen. The first character is the left delimiter. The second character is the right delimiter.

When the string length is eight, the button is contained within a box that occupies three rows on the screen. A PushButton object may only be either one or three lines in height.

Standard Box Types

       Constant            Description

       B_SINGLE            Single-line box

       B_DOUBLE            Double-line box

       B_SINGLE_DOUBLE     Single-line top/bottom, double-line sides

       B_DOUBLE_SINGLE     Double-line top/bottom, single-line sides

Box.ch contains manifest constants for the PushButton:style value.

The default style for the PushButton class is «<>».

Note: The style instance variable is ignored in graphic mode.

typeOut Logical value false (.F.)


typeOut

Contains the logical value false (.F.). PushButton:typeOut never changes. It is not used by the PushButton object and is only provided for compatibility with the other GUI control classes.

display() Shows a push button on the screen


oPushButton:display() → self

display() is a method of the PushButton class that is used for showing a push button on the screen. display() uses the values of the following instance variables to correctly show the push button in its current context, in addition to providing maximum flexibility in the manner a push button appears on the screen: buffer, caption, col, colorSpec, hasFocus, row, and style.

HitTest() Indicates position of mouse cursor relative to push button


oPushButton:hitTest(nMouseRow, nMouseCol)

nHitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the relationship of the mouse cursor with the push button.

Applicable Hit Test Return Values

       Value   Constant       Description

       0       HTNOWHERE      The mouse cursor is not within the region of

                              the screen that the push button occupies

       -1      HTTOPLEFT      The mouse cursor is on the top left corner of

                              the push button’s border

       -2      HTTOP          The mouse cursor is on the push button’s top

                              border

       -3      HTTOPRIGHT     The mouse cursor is on the top right corner of

                              the push button’s border

       -4      HTRIGHT        The mouse cursor is on the push button’s right

                              border

       -5      HTBOTTOMRIGHT  The mouse cursor is on the bottom right corner

                              of the push button’s border

       -6      HTBOTTOM       The mouse cursor is on the push button’s

                              bottom border

       -7      HTBOTTOMLEFT   The mouse cursor is on the bottom left corner

                              of the push button’s border

       -8      HTLEFT         The mouse cursor is on the push button’s left

                              border

       -2049   HTCLIENT       The mouse cursor is on the push button

Button.ch contains manifest constants for the PushButton:hitTest() return value.

HitTest() is a method of the PushButton class that is used for determining if the mouse cursor is within the region of the screen that the push button occupies.

killFocus() Takes input focus away from the PushButton object


oPushButton:killFocus() → self

killFocus() is a method of the PushButton class that is used for taking input focus away from a PushButton object. Upon receiving this message, the PushButton object redisplays itself and, if present, evaluates the code block within its fBlock variable.

This message is meaningful only when the PushButton object has input focus.

Select() Activates a push button


oPushButton:select([nInkeyValue]) → self

nInkeyValue is a numeric value that indicates the key that triggered the push button’s activation. If passed, Select() waits for the key specified by nInkeyValue to be released before continuing.

Select() is a method of the PushButton class that is used for activating a push button. When activated, a push button performs several operations. First, Select() sets SELF:BUFFER to true (.T.). Then, it calls SELF:display() to show the button in its highlighted color. If nInkeyValue is passed, it waits for the key specified by nInkeyValue to be released. Then, if present, it evaluates its sBlock code block. Select() then calls SELF:display() to show the button in its selected color. A push button’s state is typically changed when the space bar or enter key is pressed or the mouse’s left button is pressed when its cursor is within the push button’s screen region.

This message is meaningful only when the PushButton object has input focus.

setFocus() Gives input focus to the PushButton object


oPushButton:setFocus() → self

setFocus() is a method of the PushButton class that is used for giving focus to a PushButton object. Upon receiving this message, the PushButton object redisplays itself and, if present, evaluates the code block within its fBlock variable.

This message is meaningful only when the PushButton object does not have input focus.

Examples

■  This example creates an object which is placed at row 2 and
   column 2 and has a caption of "Exit":

   oBtn:PushButton(2,2,"Exit")

Platforms

Available on MS-DOS

PUBLIC⌃ | ☰

Create and initialize public memory variables and arrays

Syntax

PUBLIC <identifier> [[:= <initializer>], ... ]

Arguments

identifier is the name of a public variable or array to create. If the identifier is followed by square brackets ([ ]), it is created as an array. If the identifier is an array, the syntax for specifying the number of elements for each dimension can be array[nElements, nElements2,…] or array[nElements][nElements2]…. The maximum number of elements per dimension is 4096. The maximum number of dimensions per array is limited only by available memory.

initializer is the optional assignment of a value to a new public variable. Array identifiers, however, cannot be given values with an initializer. An initializer for a public variable consists of the inline assignment operator (:=) followed by any valid CA-Clipper expression including a literal array. Except for arrays, if no initializer is specified, public variables are initialized to false (.F.). This is an exception to the general rule that uninitialized variables are NIL. With arrays, however, the initial value of each element is NIL.

A list of variables and arrays can be created and, optionally, initialized with one PUBLIC statement if each definition is separated by a comma.

Description

The PUBLIC statement creates variables and arrays visible to all procedures and user-defined functions in a program. Public variables exist for the duration of the program or until explicitly released with CLEAR ALL, CLEAR MEMORY, or RELEASE. Declaring private, local, or static variables or arrays with the same name as existing public variables temporarily hides those public variables until the overriding variables are released or are no longer visible. An attempt to create a public variable with the same name as an existing and visible private variable is simply ignored (see Notes below for an exception).

Attempting to specify a PUBLIC variable that conflicts with a previous FIELD, LOCAL, or STATIC declaration of the same name results in a fatal compiler error. This is true regardless of the scope of the declaration.

PUBLIC statements are executable statements and, therefore, must be specified within the body of a procedure or user-defined function definition. They also must follow all compile-time declarations, such as FIELD, LOCAL, MEMVAR, and STATIC.

The maximum number of public and private variables and arrays that can simultaneously exist in a single program is 2048.

For more information on variable declarations and scoping, refer to the Variables section in the «Basic Concepts» chapter of the Programming and Utilities Guide.

Notes

PUBLIC Clipper: To include CA-Clipper extensions in a program

and still allow the program to run under dBASE III PLUS, the special public variable, Clipper, is initialized to true (.T.) when created PUBLIC.

■ Public array name conflicts with existing private variables:

The statement, PUBLIC x[10], will not create the public array x if there is already a private or public variable x. It will, however, destroy the contents of the existing x, replacing it with a reference to a ten-element array.

Examples

■  This example creates two PUBLIC arrays and one PUBLIC
   variable:

   PUBLIC aArray1[10, 10], var2
   PUBLIC aArray2[20][10]

■  The following PUBLIC statements create variables and
   initialize them with values:

   PUBLIC cString := Space(10), cColor := SetColor()
   PUBLIC aArray := {1, 2, 3}, aArray2 := Array(12, 24)

Platforms

Available on MS-DOS

See also

QOut()Harbour implementation


⌃ | ☰

Display a list of expressions to the console

Syntax

QOut([<exp list>]) → NIL
QQOut([<exp list>]) → NIL

Arguments

exp list is a comma-separated list of expressions (of any data type other than array or block) to display to the console. If no argument is specified and QOut() is specified, a carriage return/line feed pair is displayed. If QQOut() is specified without arguments, nothing displays.

Returns

QOut() and QQOut() always return NIL.

Description

QOut() and QQOut() are console functions. These are the functional primitives that create the ? and ?? commands, respectively. Like the ? and ?? commands, they display the results of one or more expressions to the console. QOut() outputs carriage return and line feed characters before displaying the results of exp list. QQOut() displays the results of exp list at the current Row() and Col() position. When QOut() and QQOut() display to the console, Row() and Col() are updated. If SET PRINTER is ON, PRow() and PCol() are updated instead. If exp list is specified, both QOut() and QQOut() display a space between the results of each expression.

You can use QOut() and QQOut() for console display within an expression. This is particularly useful for blocks, iteration functions such as AEval() and dbEval(), and in a list of statements in the output pattern of a user-defined command definition.

Examples

■  This example uses QOut() with AEval() to list the contents of
   a literal array to the console:

   LOCAL aElements := { 1, 2, 3, 4, 5 }
   AEval(aElements, { |element| QOut(element) })

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

QUITHarbour implementation⌃ | ☰

Terminate program processing

Syntax

Description

QUIT and CANCEL both terminate program processing, close all open files, and return control to the operating system. Each of these commands can be used from anywhere in a program system. A RETURN executed at the highest level procedure or a BREAK, with no pending SEQUENCE, also QUITs the program.

Notes

■ Return code: When a CA-Clipper program terminates, the return

code is set to 1 if the process ends with a fatal error. If the process ends normally, the return code is set to zero or the last ErrorLevel() set in the program.

Examples

■  This example uses QUIT in a dialog box:

   IF DialogYesNo(10, 10, "Quit to DOS", "BG+/B,B/W", 2)
      QUIT
   ENDIF
   RETURN

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

rddList()Harbour implementation


⌃ | ☰

Return an array of the available Replaceable Database Drivers (RDDs)

Syntax

rddList([<nRDDType>]) → aRDDList

Arguments

nRDDType is an integer that represents the type of the RDD you wish to list. The constants RDT_FULL and RDT_TRANSFER represent the two types of RDDs currently available.

RDDType Summary

    Constant     Value     Meaning

    RDT_FULL       1       Full RDD implementation

    RDT_TRANSFER   2       Import/Export only driver

RDT_FULL identifies full-featured RDDs that have all the capabilities associated with an RDD.

RDT_TRANSFER identifies RDDs of limited capability. They can only transfer records between files. You cannot use these limited RDD drivers to open a file in a work area. The SDF and DELIM drivers are examples of this type of RDD. They are only used in the implementation of APPEND FROM and COPY TO with SDF or DELIMITED files.

Returns

rddList() returns a one-dimensional array of the RDD names registered with the application as nRDDType.

Description

rddList() is an RDD function that returns a one-dimensional array that lists the available RDDs.

If you do not supply nRDDType, all available RDDs regardless of type are returned.

Examples

■  In this example rddList() returns an array containing the
   character strings, "DBF", "SDF", "DELIM", "DBFCDX", and "DBFNTX":

   REQUEST DBFCDX

   .
   . < statements >
   .

   aRDDs := rddList()

         // Returns {"DBF", SDF", "DELIM", "DBFCDX", "DBFNTX" }

■  In this example, rddList() returns an array containing the
   character strings, "SDF" and "DELIM":

   #include "rddsys.ch"
   .
   . < statements >
   .
   aImpExp := rddList( RDT TRANSFER )

Platforms

Available on MS-DOS

File

Rddsys.ch.

See also

rddName()Harbour implementation


⌃ | ☰

Return the name of the RDD active in the current or specified work area

Syntax

Returns

Returns a character string, cRDDName, the registered name of the active RDD in the current or specified work area.

Description

rddName() is an RDD function that returns a character string for the name of the active RDD, cRDDName, in the current or specified work area.

You can specify a work area other than the currently active work area by aliasing the function.

Examples

USE Customer VIA "DBFNTX" NEW
USE Sales    VIA "DBFCDX" NEW

? rddName()                          // Returns: DBFCDX
? Customer->( rddName() )            // Returns: DBFNTX
? Sales->( rddName() )               // Returns: DBFCDX

Platforms

Available on MS-DOS

See also

rddSetDefault()Harbour implementation


⌃ | ☰

Set or return the default RDD for the application

Syntax

rddSetDefault([<cNewDefaultRDD>])
   → cPreviousDefaultRDD

Arguments

cNewDefaultRDD is a character string, the name of the RDD that is to be made the new default RDD in the application.

Returns

rddSetDefault() returns a character string, cPreviousDefaultRDD, the name of the previous default driver. The default driver is the driver that CA-Clipper uses if you do not explicitly specify an RDD with the VIA clause of the USE command.

Description

rddSetDefault() is an RDD function that sets or returns the name of the previous default RDD driver and, optionally, sets the current driver to the new RDD driver specified by cNewDefaultRDD. If cNewDefaultDriver is not specified, the current default driver name is returned and continues to be the current default driver.

This function replaces the dbSetDriver() function.

Examples

// If the default driver is not DBFNTX, make it the default

IF ( rddSetDefault() != "DBFNTX" )
   cOldRdd := rddSetDefault( "DBFNTX" )
ENDIF

Platforms

Available on MS-DOS

RadioButto class⌃ | ☰

Create a radio button

Description

Radio buttons are typically presented in related groups and provide mutually exclusive responses to a condition where only one choice is appropriate. For example, a group of radio buttons might allow you to sort public variables either by name or by address.

Only one radio button can be on—when a new button is pressed, the previously selected button is turned off.

Methods link

RadioButto() Create a new RadioButto object


RadioButto(nRow, nColumn, [cCaption])

→ oRadioButto

Arguments

nRow is a numeric value that indicates the screen row of the radio button.

nColumn is a numeric value that indicates the screen column of the radio button.

cCaption is an optional character string that contains a text string that describes the radio button on the screen. The default is an empty string.

Returns

Returns a RadioButto object when all of the required arguments are present; otherwise, RadioButto() returns NIL.

Exported Instance Variables


bitmaps An array of bitmap files to be displayed


bitmaps (Assignable)

Contains an array of exactly two elements. The first element of this array is the file name of the bitmap to be displayed when the radio button is selected. The second element of this array is the file name of the bitmap to be displayed when the radio button is not selected.

Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .BML extension.

CA-Clipper will search for the file name first and, if it is not found, search in the bitmap library second. If no file is found either on disk or in the library, no bitmap will be displayed.

If this instance variable is not used, and the application is running in graphic mode, the files RADIO_F.BMU and RADIO_E.BMU will be used for the selected bitmap and unselected bitmap, respectively.

This instance variable only affects applications running in graphic mode and is ignored in text mode.

buffer Logical value indicating whether a radio button is selected


buffer

Contains a logical value that indicates whether a radio button is selected or not. A value of true (.T.) indicates that it selected; otherwise, a value of false (.F.) indicates that it is not.

caption Character string describing the radio button on the screen


caption (Assignable)

Contains a character string that describes the radio button on the screen. When present, the & character specifies that the character immediately following it in the caption is the radio button’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one radio button to another. The user performs the selection by pressing an accelerator key. The case of an accelerator key is ignored.

capCol Indicates column where radio button’s caption is displayed


capCol (Assignable)

Contains a numeric value that indicates the screen column where the radio button’s caption is displayed.

capRow Indicates column where radio button’s caption is displayed


capRow (Assignable)

Contains a numeric value that indicates the screen row where the radio button’s caption is displayed.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the RadioButto object. RadioButto:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a RadioButto object and retrieved later.

col Indicates the column where the radio button is displayed


col (Assignable)

Contains a numeric value that indicates the screen column where the radio button is displayed.

colorSpec Indicates colors used by the radio button’s display() method


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the radio button’s display() method. The default is the system’s current unselected and enhanced colors. The string must contain seven color specifiers.

Note: In graphic mode, colorSpec positions 1 through 4 have no affect and are ignored.

RadioButto Color Attributes

       Position     Applies To                          Default Value from

       in colorSpec                                     System Color Setting

       1            A radio button when it is unselected    Unselected

                    and does not have input focus

       2            A radio button when it is selected      Unselected

                    and does not have input focus

       3            A radio button when it is unselected    Enhanced

                    and has input focus

       4            A radio button when it is selected and  Enhanced

                    has input focus

       5            A radio button’s caption                Standard

       6            A radio button caption’s accelerator    Standard

                    key when it does not have input focus

       7            A radio button caption’s accelerator    Background

                    key when it has input focus

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Workbench Properties window for that item.

fBlock Code block evaluated at each input focus change


fBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the RadioButto object receives or loses input focus. The code block takes no implicit arguments. Use the RadioButto:hasFocus instance variable to determine if the radio button is receiving or losing input focus. A value of true (.T.) indicates that it is receiving input focus; otherwise, a value of false (.F.) indicates that it is losing input focus.

This code block is included in the RadioButto class to provide a method of indicating when an input focus change event has occurred. The name «fBlock» refers to focus block.

hasFocus Logical value indicating the input focus


hasFocus

Contains a logical value that indicates whether the RadioButto object has input focus. RadioButto:hasFocus contains true (.T.) if it has input focus; otherwise, it contains false (.F.) .

row Indicates the row where the radio button is displayed


row (Assignable)

Contains a numeric value that indicates the screen row where the radio button is displayed.

sBlock Code block evaluated at every state change


sBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the RadioButto object’s state changes. The code block takes no implicit arguments. Use the RadioButto:buffer instance variable to determine whether the radio button is being selected or unselected. A value of true (.T.) indicates that it is being selected; otherwise, a value of false (.F.) indicates that it is being unselected.

This code block is included in the RadioButto class to provide a method of indicating when a state change event has occurred. The name «sBlock» refers to state block.

style Indicates characters used by radio button’s display() method


style (Assignable)

Contains a character string that indicates the characters that are used by the radio button’s display() method. The string must contain four characters. The first is the left delimiter. Its default value is the left parenthesis ( ( ) character. The second is the selected indicator. Its default value is the asterisk (*) character. The third is the unselected indicator. Its default is the space ( » » ) character. The fourth character is the right delimiter. Its default value is the right parenthesis ( ) ) character.

Note: In graphic mode, the style instance variable is ignored.

display() Shows a radio button and its caption on the screen


oRadioButto:display() → self

display() is a method of the RadioButto class that is used for showing a radio button and its caption on the screen. display() uses the values of the following instance variables to correctly show the radio button in its current context in addition to providing maximum flexibility in the manner a radio button appears on the screen: buffer, caption, capCol, capRow, col, colorSpec, hasFocus, row, and style.

HitTest() Indicates position of mouse cursor relative to radio button


oRadioButto:hitTest(nMouseRow, nMouseCol)

nHitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the relationship of the mouse cursor with the radio button.

Applicable Hit Test Return Values

       Value   Constant    Description

       0       HTNOWHERE   The mouse cursor is not within the region of the

                           screen that the radio button occupies

       -1025   HTCAPTION   The mouse cursor is on the radio button’s caption

       -2049   HTCLIENT    The mouse cursor is on the radio button

Button.ch contains manifest constants for the RadioButto:hitTest() return value.

HitTest() is a method of the RadioButto class that is used for determining if the mouse cursor is within the region of the screen that the radio button occupies.

HitTest() returns a numeric value in order to maintain an appropriate level of symmetry with the HitTest() methods contained within the other data input control classes.

isAccel() Determines if a key press is interpreted as a user request


oRadioButto:isAccel(nInkeyValue)

lHotKeyStatus

nInkeyValue is a numeric value that indicates the inkey value to check.

Returns a logical value that indicates whether the value specified by nInkeyValue should be treated as a hot key. A value of true (.T.) indicates that the key should be treated as a hot key; otherwise, a value of false (.F.) indicates that it should not.

isAccel() is a method of the RadioButto class that is used for determining whether a key press should be interpreted as a user request to select a radio button.

killFocus() Takes input focus away from the RadioButto object


oRadioButto:killFocus() → self

killFocus() is a method of the RadioButto class that is used for taking input focus away from a RadioButto object. Upon receiving this message, the RadioButto object redisplays itself and, if present, evaluates the code block within its fBlock instance variable.

This message is meaningful only when the RadioButto object has input focus.

Select() Changes the state of a radio button


oRadioButto:select([lNewState]) → self

lNewState is a logical value that indicates whether the radio button should be selected or not. Set to true (.T.) to select the button or false (.F.) to deselect the button. If omitted, the radio button state will toggle to its opposing state.

Select() is a method of the RadioButto class that is used for changing the state of a radio button. Its state is typically changed when the space bar or one of the arrow keys is pressed or the mouse’s left button is pressed when its cursor is within the radio button’s screen region.

This message is meaningful only when the RadioButto object has input focus, or when the radio button is a member of a Group object that has input focus.

setFocus() Gives input focus to the RadioButto object


oRadioButto:setFocus() → self

setFocus() is a method of the RadioButto class that is used for giving focus to a RadioButto object. Upon receiving this message, the RadioButto object redisplays itself and, if present, evaluates the code block within its fBlock instance variable.

This message is meaningful only when the RadioButto object does not have input focus.

Examples

■  This example creates two radio buttons, one with a caption of
   "Commands" and the other "Macros," and groups them together using the
   RadioGroup class:

   oRadio1:RadioButto(2,2,"Commands")
   oRadio2:RadioButto(3,2,"Macros")
   oRadiogroup:RadioGroup(2,2,3,9)

Platforms

Available on MS-DOS

RadioGroup class⌃ | ☰

Create a radio button group

Description

The RadioGroup class provides a convenient mechanism for manipulating radio buttons.

Methods link

RadioGroup() Create a new RadioGroup object


RadioGroup(nTop, nLeft, nBottom, nRight)

oRadioGroup

Arguments

nTop is a numeric value that indicates the top screen row of the radio group.

nLeft is a numeric value that indicates the left screen column of the radio group.

nBottom is a numeric value that indicates the bottom screen row of the radio group.

nRight is a numeric value that indicates the right screen column of the radio group.

Returns

Returns a RadioGroup object when all of the required arguments are present; otherwise, RadioGroup() returns NIL.

Exported Instance Variables


bottom Numeric value indicating the bottommost screen row


bottom (Assignable)

Contains a numeric value that indicates the bottommost screen row where the radio group is displayed.

buffer Numeric value indicating the position in the radio group


buffer (Assignable)

Contains a numeric value that indicates the position in the radio group of the selected radio button.

capCol Indicates column where radio group’s caption is displayed


capCol (Assignable)

Contains a numeric value that indicates the screen column where the radio group’s caption is displayed.

capRow Indicates row where the radio group’s caption is displayed


capRow (Assignable)

Contains a numeric value that indicates the screen row where the radio group’s caption is displayed.

caption Character string describing the radio group on the screen


caption (Assignable)

Contains a character string that concisely describes the radio group on the screen.

When present, the & character specifies that the character immediately following it in the caption is the radio group’s accelerator key. The accelerator key provides a quick and convenient mechanism for the user to move input focus from one data input control to a radio group. The user performs the selection by pressing the Alt key in combination with an accelerator key. The case of an accelerator key is ignored.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the RadioGroup object. RadioGroup:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a RadioGroup object and retrieved later.

coldBox Characters to use when drawing a box around a radio group


coldBox (Assignable)

Contains an optional string that specifies the characters to use when drawing a box around the radio group when it does not have input focus. Its default value is a single-line box.

Standard Box Types

       Constant            Description

       B_SINGLE            Single-line box

       B_DOUBLE            Double-line box

       B_SINGLE_DOUBLE     Single-line top/bottom, double-line sides

       B_DOUBLE_SINGLE     Double-line top/bottom, single-line sides

Box.ch contains manifest constants for the RadioGroup:coldBox value.

colorSpec Indicates colors used by the radio group’s display() method


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the radio group’s display() method. The string must contain three color specifiers.

RadioGroup Color Attributes

       Position     Applies To                          Default Value from

       in colorSpec                                     System Color Setting

       1            The radio group’s border                Border

       2            The radio group’s caption               Standard

       3            The radio group caption’s               Background

                    accelerator key

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Workbench Properties window for that item.

fBlock Code block evaluated at each input focus change


fBlock (Assignable)

Contains an optional code block that, when present, is evaluated each time the RadioGroup object receives or loses input focus. The code block takes no implicit arguments. Use the RadioGroup:hasFocus instance variable to determine if the radio group is receiving or losing input focus. A value of true (.T.) indicates that it is receiving input focus; otherwise, a value of false (.F.) indicates that it is losing input focus.

This code block is included in the RadioGroup class to provide a method of indicating when an input focus change event has occurred. The name «fBlock» refers to focus block.

hasFocus Logical value indicating the input focus


hasFocus

Contains a logical value that indicates whether the RadioGroup object has input focus. It should contain true (.T.) when it has input focus; otherwise, it should contain false (.F.).

hotBox Specifies characters to use when drawing a radio group’s box


hotBox (Assignable)

Contains an optional string that specifies the characters to use when drawing a box around the radio group when it has input focus. Its default value is a double-line box.

Standard Box Types

       Constant            Description

       B_SINGLE            Single-line box

       B_DOUBLE            Double-line box

       B_SINGLE_DOUBLE     Single-line top/bottom, double-line sides

       B_DOUBLE_SINGLE     Double-line top/bottom, single-line sides

Box.ch contains manifest constants for the RadioGroup:hotBox value.

itemCount Indicates total number of radio buttons in the radio group


itemCount (Assignable)

Contains a numeric value that indicates the total number of radio buttons in the RadioGroup object.

left Indicates leftmost column where the radio group is displayed


left (Assignable)

Contains a numeric value that indicates the leftmost screen column where the radio group is displayed.

message Character string that is the radio group’s description


message (Assignable)

Contains a character string that is the radio group’s description that is displayed on the screen’s status bar line.

right Indicates rightmost column where radio group is displayed


right (Assignable)

Contains a numeric value that indicates the rightmost screen column where the radio group is displayed.

top Indicates the topmost row where the radio group is displayed


top (Assignable)

Contains a numeric value that indicates the topmost screen row where the radio group is displayed.

typeOut Logical value indicating whether group contains any buttons


typeOut (Assignable)

Contains a logical value that indicates whether the group contains any buttons. A value of true (.T.) indicates the group contains selectable buttons; a false (.F.) value indicates that the group is empty.

addItem() Appends a new radio button to a radio group


oRadioGroup:addItem(oRadioButto) → self

oRadioButto is the radio button object to be added.

addItem() is a method of the RadioGroup class that is used for appending a new radio button to a radio group.

delItem() Removes a radio button from a radio group


oRadioGroup:delItem(nPosition>) → self

nPosition is a numeric value that indicates the position in the radio group of the radio button to be deleted.

delItem() is a method of the RadioGroup class that is used for removing a radio button from a radio group.

display() Shows its radio buttons on the screen


oRadioGroup:display() → self

display() is a method of the RadioGroup class used for showing its radio buttons on the screen. display() accomplishes this by calling the display() method of each of the radio buttons in its group.

getAccel() Determines if a key press is interpreted as a user request


oRadioGroup:getAccel(nInkeyValue) → nPosition

nInkeyValue is a numeric value that indicates the inkey value to check.

Returns a numeric value that indicates the position in the radio group of the first item whose accelerator key matches that which is specified by nInkeyValue.

getAccel() is a method of the RadioGroup class that is used for determining whether a key press should be interpreted as a user request to select a particular radio button. getAccel() accomplishes this by calling the getAccel() method of each of the radio buttons in its group.

getItem() Retrieves a radio button from a radio group


oRadioGroup:getItem(nPosition) → oRadioButto

nPosition is a numeric value that indicates the position in the list of the item that is being retrieved.

Returns the RadioButto object specified by nPosition.

getItem() is a method of the RadioGroup class that is used for retrieving a radio button from a radio group.

HitTest() Indicates position of mouse cursor relative to radio group


oRadioGroup:hitTest(nMouseRow, nMouseCol)

nHitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the relationship of the mouse cursor with the radio group.

Applicable Hit Test Return Values

       Value   Constant       Description

       > 0     Not Applicable The position in the radio group of the radio

                              button whose region the mouse is within

       0       HTNOWHERE      The mouse cursor is not within the region of

                              the screen that the radio group occupies

       -1      HTTOPLEFT      The mouse cursor is on the radio group’s

                              border

       -2      HTTOP          The mouse cursor is on the radio group’s top

                              border

       -3      HTTOPRIGHT     The mouse cursor is on the top right corner of

                              the radio group’s border

       -4      HTRIGHT        The mouse cursor is on the radio group’s right

                              border

       -5      HTBOTTOMRIGHT  The mouse cursor is on the bottom right corner

                              of the radio group’s border

       -6      HTBOTTOM       The mouse cursor is on the radio group’s bottom

                              border

       -7      HTBOTTOMLEFT   The mouse cursor is on the bottom left corner

                              of the radio group’s border

       -8      HTLEFT         The mouse cursor is on the radio group’s left

                              border

       -2049   HTCLIENT       The mouse cursor is within the radio group’s

                              screen region but not on a radio button

Button.ch contains manifest constants for the RadioGroup:hitTest() return value.

HitTest() is a method of the RadioGroup class that is used for determining if the mouse cursor is within the region of the screen that any of the RadioButto objects contained within the radio group occupies. HitTest() accomplishes this by calling the HitTest() method of each of the radio buttons in its group.

insItem() Inserts a new radio button into a radio group


oRadioGroup:insItem(nPosition, oRadioButto)

→ self

nPosition is a numeric value that indicates the position at which the new item is inserted.

oRadioButto is the RadioButto object to be inserted.

insItem() is a method of the RadioGroup class that is used for inserting a new radio button into a radio group.

killFocus() Takes input focus away from the RadioGroup object


oRadioGroup:killFocus() → self

killFocus() is a method of the RadioGroup class that is used for taking input focus away from a RadioGroup object. Upon receiving this message, the RadioGroup object redisplays itself and, if present, evaluates the code block within its fBlock instance variable.

This message is meaningful only when the RadioGroup object has input focus.

nextItem() Changes radio button from current item to the following one


oRadioGroup:nextItem() → self

nextItem() is a method of the RadioGroup class that is used for changing the selected radio button from the current item to the one immediately following it.

This message is meaningful only when the RadioGroup object has input focus.

prevItem() Changes radio button from current item to the previous one


oRadioGroup:prevItem() → self

prevItem() is a method of the RadioGroup class that is used for changing the selected item from the current radio button to the one immediately before it.

This message is meaningful only when the RadioGroup object has input focus.

Select() Changes the selected radio button in a radio group


oRadioGroup:select(nPosition) → self

nPosition is a numeric value that indicates the position in the list of the radio button to be selected.

Select() is a method of the RadioGroup class that is used for changing the selected radio button in a radio group. Its state is typically changed when one of the arrow keys is pressed or the mouse’s left button is pressed when its cursor is within one of the radio button’s screen region.

This message is meaningful only when the RadioGroup object has input focus.

SetColor() Sets the color attributes of all radio buttons in a group


oRadioGroup:setColor([cColorString]) → self

cColorString is a character string that indicates the color attributes that are used by the radio button’s display() method. The string must contain seven color specifiers.

RadioButto Color Attributes

       Position     Applies To                            Default Value from

       in colorSpec                                       System Color Setting

       1            A radio button when it is unselected    Unselected

                    and does not have input focus

       2            A radio button when it is selected and  Unselected

                    does not have input focus

       3            A radio button when it is unselected    Enhanced

                    and has input focus

       4            A radio button when it is selected and  Enhanced

                    has input focus

       5            A radio button’s caption                Standard

       6            A radio button caption’s accelerator    Standard

                    key when it does not have input focus

       7            A radio button caption’s accelerator    Background

                    key when it has input focus

SetColor() is a method of the RadioGroup class that is used for uniformly setting the color attributes of all the radio buttons in its group. SetColor() accomplishes this by setting the colorSpec instance variable of each of the radio buttons in its group to the value specified by cColorString.

setFocus() Gives input focus to the RadioGroup object


oRadioGroup:setFocus() → self

setFocus() is a method of the RadioGroup class that is used for giving focus to a RadioGroup object. Upon receiving this message, the RadioGroup object redisplays itself and, if present, evaluates the code block within its fBlock instance variable.

This message is meaningful only when the RadioGroup object does not have input focus.

setStyle() Sets the style attribute of all radio buttons in a group


oRadioGroup:setStyle([cStyle]) → self

cStyle is a character string that indicates the characters that are used by the radio button’s display() method. The string must contain four characters. The first is the left delimiter. The second is the selected indicator. The third is the unselected indicator. The fourth character is the right delimiter.

setStyle() is a method of the RadioGroup class that is used for uniformly setting the Style attribute of all the radio buttons in its group. setStyle() accomplishes this by setting the Style of each of the radio buttons in its group to the value specified by cStyle.

Examples

■  This example creates a group of radio buttons, one with a
   caption of "Commands" and the other "Macros":

   oRadio1:RadioButto(2,2,"Commands")
   oRadio2:RadioButto(3,2,"Macros")
   oRadiogroup:RadioGroup(2,2,3,9)

Platforms

Available on MS-DOS

RAt()Harbour implementation


⌃ | ☰

Return the position of the last occurrence of a substring

Syntax

RAt(<cSearch>, <cTarget>) → nPosition

Arguments

cSearch is the character string to be located.

cTarget is the character string to be searched.

Returns

RAt() returns the position of cSearch within cTarget as an integer numeric value. If cSearch is not found, RAt() returns zero.

Description

RAt() is a character function that returns the position of the last occurrence of a character substring within another character string. It does this by searching the target string from the right. RAt() is like the At() function, which returns the position of the first occurrence of a substring within another string. RAt() is also like the $ operator, which determines whether a substring is contained within a string.

Both the RAt() and At() functions are used with SubStr(), Left(), and Right() to extract substrings.

Examples

■  This example uses RAt() to create a user-defined function,
   FilePath(), that extracts the path from a file specification.  If the
   path is unspecified, FilePath() returns a null string (""):

   ? FilePath("C:DBFSales.dbf")      // Result: C:DBF

   FUNCTION FilePath( cFile )
      LOCAL nPos, cFilePath
      IF (nPos := RAt("", cFile)) != 0
         cFilePath = SubStr(cFile, 1, nPos)
      ELSE
         cFilePath = ""
      ENDIF
      RETURN cFilePath

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

ReadExit()Harbour implementation


⌃ | ☰

Toggle Up arrow and Down arrow as READ exit keys

Syntax

ReadExit([<lToggle>]) → lCurrentState

Arguments

lToggle toggles the use of Up arrow and Down arrow as READ exit keys. Specifying true (.T.) enables them as exit keys, and false (.F.) disables them.

Returns

ReadExit() returns the current setting as a logical value.

Description

ReadExit() is an environment function that reports the current state of Up arrow and Down arrow as keys the user can press to exit a READ from the first or last Get object in a GetList. If the optional lToggle argument is specified, Up arrow and Down arrow are either enabled or disabled as READ exit keys. At program startup, Up arrow and Down arrow are not enabled as READ exit keys. Normally, READ exit keys include only Pgup, Pgdn, Esc, or Return from the last GET.

Examples

■  This example shows ReadExit() enabling Up arrow and Down arrow
   exit keys before a READ then resetting them after the READ
   terminates:

   cMyvar = Space(10)
   lLastExit = ReadExit(.T.)   // Result: Turn on exit keys
   //
   @ 10, 10 SAY "Enter: " GET cMyvar
   READ
   ReadExit(lLastExit)         // Result: Restore previous setting

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ReadFormat()Harbour implementation


⌃ | ☰

Return and optionally, set the code block that implements a format (.fmt) file

Syntax

ReadFormat([<bFormat>]) → bCurrentFormat

Arguments

bFormat is the name of the code block, if any, to use for implementing a format file. If no argument is specified, the function simply returns the current code block without setting a new one.

Returns

ReadFormat() returns the current format file as a code block. If no format file has been set, ReadFormat() returns NIL.

Description

ReadFormat() is a Get system function that accesses the current format file in its internal code block representation. It lets you manipulate the format file code block from outside of the Get system’s source code.

To set a format file, use SET FORMAT (see the SET FORMAT entry ) or ReadFormat().

ReadFormat() is intended primarily for creating new READ layers. The code block that ReadFormat() returns, when evaluated, executes the code that is in the format file from which it was created.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

ReadInsert()Harbour implementation


⌃ | ☰

Toggle the current insert mode for READ and MemoEdit()

Syntax

ReadInsert([<lToggle>]) → lCurrentMode

Arguments

lToggle toggles the insert mode on or off. True (.T.) turns insert on, while false (.F.) turns insert off. The default is false (.F.) or the last user-selected mode in READ or MemoEdit().

Returns

ReadInsert() returns the current insert mode state as a logical value.

Description

ReadInsert() is an environment function that reports the current state of the insert mode for READ and MemoEdit() and, optionally, sets the insert mode on or off depending on the value of lToggle. When ReadInsert() returns false (.F.) and the user enters characters into a Get object’s buffer during a READ or a MemoEdit(), characters are overwritten. When ReadInsert() returns true (.T.), entered characters are inserted instead. The insert mode is a global setting belonging to the system and not to any specific object.

You can execute ReadInsert() prior to or during a READ or MemoEdit(). If used with READ, ReadInsert() can be invoked within a WHEN or VALID clause of @...GET or within a SET KEY procedure. If used with MemoEdit(), it can be invoked with the user function as well as a SET KEY procedure.

Examples

■  This example sets the insert mode prior to entering MemoEdit()
   and resets the mode when MemoEdit() terminates:

   USE Sales NEW

   // Turn on insert mode
   lInsMode = ReadInsert(.T.)
   Sales->Notes := MemoEdit(Sales->Notes)
   //
   // Restore previous insert mode
   ReadInsert(lInsMode)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ReadKey()*Harbour implementation


⌃ | ☰

Determine what key terminated a READ

Syntax

Returns

ReadKey() returns a code representing the key pressed to exit a READ. In CA-Clipper, the following keys are the standard READ exit keys and their ReadKey() return codes:

ReadKey() Return Codes

    Exit Key            Return Code

    Up arrow             5

    Down arrow           2

    PgUp                 6

    PgDn                 7

    Ctrl+PgUp           31

    Ctrl+PgDn           30

    Esc                 12

    Ctrl+End, Ctrl+W    14

    Type past end       15

    Return              15

Description

ReadKey() is a keyboard function that emulates the ReadKey() function in dBASE III PLUS. Its purpose is to determine what key the user pressed to terminate a READ. If Updated() is true (.T.), ReadKey() returns the code plus 256. Up arrow and Down arrow exit a READ only if ReadExit() returns true (.T.). The default value is false (.F.). To provide complete compatibility for these keys, execute a READEXIT (.T.) at the beginning of your main procedure.

ReadKey() is supplied as a compatibility function and, therefore, its use is strongly discouraged. It is superseded entirely by LastKey() which determines the last keystroke fetched from the keyboard buffer. If the keystroke was a READ exit key, LastKey() will return the Inkey() code for that key. To determine whether any Get object’s buffer was modified during a READ, it is superseded by the Updated() function.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/READKEY.PRG

See also

ReadKill()Harbour implementation


⌃ | ☰

Return, and optionally set, whether the current READ should be exited

Syntax

ReadKill([<lKillRead>]) → lCurrentSetting

Arguments

lKillRead sets the ReadKill() flag. A value of true (.T.) indicates that the current read should be terminated, and a value of false (.F.) indicates that it should not.

Returns

ReadKill() returns the current setting as a logical value.

Description

ReadKill() is a Get system function that lets you control whether or not to terminate the current READ.

Unless directly manipulated, ReadKill() returns true (.T.) after you issue a CLEAR GETS (see the CLEAR GETS entry ) for the current READ; otherwise, it returns false (.F.).

By accessing the function directly, however, you can control the ReadKill() flag with its function argument and use it to create new READ layers.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

ReadModal()Harbour implementation


⌃ | ☰

Activate a full-screen editing mode for a GetList

Syntax

ReadModal(<aGetList>, [<nGet>], [<oMenu>], [<nMsgRow>,
   <nMsgLeft>, <nMsgRight>, <cMsgColor>])
   → <lUpdated>

Arguments

aGetList is an array containing a list of Get objects to edit.

nGet is an optional numeric value that indicates which Get object within aGetList should initially receive input focus.

oMenu is an optional Topbarmenu object that, when supplied, permits menu selection during data entry.

nMsgRow, nMsgLeft, and nMsgRight specify the row, left, and right margins where the Get object messages appear on the screen.

cMsgColor defines the color setting of the message area. It consists of a single foreground/background color pair.

Returns

ReadModal() returns true (.T.) when GetList is updated, false (.F.) when it is not.

Description

ReadModal() is a user interface function that implements the full-screen editing mode for GETs, and is part of the open architecture Get system of CA-Clipper. ReadModal() is like the READ command, but takes a GetList array as an argument and does not reinitialize the GetList array when it terminates. Because of this, you can maintain multiple lists of Get objects and activate them any time in a program’s execution as long as the array to activate is visible.

In order to retain compatibility with previous versions of CA-Clipper, the GET system in CA-Clipper is implemented using a public array called GetList. Each time an @...GET command executes, it creates a Get object and adds to the currently visible GetList array. The standard READ command is preprocessed into a call to ReadModal() using the GetList array as its argument. If the SAVE clause is not specified, the variable GetList is assigned an empty array after the ReadModal() function terminates.

Some of the functions in the Getsys.prg have been made public so that they can be used when implementing customized GET readers. These functions are listed in the table below.

Get System functions

    Function            Description

    GetActive()         Return the currently active Get object

    GetApplyKey()       Apply a key to a Get object from within a GET reader

    GetDoSetKey()       Process SET KEY during GET editing

    GetPostValidate()   Postvalidate the current Get object

    GetPreValidate()    Prevalidate a Get object

    GetReader()         Execute standard READ behavior for a Get object

    ReadFormat()        Return and, optionally, set the code block that

                        implements a format (.fmt) file

    ReadKill()          Return and, optionally, set whether the current Read

                        should be exited

    ReadUpdated()       Return and, optionally, set whether a GET has

                        changed during a Read

For reference information on the Get objects and functions listed above, refer to the «Get System» chapter in the Programming and Utilities Guide.

For more information on the supported keys in the default ReadModal() function, refer to the READ command reference in this chapter.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is SOURCE/SYS/GETSYS.PRG

See also

ReadUpdated()Harbour implementation


⌃ | ☰

Determine whether any GET variables changed during a READ and optionally change the ReadUpdated() flag

Syntax

ReadUpdated([<lChanged>]) → lCurrentSetting

Arguments

lChanged sets the ReadUpdated() flag. A value of true (.T.) indicates that data has changed, and a value of false (.F.) indicates that no change has occurred.

Returns

ReadUpdated() returns the current setting as a logical value.

Description

ReadUpdated() is a Get system function intended primarily for creating new READ Layers. It is identical in functionality to Updated() (see the Updated() entry ), except that it allows the Updated() flag to be set.

ReadUpdated() enables you to manipulate the Updated() flag from outside of the Get system’s source code.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, source file is Getsys.prg.

See also

ReadVar()Harbour implementation


⌃ | ☰

Return the current GET/MENU variable name

Syntax

Returns

ReadVar() returns the name of the variable associated with the current Get object or the variable being assigned by the current MENU TO command as an uppercase character string.

Description

ReadVar() is an environment function that primarily implements context- sensitive help for Get objects and lightbar menus. ReadVar() only works during a READ or MENU TO command. If used during any other wait states, such as ACCEPT, INPUT, WAIT, AChoice(), dbEdit(), or MemoEdit(), it returns a null string («»). Access it within a SET KEY procedure, or within a user-defined function invoked from a WHEN or VALID clause of a Get object.

Examples

■  This example implements a simple help system for Get objects
   using a database file to store the help text.  When the user presses
   F1, the help database file is searched using ReadVar() as the key
   value.  If there is help text available, it is displayed in a window:

   #include "Inkey.ch"
   //
   SET KEY K_F1 TO HelpLookup
   cString = Space(10)
   @ 5, 5 SAY "Enter:" GET cString
   READ
   RETURN

   FUNCTION HelpLookup
      USE Help INDEX Help NEW
      SEEK ReadVar()
      IF Found()
         DisplayHelp(Help->Topic)
      ELSE
         DisplayHelp("No help for " + ReadVar())
      ENDIF
      CLOSE Help
      RETURN NIL

   FUNCTION DisplayHelp( cTopic )
      LOCAL cScreen := SaveScreen(5,5,15,70),;
             cColor := SetColor("BG+/B")
      //
      SET CURSOR OFF
      @ 5, 5 CLEAR TO 15, 70
      @ 5, 5 TO 15, 70 DOUBLE
      @ 5, 30 SAY " Help for " + ReadVar() + " "
      MemoEdit(cTopic, 6, 7, 14, 68, .F.)
      //
      RestScreen(5, 5, 15, 70, cScreen)
      SetColor(cColor)
      SET CURSOR ON
      //
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RecCount()*→ LastRec()Harbour implementation


⌃ | ☰

Determine the number of records in the current database (.dbf) file

Syntax

RecCount()* | LastRec() → nRecords

Returns

RecCount() returns the number of physical records in the current database file as an integer numeric value. Filtering commands such as SET FILTER or SET DELETED have no affect on the return value. RecCount() returns zero if there is no database file open in the current work area.

Description

RecCount() is a database function that is a synonym for LastRec(). By default, RecCount() 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 (see example below). Note that RecCount() is a compatibility function. LastRec() should be used in its place.

Examples

■  This example illustrates the relationship between COUNT and
   RecCount():

   USE Sales NEW
   ? RecCount()                      // Result: 84
   //
   SET FILTER TO Salesman = "1001"
   COUNT TO nRecords
   ? nRecords                        // Result: 14
   ? RecCount()                      // Result: 84

■  This example uses an aliased expression to access the number
   of records in an unselected work area:

   USE Sales NEW
   USE Customer NEW
   ? RecCount(), Sales->(RecCount())

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RecNo()Harbour implementation


⌃ | ☰

Return the identity at the position of the record pointer

Syntax

Returns

RecNo() returns the identity found at the position of the record pointer.

Description

RecNo() is a database function that returns the identity found at the current position of the record pointer. Identity is a unique value guaranteed by the structure of the data file to reference a specific record of a data file. The data file need not be a traditional Xbase file. Therefore, unlike earlier versions of CA-Clipper, the value returned need not be a numeric data type.

Under all RDDs, RecNo() returns the value at the position of the record pointer; the data type and other characteristics of this value are determined by the content of the accessed data and the RDD active in the current work area. In an Xbase database this value is the record number.

Examples

USE Sales VIA "DBFNTX"
.
. < statements >
.
dbGoTop()
RecNo()            // Returns 1

Platforms

Available on MS-DOS

RecSize()Harbour implementation


⌃ | ☰

Determine the record length of a database (.dbf) file

Syntax

Returns

RecSize() returns, as a numeric value, the record length in bytes of the database file open in the current work area. RecSize() returns zero if no database file is open.

Description

RecSize() is a database function that determines the length of a record by summing the lengths of each field then adding one for the Deleted() status flag. When this value is multiplied by LastRec(), the product is the amount of space occupied by the file’s records.

RecSize() is useful in programs that perform automatic file backup. When used in conjunction with DiskSpace(), the RecSize() function can assist in ensuring that sufficient free space exists on the disk before a file is stored.

By default, RecSize() 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 (see example below).

Examples

■  The following user-defined function, DbfSize(), uses RecSize()
   to calculate the size of the current database file:

   FUNCTION DbfSize
      RETURN ((RecSize() * LastRec()) + Header() + 1)

■  This example illustrates the use of RecSize() to determine the
   record length of database files open in unselected work areas:

   USE Customer NEW
   USE Sales NEW
   //
   ? RecSize(), Customer->(RecSize())
   ? DbfSize(), Customer->(DbfSize())

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

Replicate()Harbour implementation


⌃ | ☰

Return a string repeated a specified number of times

Syntax

Replicate(<cString>, <nCount>) → cRepeatedString

Arguments

cString is the character string to be repeated.

nCount is the number of times to repeat cString.

Returns

Replicate() returns a character string up to a maximum of 65,535 (64K) bytes in length. Specifying a zero as the nCount argument returns a null string («»).

Description

Replicate() is a character function that repeatedly displays, prints, or stuffs the keyboard with one or more characters. Replicate() is like the Space() function, which returns a specified number of space characters.

Examples

■  These examples demonstrate Replicate() repeating strings:

   ? Replicate("*", 5)           // Result: *****
   ? Replicate("Hi ", 2)         // Result: Hi Hi
   ? Replicate(Chr(42), 5)       // Result: *****

■  This example uses Replicate() to stuff the keyboard with
   several Down arrow keys:

   #include "Inkey.ch"
   KEYBOARD REPLICATE(Chr(K_DOWN), 25)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RestScreen()Harbour implementation


⌃ | ☰

Display a saved screen region to a specified location

Syntax

RestScreen([<nTop>], [<nLeft>],
   [<nBottom>], [<nRight>], <cScreen>) → NIL

Arguments

nTop, nLeft, nBottom, and nRight define the coordinates of the screen information contained in cScreen. If cScreen was saved without coordinates to preserve the entire screen, no screen coordinates are necessary with RestScreen().

cScreen is a character string containing the saved screen region.

Returns

RestScreen() always returns NIL.

Description

RestScreen() is a screen function that redisplays a screen region saved with SaveScreen(). The target screen location may be the same as or different from the original location when the screen region was saved. If you specify a new screen location, the new screen region must be the same size or you will get ambiguous results. To use RestScreen() to restore screen regions saved with SAVE SCREEN, specify the region coordinates as 0, 0, MaxRow(), MaxCol().

Warning! SAVE SCREEN, RESTORE SCREEN, SaveScreen(), and RestScreen() are supported when using the default (IBM PC memory mapped) screen driver. Other screen drivers may not support saving and restoring screens.

Examples

■  This example demonstrates RestScreen() as part of a general
   purpose pop-up menu function, PopMenu():

   ? PopMenu({1, 1, 3, 10, {"ItemOne", "ItemTwo"}, ;
         "BG+/B"})

   FUNCTION PopMenu( aList )
      LOCAL cScreen, nChoice, cOldColor := ;
               SetColor(aList[6])
      cScreen := SaveScreen(aList[1], aList[2],;
          aList[3], aList[4])
      @ aList[1], aList[2], TO aList[3], aList[4] DOUBLE
      nChoice := AChoice(++aList[1], ++aList[2],;
         --aList[3], --aList[4], aList[5])
      SetColor(cOldColor)
      RestScreen(--aList[1], --aList[2], ++aList[3],;
          ++aList[4], cScreen)
      RETURN nChoice

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

READHarbour implementation⌃ | ☰

Activate full-screen editing mode using Get objects

Syntax

READ [SAVE] [MENU <oMenu>] [MSG AT <nRow>, <nLeft>,
   <nRight>] [MSG COLOR <cColorString>]

Arguments

SAVE retains the contents of the current GetList after the READ terminates. Later, you can edit the same Get objects by issuing another READ. If not specified, the current GetList is assigned an empty array deleting all of the previous Get objects when the READ terminates.

MENU oMenu specifies an optional Topbarmenu object that, when supplied, permits menu selection during data entry.

MSG AT nMsgRow, nMsgLeft, nMsgRight specify the row, left, and right margins where the Get object messages appear on the screen. If omitted, messages will not appear.

MSG COLOR cMsgColor defines the color setting of the message area. It consists of a single foreground/background color pair.

Description

READ executes a full-screen editing mode using all Get objects created and added to the current GetList since the most recent CLEAR, CLEAR GETS, CLEAR ALL or READ commands. If there is a format procedure active, READ executes that procedure before entering the full-screen editing mode.

Within a READ, the user can edit the buffer of each Get object as well as move from one Get object to another. Before the user can enter a Get object, control passes to the associated WHEN lPreCondition if one has been assigned to that Get object. If lPreCondition returns true (.T.), the user is allowed to edit the buffer of the Get object. Otherwise, control passes to the next Get object in the GetList. Within a GET buffer, the user can edit using the full complement of editing and navigation keys. See the tables below.

When the user presses a GET exit key, control passes to the associated RANGE or VALID postcondition if one has been specified. If either condition returns true (.T.), editing of the Get object is terminated and control passes to the next Get object. Otherwise, control remains within the current Get object until a valid value is entered or the user presses the Esc key.

When the user successfully enters a value into a Get object, the associated variable is assigned the value of the Get object’s buffer.

The following tables list active keys within a READ:

READ Navigation Keys

    Key                           Action

    Left arrow, Ctrl+S            Character left. Does not move cursor to

                                  previous GET.

    Right arrow, Ctrl+D           Character right.  Does not move cursor to

                                  next GET.

    Ctrl+Left arrow, Ctrl+A       Word left.

    Ctrl+Right arrow, Ctrl+F      Word right.

    Up arrow, Shift+Tab, Ctrl+E   Previous GET.

    Down arrow, Tab, Ctrl+X,      Return, Ctrl+M Next GET.

    Home                          First character of GET.

    End                           Last character of GET.

    Ctrl+Home                     Beginning of first GET.

READ Editing Keys

    Key                 Action

    Del, Ctrl+G         Delete character at cursor position

    Backspace, Ctrl+H   Destructive backspace

    Ctrl+T              Delete word right

    Ctrl+Y              Delete from cursor position to end of GET

    Ctrl+U              Restore current GET to original value

READ Toggle Keys

    Key            Action

    Ins, Ctrl+V    Toggle insert mode

READ Exit Keys

    Key                           Action

    Ctrl+W, Ctrl+C, PgUp, PgDn    Terminate READ saving current GET

    Return, Ctrl+M                Terminate READ from last GET

    Esc                           Terminate READ without saving current GET

    Up arrow                      Terminate READ from first GET if

                                  ReadExit()=.T.

    Down arrow                    Terminate READ from last GET if

                                  ReadExit()=.T.

Notes

■ Nested READs: To perform a nested READ within a SET KEY,

VALID, or WHEN procedure or user-defined function, declare or create a new GetList, perform a series of @...GET statements, and then READ. When the procedure terminates, the new GetList is released and the previous GetList becomes visible again. See the example below.

■ Quick keys: Pressing Home or End in quick succession goes to

the first or last nonblank character in a Get object’s buffer.

■ Terminating a READ: A READ is terminated by executing a BREAK,

CLEAR, CLEAR GETS, or CLEAR ALL from within a SET KEY procedure or a user-defined function initiated by VALID.

Updated(): If any Get object buffer was changed during the

current READ, Updated() is set to true (.T.).

Examples

■  This example defines several GETs then READs them:

   CLEAR
   cVar1 := cVar2 := cVar3 := Space(10)
   @ 10, 10 SAY "Variable one:" GET cVar1 VALID ;
         !Empty(cVar1)
   @ 11, 10 SAY "Variable two:" GET cVar2 ;
            WHEN RTrim(cVar1) !=  "One"
   @ 12, 10 SAY "Variable three:" GET cVar3 VALID ;
            !Empty(cVar3)
   READ

■  This example performs a nested READ within a SET KEY, WHEN, or
   VALID procedure or user-defined function:

   LOCAL cName := Space(10)
   @ 10, 10 GET cName VALID SubForm( cName )
   READ
   RETURN

   FUNCTION SubForm( cLookup )
      LOCAL GetList := {}         // Create new GetList
      USE Sales INDEX Salesman NEW
      SEEK cLookup
      IF Found()
         @ 15, 10 GET Salesman    // Add Get objects to
         @ 16, 10 GET Amount      // new GetList
         READ                     // READ from new GetList
      ENDIF
      CLOSE Sales
      RETURN .T.                  // Release new GetList

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RECALLHarbour implementation⌃ | ☰

Restore records marked for deletion

Syntax

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

Arguments

scope is the portion of the current database file to RECALL. The default scope is the current record, or NEXT 1. If a condition is specified, the default scope becomes ALL.

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

FOR lCondition specifies the conditional set of records to RECALL within the given scope.

Description

RECALL is a database command that restores records marked for deletion in the current work area. This is the inverse of the DELETE command. If DELETED is ON, RECALL can restore the current record or a specific record, if you specify a RECORD scope. Note that once you PACK a database file, all marked records have been physically removed from the file and cannot be recovered.

In a network environment, RECALLing the current record requires an RLock(). RECALLing several records requires an FLock() or EXCLUSIVE USE of the current database file. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Examples

■  This examples show the results of RECALL:

   USE Sales NEW
   //
   DELETE RECORD 4
   ? Deleted()               // Result: .T.
   //
   RECALL
   ? Deleted()               // Result: .F.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

REINDEXHarbour implementation⌃ | ☰

Rebuild open indexes in the current work area

Syntax

REINDEX
   [EVAL <lCondition>]
   [EVERY <nRecords>]

Arguments

EVAL lCondition specifies a condition that is evaluated either for each record processed or at the interval specified by the EVERY clause. This clause is identical to the EVAL clause of the INDEX command, but must be respecified in order for the reindexing operation to be monitored since the value of lCondition is transient.

EVERY nRecords specifies a numeric expression that modifies how often EVAL is evaluated. When using EVAL, the EVERY option offers a performance enhancement by evaluating the condition for every nth record instead of evaluating each record reindexed. The EVERY keyword is ignored if no EVAL condition is specified.

Description

REINDEX is a database command that rebuilds all open indexes in the current work area. When the reindexing operation finishes, all rebuilt indexes remain open, order is reset to one, and the record pointer is positioned to the first record in the controlling index. If any of the indexes were created with SET UNIQUE ON, REINDEX adds only unique keys to the index. If any of the indexes were created using a FOR condition, only those key values from records matching the condition are added to the index.

In a network environment, REINDEX requires EXCLUSIVE USE of the current database file. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Caution! REINDEX does not recreate the header of the index file when it recreates the index. Because of this, REINDEX does not help if there is corruption of the file header. To guarantee a valid index, always use INDEX ON in place of REINDEX to rebuild damaged indexes

Notes

Index key order, UNIQUE status, and the FOR condition are known to the index (.ntx) file and are, therefore, respected and maintained by REINDEX.

Examples

■  This example REINDEXes the index open in the current work
   area:

   USE Sales INDEX Salesman, Territory NEW
   REINDEX

■  This example REINDEXes using a progress indicator:

USE Sales INDEX Salesman, Territory NEW
   REINDEX EVAL NtxProgress() EVERY 10

   FUNCTION NtxProgress
   LOCAL cComplete := LTrim(Str((RecNo()/LastRec()) * 100))
   @ 23, 00 SAY "Indexing..." + cComplete + "%"

   RETURN .T.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RELEASEHarbour implementation⌃ | ☰

Delete public and private memory variables

Syntax

RELEASE <idMemvar list>
RELEASE ALL [LIKE | EXCEPT <skeleton>]

Arguments

idMemvar list is a list of private or public variables or arrays to delete.

ALL [LIKE|EXCEPT skeleton] defines the set of visible private memory variables to assign, or to exclude from assignment of, a NIL value. skeleton is the wildcard mask to specify a group of memory variables to delete. The wildcard characters supported are * and ?.

Description

RELEASE is a memory variable command that performs one of two actions depending on how it is specified. If RELEASE is specified with idMemvar list, the specified public and private memory variables and/or arrays are deleted from memory. Previous hidden instances (public or private variables defined in higher-level procedures) become accessible upon termination of the procedure where the variable was originally created.

If RELEASE is specified with any form of the ALL clause, private memory variables created at the current procedure level are assigned a NIL and not deleted until the current procedure or user-defined function terminates. Public variables are unaffected by this form of the RELEASE command. To release public variables, you must RELEASE them explicitly or use CLEAR MEMORY.

Local or static variables are not affected by the RELEASE command. Local variables are released automatically when the procedure or user- defined function (where the variables were declared) terminates. Static variables cannot be released since they exist for the duration of the program.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RENAMEHarbour implementation⌃ | ☰

Change the name of a file

Syntax

RENAME <xcOldFile> TO <xcNewFile>

Arguments

xcOldFile is the name of the file to be renamed including an extension, and optionally is preceded by a drive and/or path designator. xcOldFile can be a literal string or a character expression enclosed in parentheses.

TO xcNewFile specifies the new file name including extension and optionally prefaced by a drive and/or path designator. xcNewFile can be a literal string or a character expression enclosed in parentheses.

Description

RENAME is a file command that changes the name of a specified file to a new name. If the source directory is different from the target directory, the file moves to the new directory. RENAME does not use SET DEFAULT and SET PATH to locate xcOldFile. Instead, the xcOldFile is renamed only if it is located in the current DOS directory or in the specified path.

In the instance that either xcNewFile exists or is currently open, RENAME does nothing. To trap this condition as an error, use the File() function before executing the command. See the example.

Warning! Files must be CLOSEd before renaming. Attempting to rename an open file will produce unpredictable results. When a database file is RENAMEd, remember that any associated memo (.dbt) file must also be RENAMEd. Failure to do so may compromise the integrity of your program.

Examples

■  This example renames a file, checking for the existence of the
   target file before beginning the RENAME operation:

   xcOldFile := "OldFile.txt"
   xcNewFile := "NewFile.txt"
   IF !FILE(xcNewFile)
      RENAME (xcOldFile) TO (xcNewFile)
      ELSE
   ? "File already exists"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

REPLACEHarbour implementation⌃ | ☰

Assign new values to field variables

Syntax

REPLACE <idField> WITH <exp>
   [, <idField2> WITH <exp2>...]
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]

Arguments

idField is the name of the field variable to be assigned a new value. If idField is prefaced with an alias, the assignment takes place in the designated work area.

WITH exp defines the value to assign to idField.

scope is the portion of the current database file to REPLACE. The default is the current record, or NEXT 1. Specifying a condition changes the default to ALL records in the current work area.

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

FOR lCondition specifies the conditional set of records to REPLACE within the given scope.

Description

REPLACE is a database command that assigns new values to the contents of one or more field variables in the current record in the specified work areas. The target field variables can be character, date, logical, memo, or numeric. REPLACE performs the same function as the assignment operator (:=) except that it assumes that an unaliased reference is to a field variable. This means that you can assign new values to field variables using assignment statements provided that the field variable references are prefaced with an alias, the FIELD alias, or declared using the FIELD declaration statement.

The default scope of REPLACE is the current record unless a scope or condition is specified. If a scope or condition is specified, the replace operation is performed on each record matching the scope and/or condition.

Warning! When you REPLACE a key field, the index is updated and the relative position of the record pointer within the index is changed. This means that REPLACEing a key field with a scope or a condition may yield an erroneous result. To update a key field, SET ORDER TO 0 before the REPLACE. This ensures that the record pointer moves sequentially in natural order. All open indexes, however, are updated if the key field is REPLACEd.

In a network environment, REPLACEing the current record requires an RLock(). REPLACEing with a scope and/or condition requires an FLock() or EXCLUSIVE USE of the current database file. If a field is being REPLACEd in another work area by specifying its alias, that record must also be locked with an RLock(). Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Examples

■  This example shows a simple use of REPLACE:

   USE Customer NEW
   APPEND BLANK
   USE Invoices NEW
   APPEND BLANK
   //
   REPLACE Charges WITH Customer->Markup * Cost,;
      Custid WITH Customer->Custid,;
      Customer->TranDate WITH Date()

■  This example uses assignment statements in place of the
   REPLACE command:

   FIELD->Charges := Customer->Markup * FIELD->Cost
   FIELD->Custid := Customer->Custid
   Customer->TranDate := Date()

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

REPORT FORMHarbour implementation⌃ | ☰

Display a report to the console

Syntax

REPORT FORM <xcReport>
   [TO PRINTER] [TO FILE <xcFile>] [NOCONSOLE]
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]
   [PLAIN | HEADING <cHeading>] [NOEJECT] [SUMMARY]

Arguments

xcReport is the name of the report form (.frm) file that contains the definition of the REPORT. If an extension is not specified, (.frm) is assumed. xcReport can be specified as a literal string or as a character expression enclosed in parentheses.

TO PRINTER echoes output to the printer.

TO FILE xcFile echoes output without form feed characters (ASCII 12) to a file. If a file extension is not specified, .txt is added. You can specify xcFile as a literal string or as a character expression enclosed in parentheses.

NOCONSOLE suppresses all REPORT FORM output to the console. If not specified, output automatically displays to the console unless SET CONSOLE is OFF.

scope is the portion of the current database file to report. The default scope is ALL.

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

FOR lCondition specifies the conditional set of records to report within the given scope.

PLAIN suppresses the display of the date and page number, and causes the report to print without page breaks. In addition, the report title and column headings display only at the top of the report.

HEADING places the result of cHeading on the first line of each page. cHeading is evaluated only once at the beginning of the report before the record pointer is moved. If both PLAIN and HEADING are specified, PLAIN takes precedence.

NOEJECT suppresses the initial page eject when the TO PRINTER clause is used.

SUMMARY causes REPORT FORM to display only group, subgroup, and grand total lines. Detail lines are suppressed.

Description

REPORT FORM is a console command that sequentially accesses records in the current work area and displays a tabular and optionally grouped report with page and column headings from a definition held in a .frm file. The actual REPORT FORM file (.frm) is created using RL.EXE or dBASE III PLUS. Refer to the «Report and Label Utility» chapter in the Programming and Utilities Guide for more information about creating report definitions.

When invoked, REPORT FORM sends output to the screen and, optionally, to the printer and/or a file. To suppress output to the screen while printing or echoing output to a file, SET CONSOLE OFF or use the NOCONSOLE keyword before the REPORT FORM invocation.

When invoked, REPORT FORM searches the current SET PATH drive and directory if the xcReport file is not found in the current directory and the path is not specified.

Notes

■ Interrupting REPORT FORM: To allow the user to interrupt a

REPORT FORM, use Inkey() to test for an interrupt key press, as a part of the FOR condition. See the example below.

■ Printer margin: REPORT FORM obeys the current SET MARGIN value

for output echoed to the printer.

■ Forcing formfeed characters into an output file: To include

form feed characters when sending a REPORT FORM TO FILE, redirect printer output to a file using SET PRINTER like this:

SET PRINTER TO xcFile REPORT FORM xcReport TO PRINTER SET PRINTER TO

■ Reporting in a network environment: REPORT FORM commands

executed in a network environment can be affected by changes made to database files by other users while the report is in progress. For example, if a user changes a key value from «A» to «Z» while the report is printing, the same record could appear twice.

Examples

■  This example uses both a literal and an extended expression to
   execute a REPORT FORM:

   LOCAL xcReport := "Sales"
   USE Sales INDEX Sales NEW
   REPORT FORM Sales TO PRINTER FOR Branch = "100";
             HEADING "Branch 100"
   REPORT FORM (xcReport) TO PRINTER FOR Branch != "100"

■  This example interrupts a REPORT FORM using Inkey() to test
   whether the user has pressed the Esc key:

   #define K_ESC  27
   USE Sales INDEX Sales NEW
   REPORT FORM Sales WHILE Inkey() != K_ESC

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

REQUEST⌃ | ☰

Declare a module request list

Syntax

Arguments

idModule list is the list of modules that will be linked into the current executable (.EXE) file.

Description

REQUEST is a declaration statement that defines a list of module identifiers to the linker. Like all other declaration statements, a REQUEST statement must be specified before any executable statements in either the program file, or a procedure or user-defined function definition.

During the compilation of CA-Clipper source code, all explicit references to procedures and user-defined functions are made to the linker. In some instances, within a source file, there may be no references made to procedure or user-defined function names until runtime. REQUEST resolves this situation by forcing the named procedures or user-defined functions to be linked even if they are not explicitly referenced in the source file. This is important in several instances:

■ Procedures, user-defined functions, or formats referenced with

macro expressions or variables

■ Procedures and user-defined functions used in REPORT and LABEL

FORMs and not referenced in the source code

■ User-defined functions used in index keys and not referenced

in the source code

AChoice(), dbEdit(), or MemoEdit() user functions

■ Initialization procedures declared with the INIT PROCEDURE

statement

■ Exit procedures declared with the EXIT PROCEDURE statement

To group common REQUESTs together, place them in a header file and then include (#include) the header file into each program file (.prg) that might indirectly use them.

Examples

■  This example shows a typical header file consisting of common
   REQUESTs for REPORT FORMs:

   // Request.ch

   REQUEST HardCR
   REQUEST Tone
   REQUEST MemoTran
   REQUEST StrTran

Platforms

Available on MS-DOS

See also

RESTOREHarbour implementation⌃ | ☰

Retrieve memory variables from a memory (.mem) file

Syntax

RESTORE FROM <xcMemFile> [ADDITIVE]

Arguments

xcMemFile is the memory (.mem) file to load from disk. If an extension is not specified, the extension .mem is assumed. The file name may be specified as a literal string or as a character expression enclosed in parentheses.

ADDITIVE causes memory variables loaded from the memory file to be added to the existing pool of memory variables.

Description

RESTORE is a memory variable command that recreates public and private variables previously SAVEd to a memory (.mem) file and initializes them with their former values. The scope of the variable is not SAVEd with the variable, but is instead established when the variable is RESTOREd. Arrays and local variables cannot be SAVEd or RESTOREd.

When memory variables are RESTOREd, they are recreated as private variables with the scope of the current procedure or user-defined function unless they exist as public variables and you specify the ADDITIVE clause. If ADDITIVE is specified, public and private variables with the same names are overwritten unless hidden with PRIVATE. If ADDITIVE is not specified, all public and private variables are released before the memory file is loaded.

Local and static variables are unaffected by RESTORE. If a local or static variable has been declared in the current procedure or user- defined function and a variable with the same name is RESTOREd, only the local or static variable is visible unless references to the RESTOREd variable are prefaced with the MEMVAR alias.

Examples

■  This example demonstrates a typical application of SAVE and
   RESTORE.  Here memory variables containing screens are SAVEd TO and
   RESTOREd FROM memory files:

   // Create and use a pseudoarray of screens
   SAVE SCREEN TO cScreen1
   SAVE ALL LIKE cScreen* TO Screens
   //
   <statements>...
   //
   RESTORE FROM Screens ADDITIVE
   nNumber = "1"
   RESTORE SCREEN FROM ("cScreen" + nNumber)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RESTORE SCREEN*Harbour implementation⌃ | ☰

Display a saved screen

Syntax

RESTORE SCREEN [FROM <cScreen>]

Arguments

FROM cScreen specifies a character expression to display to the screen.

Description

RESTORE SCREEN is a command synonym for the RestScreen() function that redisplays a previously saved screen, and is used with SAVE SCREEN to avoid repainting the original screen painted with @...SAY, @...GET, and ? commands.

RESTORE SCREEN works in two ways depending on whether or not you specify the FROM clause. If you specify the FROM clause, the SCREEN is RESTOREd FROM cScreen. cScreen is a character expression, usually a variable assigned a screen image by SAVE SCREEN. If you do not specify the FROM clause, the SCREEN is RESTOREd from the default save screen buffer created by SAVE SCREEN specified without the TO clause.

SaveScreen() and RESTORESCREEN() functions supersede SAVE SCREEN and RESTORE SCREEN commands.

RESTORE SCREEN is a compatibility command and therefore not recommended.

Warning! SAVE SCREEN, RESTORE SCREEN, SaveScreen(), and RestScreen() are supported when using the default (IBM PC memory mapped) screen driver. Other screen drivers may not support saving and restoring screens.

Examples

■  This example displays a small alert pop-up box using SAVE and
   RESTORE SCREEN:

   IF FileAlert()
      COPY FILE Them.txt TO My.txt
   ELSE
      BREAK
   ENDIF
   RETURN

   FUNCTION FileAlert
      LOCAL lAnswer := .F., cScreen
      SAVE SCREEN TO cScreen
      @ 10, 10 CLEAR TO 12, 45
      @ 10, 10 TO 12, 45 DOUBLE
      @ 11, 12 SAY "File exists, overwrite? (y/n) ";
             GET lAnswer PICTURE "Y"
      READ
      RESTORE SCREEN FROM cScreen
      RETURN lAnswer

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RETURN⌃ | ☰

Terminate a procedure, user-defined function, or program

Syntax

Arguments

exp is an expression of any type that evaluates to the return value for user-defined functions. If a user-defined function terminates without executing a RETURN statement, the return value is NIL.

Description

RETURN terminates a procedure, user-defined function, or program by returning control to either the calling procedure or user-defined function. When RETURN executes in the highest level procedure, control passes to the operating system. All private variables created and local variables declared in the current procedure or user-defined function are released when control returns to the calling procedure.

There can be more than one RETURN in a procedure or user-defined function. A procedure or user-defined function need not, however, end with a RETURN. Since user-defined functions must return values, each must contain at least one RETURN statement with an argument.

Note: A procedure or user-defined function definition is terminated by a PROCEDURE statement, a FUNCTION statement, or end of file but not by a RETURN statement.

Notes

■ Arrays: Since array is a data type like any other data type,

instances of array type are really values like character strings and, therefore, can be RETURNed from a user-defined function.

RETURN TO MASTER: CA-Clipper does not support RETURN TO MASTER

or any other form of RETURN specifying the level to which the call is to return. You can, however, simulate these operations with BEGIN SEQUENCE...END.

Examples

■  These examples illustrate the general form of the RETURN
   statement in a procedure and in a user-defined function:

   PROCEDURE <idProcedure>
      //
      <statements>...
      //
      RETURN

   FUNCTION <idFunction>
      //
      <statements>...
      //
      RETURN <expReturn>

■  This example returns an array, created in a user-defined
   function, to a calling procedure or user-defined function:

   FUNCTION PassArrayBack
      PRIVATE aArray[10][10]
      aArray[1][1] = "myString"
      RETURN aArray

Platforms

Available on MS-DOS

See also

Right()Harbour implementation


⌃ | ☰

Return a substring beginning with the rightmost character

Syntax

Right(<cString>, <nCount>) → cSubString

Arguments

cString is the character string from which to extract characters.

nCount is the number of characters to extract.

Returns

Right() returns the rightmost nCount characters of cString. If nCount is zero, Right() returns a null string («»). If nCount is negative or larger than the length of the character string, Right() returns cString. The maximum string size is 65,535 (64K) bytes.

Description

Right() is a character function that extracts a substring beginning with the rightmost character in cString. It is the same as the character expression, SubStr(cString, nCount). For example, Right(«ABC», 1) is the same as SubStr(«ABC», -1). Right() is related to Left(), which extracts a substring beginning with the leftmost character in cString.

The Right(), Left(), and SubStr() functions are often used with both the At() and RAt() functions to locate either the first and/or the last position of a substring before extracting it.

Examples

■  This example shows the relationship between Right() and
   SubStr():

   ? Right("ABCDEF", 3)              // Result: DEF
   ? SubStr("ABCDEF", -3)            // Result: DEF

■  This example extracts a substring from the end of another
   string up to the last occurrence of a comma:

   LOCAL cName := "James,William"
   ? Right(cName,;
   Len(cName) - RAt(",", cName) - 1)      // Result: William

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

RLock()Harbour implementation


⌃ | ☰

Lock the current record in the active work area

Syntax

Returns

RLock() returns true (.T.) if the record lock is obtained; otherwise, it returns false (.F.).

Description

RLock() is a network function that locks the current record, preventing other users from updating the record until the lock is released. RLock() provides a shared lock, allowing other users read-only access to the locked record while allowing only the current user to modify it. A record lock remains until another record is locked, an UNLOCK is executed, the current database file is closed, or an FLock() is obtained on the current database file.

For each invocation of RLock(), there is one attempt to lock the current record, and the result is returned as a logical value. An attempt to obtain a record lock fails if another user currently has a file or record lock on that particular record, or EXCLUSIVE USE of the database file. An attempt to RLock() in an empty database returns true (.T.).

By default, RLock() 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 (see example below). This feature is useful since RLock() does not automatically attempt a record lock for related files.

As a general rule, RLock() operates solely on the current record. This includes the following commands:

@...GET

DELETE (single record)

RECALL (single record)

REPLACE (single record)

Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Notes

SET RELATION: CA-Clipper does not automatically lock all

records in the relation chain when you lock the current work area record. Also, an UNLOCK has no effect on related work areas.

Examples

■  This example deletes a record in a network environment, using
   RLock():

   USE Customer INDEX CustName SHARED NEW
   SEEK "Smith"
   IF Found()
      IF RLock()
         DELETE
         ? "Smith deleted"
      ELSE
         ? "Record in use by another"
      ENDIF
   ELSE
      ? "Smith not in Customer file"
   ENDIF
   CLOSE

■  This example specifies RLock() as an aliased expression to
   lock a record in an unselected work area:

   USE Sales SHARED NEW
   USE Customer SHARED NEW
   //
   IF !Sales->(RLock())
      ? "The current Sales record is in use by another"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Round()Harbour implementation


⌃ | ☰

Return a numeric value rounded to a specified number of digits

Syntax

Round(<nNumber>, <nDecimals>) → nRounded

Arguments

nNumber is the numeric value to be rounded.

nDecimals defines the number of decimal places to retain. Specifying a negative nDecimals value rounds whole number digits.

Returns

Round() returns a numeric value.

Description

Round() is a numeric function that rounds nNumber to the number of places specified by nDecimals. Specifying a zero or negative value for nDecimals allows rounding of whole numbers. A negative nDecimals indicates the number of digits to the left of the decimal point to round. Digits between five to nine (inclusive) are rounded up. Digits below five are rounded down.

The display of the return value does not obey the DECIMALS setting unless SET FIXED is ON. With SET FIXED OFF, the display of the return value contains as many decimal digits as you specify for nDecimals, or zero, if nDecimals is less than one.

Examples

■  These examples round values with decimal digits:

   SET DECIMALS TO 2
   SET FIXED ON
   //
   ? Round(10.4, 0)                     // Result: 10.00
   ? Round(10.5, 0)                     // Result: 11.00
   ? Round(10.51, 0)                    // Result: 11.00
   ? Round(10.49999999999999, 2)        // Result: 10.50

■  These examples use a negative <nDecimals> argument to round
   numeric values to whole number values:

   ? Round(101.99, -1)                  // Result: 100.00
   ? Round(109.99, -1)                  // Result: 110.00
   ? Round(109.99, -2)                  // Result: 100.00

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Row()Harbour implementation


⌃ | ☰

Return the screen row position of the cursor

Syntax

Returns

Row() returns the cursor row position as an integer numeric value. The range of the return value is zero to MaxRow().

Description

Row() is a screen function that returns the current row or line position of the screen cursor. The value of Row() is updated by both console and full-screen commands and functions. @...SAY only updates Row() when the current DEVICE is the SCREEN.

Row() is used with Col() and all variations of the @ command to position the cursor to a new line relative to the current line. In particular, you can use Row() and Col() to create screen position-independent procedures or functions where you pass the upper-left row and column as parameters.

Row() is related to PRow() and PCol(), which track the current printhead position instead of the screen cursor position.

Examples

■  In this example, Row() simulates the LIST command, displaying
   text on the same line but in different columns:

   LOCAL nRow
   USE Customer INDEX CustName NEW
   DO WHILE .NOT. Eof()
      CLS
      @ 1, 1 SAY PadR("Name", Len(CustName))
      @ Row(), Col() + 2 SAY PadR("Address", ;
            Len(Address))
      @ Row(), Col() + 2 SAY PadR("Phone", Len(Phone))
      nRow = 0
      DO WHILE nRow++ <= 15 .AND. (!Eof())
         @ Row() + 1, 1 SAY CustName
         @ Row(), Col() + 2 SAY Address
         @ Row(), Col() + 2 SAY Phone
         SKIP
      ENDDO
      WAIT
   ENDDO
   CLOSE Customer

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RTrim()Harbour implementation


⌃ | ☰

Remove trailing spaces from a character string

Syntax

RTrim(<cString>) → cTrimString

Arguments

cString is the character string to be copied without trailing spaces.

Returns

RTrim() returns a copy of cString with the trailing spaces removed. If cString is a null string («») or all spaces, RTrim() returns a null string («»).

Description

RTrim() is a character function that formats character strings. It is useful when you want to delete trailing spaces while concatenating strings. This is typically the case with database fields which are stored in fixed-width format. For example, you can use RTrim() to concatenate first and last name fields to form a name string.

RTrim() is related to LTrim() which removes leading spaces, and AllTrim() which removes both leading and trailing spaces. The inverse of AllTrim(), LTrim(), and RTrim() are the PadC(), PadR(), and PadL() functions which center, right-justify, or left-justify character strings by padding them with fill characters. RTrim() is exactly the same as Trim() in function.

Notes

■ Space characters: The RTrim() function treats carriage

returns, line feeds, and tabs as space characters and removes these as well.

Examples

■  This is a user-defined function in which RTrim() formats city,
   state, and zip code fields for labels or form letters:

   FUNCTION CityState(cCity, cState, cZip)
      RETURN RTrim(cCity) + ", " ;
       + RTrim(cState) + "  " + cZip

■  In this example the user-defined function, CityState(),
   displays a record from Customer.dbf:

   USE Customer INDEX CustName NEW
   SEEK "Kate"
   ? CityState(City, State, ZipCode)
   // Result: Athens, GA 10066

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

RUNHarbour implementation⌃ | ☰

Execute a DOS command or program

Syntax

Arguments

xcCommandLine is any executable program including resident DOS commands and COMMAND.COM. It may be specified either as a literal string or as a character expression enclosed in parentheses.

Description

RUN executes a DOS command or program from within a compiled application. When you RUN a DOS program, CA-Clipper executes another copy of COMMAND.COM, passing the DOS command line at the same time. This has two implications. First, you must have enough memory for COMMAND.COM (5K for DOS 6.2) and the program you wish to execute. Second, COMMAND.COM must be available on the path specified by COMSPEC (the default is the root directory of the disk where you boot DOS). If COMMAND.COM is not located on this disk or the disk is changed, SET COMSPEC to the new location prior to running the CA-Clipper application. Note that SET DEFAULT and SET PATH have no effect on RUN.

The ! form of the RUN command is provided for compatibility purposes only and, therefore, is not recommended.

Warning! Do not RUN memory-resident programs from within CA-Clipper since you may lose memory when the control returns to your application program.

Examples

■  This example uses RUN with MemoRead() and MemoWrit() to create
   a user-defined function that calls a text editor with the current
   memo field:

   lSuccess = EditorMemo("Qedit", "Notes")
   RETURN

   FUNCTION EditorMemo( cEditor, cMemofld )
      IF MemoWrit("Clipedit.tmp", &cMemofld.)
         RUN (cEditor + " Clipedit.tmp")
         REPLACE &cMemofld. WITH MemoRead("Clipedit.tmp")
         ERASE Clipedit.tmp
         RETURN .T.
      ELSE
         RETURN .F.
      ENDIF

■  One of the options you may want to give your users is direct
   access to DOS.  Do this with:

   RUN COMMAND

   To make it easier for the user to return to the application program,
   change the DOS prompt in the application batch file like this:

   REM Application Batch File

   ECHO OFF
   PROMPT DOS Access: Type EXIT to return to ;
            application$_$p$g
   <your application program>
   PROMPT $p$g

   Then, instruct the user to execute the application batch file in
   place of the application .EXE file.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

SaveScreen()Harbour implementation


⌃ | ☰

Save a screen region for later display

Syntax

SaveScreen([<nTop>], [<nLeft>],
   [<nBottom>], [<nRight>]) → cScreen

Arguments

nTop, nLeft, nBottom, and nRight define the coordinates of the screen region to be saved. If either nBottom or nRight is greater than MaxRow() or MaxCol(), the screen is clipped. If you specify no coordinates, the entire screen (i.e., from 0,0 to MaxRow(), MaxCol()) is saved.

Returns

SaveScreen() returns the specified screen region as a character string.

Description

SaveScreen() is a screen function that saves a screen region to a variable of any storage class including a field variable. Later, you can redisplay the saved screen image to the same or a new location using RestScreen(). Screen regions are usually saved and restored when using a pop-up menu routine or dragging a screen object.

Warning! SAVE SCREEN, RESTORE SCREEN, SaveScreen(), and RestScreen() are supported when using the default (IBM PC memory mapped) screen driver. Other screen drivers may not support saving and restoring screens.

Examples

■  The following user-defined function creates a pop-up menu
   using AChoice() with SaveScreen() and RestScreen(), returning the
   selection in the array of choices:

   FUNCTION PopMenu( nTop, nLeft, nBottom, nRight, ;
                        aItems, cColor )
      LOCAL cScreen, nChoice, cLastColor := ;
            SetColor(cColor)
      //
      cScreen:= SaveScreen(nTop, nLeft, nBottom, nRight)
      @ nTop, nLeft TO nBottom, nRight DOUBLE
      //
      nChoice:= AChoice(++nTop, ++nLeft, ;
                   --nBottom, --nRight, aItems)
      //
      RestScreen(--nTop, --nLeft, ++nBottom, ++nRight, ;
                     cScreen)
      SetColor(cLastColor)
      RETURN nChoice

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

SAVEHarbour implementation⌃ | ☰

Save variables to a memory (.mem) file

Syntax

SAVE TO <xcMemFile> [ALL [LIKE | EXCEPT <skeleton>]]

Arguments

xcMemFile is the memory (.mem) file to SAVE to disk. You may specify the file name as a literal string or as a character expression enclosed in parentheses. If you specify no extension, the file is created with a .mem extension.

ALL [LIKE|EXCEPT skeleton] defines the set of visible private and public memory variables to save to xcMemFile. skeleton is the wildcard mask that characterizes a group of memory variables to SAVE. The wildcard characters supported are * and ?.

Description

SAVE copies public and private memory variables visible within the current procedure or user-defined function to a memory (.mem) file. Arrays and local and static variables, however, cannot be SAVEd. When variables are SAVEd, they are copied without any reference to scope. Variables hidden by PRIVATE or LOCAL declarations are not SAVEd.

If you specify the ALL LIKE clause, variable names matching the skeleton mask are saved. By contrast, if you specify ALL EXCEPT, variable names not matching the skeleton are saved.

You can specify a skeleton that includes wildcard characters. The * wildcard character matches any group of adjacent characters ending a variable name and can be specified only at the end of the skeleton. The ? wildcard character matches any single character and can be specified anywhere within the skeleton.

Examples

■  This example saves all visible private and public variables to
   Temp.mem:

   PRIVATE cOne := "1"
   SAVE ALL TO Temp

■  This example saves all visible private and public variables
   with names beginning with "c" to Myvars.mem:

   SAVE ALL LIKE c* TO MyVars

■  This example saves all visible private and public variables
   with names that do not begin with "c" to Myvars2.mem:

   SAVE ALL EXCEPT c* TO MyVars2

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SAVE SCREEN*Harbour implementation⌃ | ☰

Save the current screen to a buffer or variable

Syntax

Arguments

TO idVar specifies a variable to contain the current screen contents as a character value. If idVar is not visible or does not exist, a private memory variable is created and assigned to the screen.

Description

SAVE SCREEN is a command synonym for the SaveScreen() function that saves the screen from 0, 0 to MaxRow(), MaxCol() in a default screen buffer, or in an optional variable. If the screen is saved to a variable, the variable can be any storage class including field, local, static, or an array element. Note, however, you cannot SAVE an array or local or static variable to .mem files to save multiple screens to disk.

SAVE SCREEN is used with RESTORE SCREEN to eliminate repainting an original screen that has been temporarily replaced. You may save multiple screens by assigning each screen to a separate variable.

SAVE SCREEN is a compatibility command and not recommended. It is superseded by the SaveScreen() function which can save partial or full screens.

Warning! SAVE SCREEN, RESTORE SCREEN, SaveScreen(), and RestScreen() are supported when using the default (IBM PC memory mapped) screen driver. Other screen drivers may not support saving and restoring screens.

Examples

■  This code skeleton uses a static array to store saved screens:

   STATIC aScreens[10]
   SAVE SCREEN TO aScreens[1]
   //
   <statements>...
   //
   RESTORE SCREEN FROM aScreens[1]

■  This example saves and restores screens using a database file:

USE Screens INDEX Name NEW
   APPEND BLANK

   Screens->Name := "Screen001"            // Save the screen name
   SAVE SCREEN TO Screens->Image           // Save a new screen image
   //
   <statements>...
   //
   SEEK "Screen001"                        // Find the screen
   RESTORE SCREEN FROM Screens->Image      // Restore it

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Scroll()Harbour implementation


⌃ | ☰

Scroll a screen region up or down, right or left

Syntax

Scroll([<nTop>], [<nLeft>],[<nBottom>], [<nRight>],
   [<nVert>] [<nHoriz>]) → NIL

Arguments

nTop, nLeft, nBottom, and nRight define the scroll region coordinates. Row and column values can range from 0, 0 to MaxRow(), MaxCol(). If you do not specify coordinate arguments, the dimensions of the visible display are used.

nVert defines the number of rows to scroll vertically. A positive value scrolls up the specified number of rows. A negative value scrolls down the specified number of rows. A value of zero disables vertical scrolling. If nVert is not specified, zero is assumed.

nHoriz defines the number of rows to scroll horizontally. A positive value scrolls left the specified number of columns. A negative value scrolls right the specified number of columns. A value of zero disables horizontal scrolling. If nHoriz is not specified, zero is assumed.

If you supply neither the nVert nor nHoriz parameters to Scroll(), the area specified by the first four parameters will be blanked.

Warning! Horizontal scrolling is not supported on all of the alternate terminal drivers (i.e., ANSITERM, NOVTERM, PCBIOS).

Returns

Scroll() always returns NIL.

Description

Scroll() is a screen function that scrolls a screen region up or down a specified number of rows. When a screen scrolls up, the first line of the region is erased, all other lines are moved up, and a blank line is displayed in the current standard color on the bottom line of the specified region. If the region scrolls down, the operation is reversed. If the screen region is scrolled more than one line, this process is repeated.

Scroll() is used primarily to display status information into a defined screen region. Each time a new message is displayed, the screen region scrolls up one line and a new line displays at the bottom.

Examples

■  This user-defined function displays a message string at the
   bottom of a screen region after scrolling the region up one line:

   FUNCTION ScrollUp( nTop, nLeft, nBottom, nRight, ;
                        expDisplay )
      //
      Scroll(nTop, nLeft, nBottom, nRight, 1)
      @ nBottom, nLeft SAY expDisplay
      //
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Scrollbar class⌃ | ☰

Creates a scroll bar

Description

Scroll bars allow users to view data that exists beyond the limit of a window. By scrolling up, down, left, or right, you can reveal previously hidden pieces of data. Applications should provide scroll bars for any screen in which the data displayed is larger than the current window.

Methods link

ScrollBar() Create a new ScrollBar object


Scrollbar (nStart, nEnd, nOffset, [bSBlock]

[,nOrient]) → oScrollBar

Arguments

nStart is a numeric value that indicates the screen position where the scroll bar begins. nStart refers to the topmost row of a vertically oriented scroll bar, or the leftmost column of a horizontally oriented scroll bar.

nEnd is a numeric value that indicates the screen position where the scroll bar ends. nEnd refers to the bottommost row of a vertically oriented scroll bar, or the rightmost column of a horizontally oriented scroll bar.

nOffset is a numeric value that indicates the screen column of a vertically oriented scroll bar or the screen row of a horizontally oriented scroll bar.

bSBlock is an optional code block that, when present, is evaluated immediately before and after the ScrollBar object’s state changes.

nOrient is an optional numeric value that indicates whether the scroll bar is vertically or horizontally oriented. The default is a vertically oriented scroll bar.

Returns

Returns a ScrollBar object when all of the required arguments are present; otherwise, ScrollBar() returns NIL.

Exported Instance Variables


barLength Marks number of positions scroll bar client area occupies


barlength

Contains a numeric value that indicates the number of character positions that the scroll bar client area occupies. Each position refers to one row for a vertically oriented scroll bar or one column for a horizontally oriented scroll bar. The client area is the area between (but not including) the scroll bar’s previous arrow and its next arrow.

bitmaps An array of bitmap files to be displayed


bitmaps (Assignable)

Contains an array of exactly three elements. The first element of this array is the file name of the bitmap to be displayed at the top of a vertical scroll bar or to the left of a horizontal scroll bar. The second element of this array is the file name of the bitmap to be displayed at the bottom of a vertical scroll bar or to the right of a horizontal scroll bar. The third element of this array is the file name of the bitmap to be used as the thumbwheel.

Drive and directory names are not allowed; the file name extension is required. A bitmap file can be stored as a file on disk or in a bitmap library. If stored as a file, the file must reside in the same directory as the application. If stored in a bitmap library, the library must reside in the same directory as the application and it also must have the same name as the application with a .BML extension.

CA-Clipper will search for the file name first and then, if it is not found, it will search in the bitmap library. If no file is found either on disk or in the library, no bitmap will be displayed.

If this instance variable is not used, and the application is running in graphic mode, the files ARROW_L.BMU, ARROW_R.BMU, and ARROW_E.BMU will be used for a horizontal scroll bar and the files ARROW_U.BMU, ARROW_D.BMU, and ARROW_E.BMU will be used for a horizontal scroll bar.

This instance variable only affects applications running in graphic mode and is ignored in text mode.

cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the ScrollBar object. ScrollBar:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a ScrollBar object and retrieved later.

colorSpec Indicates the colors used by the ScrollBa:display() method


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the scroll bar’s display() method. The string must contain two color specifiers.

Note: In graphic mode, colorSpec position 2 has no affect and is ignored.

ScrollBar Color Attributes

       Position     Applies To                          Default Value from

       in colorSpec                                     System Color Setting

       1            The scroll bar’s client area            Unselected

       2            The previous arrow, next arrow, and     Enhanced

                    thumb

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Workbench Properties window for that item.

current Indicates number of current item the scroll bar refers to


current (Assignable)

Contains a numeric value that indicates the number of the current item to which the scroll bar refers.

end Indicates the screen position of the scroll bar’s next arrow


end (Assignable)

Contains a numeric value that indicates the screen position of the scroll bar’s next arrow. ScrollBar:end refers to the bottommost row of a vertically oriented scroll bar, or the rightmost column of a horizontally oriented scroll bar.

offset Indicates column or row of vertical or horizontal scroll bar


offset (Assignable)

Contains a numeric value that indicates the screen column of a vertically oriented scroll bar or the screen row of a horizontally oriented scroll bar.

orient Indicates if scroll bar is vertically/horizontally oriented


orient (Assignable)

Contains a numeric value that indicates whether the scroll bar is vertically or horizontally oriented.

Scroll Bar Types

       Value   Constant            Description

       1       SCROLL_VERTICAL     Vertical scroll bar

       2       SCROLL_HORIZONTAL   Horizontal scroll bar

Button.ch contains manifest constants for the ScrollBar:orient value.

sBlock Code block evaluated at every state change


sblock (Assignable)

Contains an optional code block that, when present, is evaluated immediately after the ScrollBar object’s state changes. The code block takes no implicit arguments.

This code block is included in the ScrollBar class to provide a method of indicating when a state change event has occurred. The name «sblock» refers to state block.

start Indicates the screen position of scroll bar’s previous arrow


start (Assignable)

Contains a numeric value that indicates the screen position of the scroll bar’s previous arrow. ScrollBar:start refers to the topmost row of a vertically oriented scroll bar, or the leftmost column of a horizontally oriented scroll bar.

style Indicates characters used by the ScrollBar:display() method


style (Assignable)

Contains a character string that indicates the characters that are used by the scroll bar’s display() method. The string must contain four characters. The first character is the previous arrow character. Its default value is the up arrow character for a vertically oriented scroll bar and the left arrow character for a horizontally oriented scroll bar. The second character is the client area character. Its default value is the character. The third is the thumb character. Its default is the character. The fourth character is the next arrow character. Its default value is the down arrow character for a vertically oriented scroll bar or the right arrow character for a horizontally oriented scroll bar.

Note: In graphic mode, the style instance variable is ignored.

thumbPos Indicates relative position of the thumb within scroll bar


thumbpos

Contains a numeric value that indicates the relative screen position of the thumb within a scroll bar. Valid ScrollBar:thumbpos values range from 1 to ScrollBar:barlength.

total Indicates the total number of items the scroll bar refers to


total (Assignable)

Contains a numeric value that indicates the total number of items to which the scroll bar refers.

display() Shows a scroll bar, including its thumb, on the screen


oScrollBar:display() → self

display() is a method of the ScrollBar class that is used for showing a scroll bar including its thumb on the screen. display() uses the values of the following instance variables to correctly show the scroll bar in its current context, in addition to providing maximum flexibility in the manner a scroll bar appears on the screen: colorSpec, end, offset, orient, start, style, and thumbPos.

update() Changes the thumb position on the screen


oScrollBar:update() → self

update() is a method of the ScrollBar class that is used for changing the thumb position on the screen. update() uses the values of the following instance variables to correctly show the thumb in its current context in addition to providing maximum flexibility in the manner a scroll bar thumb appears on the screen: colorSpec, offset, orient, stable, start, style, and thumbPos.

HitTest() Indicates position of mouse cursor relative to scroll bar


oScrollBar:hitTest( nMouseRow, nMouseCol )

→ nHitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the action to perform based on the logical position of the mouse cursor in the scroll bar’s region of the screen.

Scroll Bar hittest Return Values

       Value     Constant            Mouse Cursor Position

       0         HTNOWHERE           Not within the scroll bar’s region of

                                     the screen

       -3073     HTSCROLLTHUMBDRAG   On the thumb

       -3074     HTSCROLLUNITDEC     On the previous arrow

       -3075     HTSCROLLUNITINC     On the next arrow

       -3076     HTSCROLLBLOCKDEC    Between the previous arrow and the

                                     thumb

       -3077     HTSCROLLBLOCKINC    Between the thumb and the next arrow

Button.ch contains manifest constants for the ScrollBar:hitTest() return value.

HitTest() is a method of the ScrollBar class that is used for determining if the mouse cursor is within the region of the screen that the scroll bar occupies.

Examples

■  This example creates a vertical scroll bar from row 2 to 10:

   oScr:=(2,10,0)

Platforms

Available on MS-DOS

Seconds()Harbour implementation


⌃ | ☰

Return the number of seconds elapsed since midnight

Syntax

Returns

Seconds() returns the system time as a numeric value in the form seconds.hundredths. The numeric value returned is the number of seconds elapsed since midnight, and is based on a twenty-four hour clock in a range from 0 to 86399.

Description

Seconds() is a time function that provides a simple method of calculating elapsed time during program execution, based on the system clock. It is related to the Time() function which returns the system time as a string in the form hh:mm:ss.

Examples

■  This example contrasts the value of Time() with Seconds():

   ? Time()               // Result: 10:00:00
   ? Seconds()            // Result: 36000.00

■  This example uses Seconds() to track elapsed time in seconds:

   LOCAL nStart, nElapsed
   nStart:= Seconds()
   .
   . <statements>
   .
   nElapsed:= Seconds() - nStart
   ? "Elapsed: " + LTrim(Str(nElapsed)) + " seconds"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Select()Harbour implementation


⌃ | ☰

Determine the work area number of a specified alias

Syntax

Select([<cAlias>]) → nWorkArea

Arguments

cAlias is the target work area alias name.

Returns

Select() returns the work area of the specified alias as an integer numeric value.

Description

Select() is a database function that determines the work area number of an alias. The number returned can range from 0 to 250. If cAlias is not specified, the current work area number is returned. If cAlias is specified and the alias does not exist, Select() returns zero.

Note: The Select() function and SELECT command specified with an extended expression argument look somewhat alike. This should not be a problem since the Select() function is not very useful on a line by itself.

Examples

■  This example uses Select() to determine which work area
   USE...NEW selected:

   USE Sales NEW
   SELECT 1
   ? Select("Sales")            // Result: 4

■  To reselect the value returned from the Select() function, use
   the SELECT command with the syntax, SELECT (<idMemvar>), like this:

   USE Sales NEW
   nWorkArea:= Select()
   USE Customer NEW
   SELECT (nWorkArea)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Set()Harbour implementation


⌃ | ☰

Inspect or change a system setting

Syntax

Set(<nSpecifier>, [<expNewSetting>], [<lOpenMode>])
   → CurrentSetting

Arguments

nSpecifier is a numeric value that identifies the setting to be inspected or changed. nSpecifier should be supplied as a manifest constant (see below).

expNewSetting is an optional argument that specifies a new value for the nSpecifier. The type of expNewSetting depends on nSpecifier.

lOpenMode is a logical value that indicates whether or not files opened for the following settings,

_SET_ALTFILE, _SET_PRINTFILE, _SET_EXTRAFILE

should be truncated or opened in append mode. A value of false (.F.) means the file should be truncated. A value of true (.T.) means the file should be opened in append mode. In either case, if the file does not exist, it is created.

If this argument is not specified, the default is append mode.

Returns

Set() returns the current value of the specified setting.

Description

Set() is a system function that lets you inspect or change the values of the CA-Clipper system settings. For information on the meaning and legal values for a particular setting, refer to the associated command or function.

Use a manifest constant to specify the setting to be inspected or changed. These constants are defined in a header file called set.ch. This header file should be included at the top of any source file which uses Set().

Set.ch also defines a constant called _SET_COUNT. This constant is equal to the number of settings that can be changed or inspected with Set(), allowing the construction of a generic function that preserves all settings (see example below).

Note: The numeric values of the manifest constants in set.ch are version-dependent and should never be used directly; the manifest constants should always be used.

If nSpecifier or expNewSetting is invalid, the call to Set() is ignored.

Set Values Defined in set.ch

    Constant            Value Type     Associated Command or Function

    _SET_EXACT          Logical        SET EXACT

    _SET_FIXED          Logical        SET FIXED

    _SET_DECIMALS       Numeric        SET DECIMALS

    _SET_DATEFORMAT     Character      SET DATE

    _SET_EPOCH          Numeric        SET EPOCH

    _SET_PATH           Character      SET PATH

    _SET_DEFAULT        Character      SET DEFAULT

    _SET_EXCLUSIVE      Logical        SET EXCLUSIVE

    _SET_SOFTSEEK       Logical        SET SOFTSEEK

    _SET_UNIQUE         Logical        SET UNIQUE

    _SET_DELETED        Logical        SET DELETED

    _SET_CANCEL         Logical        SetCancel()

    _SET_DEBUG          Numeric        AltD()

    _SET_COLOR          Character      SetColor()

    _SET_CURSOR         Numeric        SetCursor()

    _SET_CONSOLE        Logical        SET CONSOLE

    _SET_ALTERNATE      Logical        SET ALTERNATE

    _SET_ALTFILE        Character      SET ALTERNATE TO

    _SET_DEVICE         Character      SET DEVICE

    _SET_PRINTER        Logical        SET PRINTER

    _SET_PRINTFILE      Character      SET PRINTER TO

    _SET_MARGIN         Numeric        SET MARGIN

    _SET_BELL           Logical        SET BELL

    _SET_CONFIRM        Logical        SET CONFIRM

    _SET_ESCAPE         Logical        SET ESCAPE

    _SET_INSERT         Logical        ReadInsert()

    _SET_EXIT           Logical        ReadExit()

    _SET_INTENSITY      Logical        SET INTENSITY

    _SET_SCOREBOARD     Logical        SET SCOREBOARD

    _SET_DELIMITERS     Logical        SET DELIMITERS

    _SET_DELIMCHARS     Character      SET DELIMITERS TO

    _SET_WRAP           Logical        SET WRAP

    _SET_MESSAGE        Numeric        SET MESSAGE

    _SET_MCENTER        Logical        SET MESSAGE

Note: _SET_EXTRAFILE and _SET_SCROLLBREAK have no corresponding commands. _SET_EXTRAFILE lets you specify an additional alternate file, and _SET_SCROLLBREAK lets you toggle the interpretation of Ctrl+S.

Examples

■  In this example a user-defined function preserves or restores
   all global settings.  This function might be used on entry to a
   subsystem to ensure that the subsystem does not affect the state of
   the program that called it:

   #include "Set.ch"
   //

   FUNCTION SetAll( aNewSets )
      LOCAL aCurrentSets[_SET_COUNT], nCurrent
      IF ( aNewSets != NIL )   // Set new and return current
         FOR nCurrent := 1 TO _SET_COUNT
            aCurrentSets[nCurrent] := ;
               Set(nCurrent, aNewSets[nCurrent])
         NEXT
      ELSE         // Just return current
         FOR nCurrent := 1 TO _SET_COUNT
            aCurrentSets[nCurrent] := Set(nCurrent)
         NEXT
      ENDIF
      RETURN (aCurrentSets)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is set.ch.

SetBlink()Harbour implementation


⌃ | ☰

Toggle asterisk (*) interpretation in the SetColor() string between blinking and background intensity

Syntax

SetBlink([<lToggle>]) → lCurrentSetting

Arguments

lToggle changes the meaning of the asterisk (*) character when it is encountered in a SetColor() string. Specifying true (.T.) sets character blinking on, and false (.F.) sets background intensity. The default is true (.T.).

Returns

SetBlink() returns the current setting as a logical value.

Description

SetBlink() is an environment function that toggles the blinking/background intensity attribute and reports the current state of SetBlink(). When SetBlink() is on, characters written to the screen can be made to blink by including an asterisk (*) in a color string passed to SetColor(). When SetBlink() is off, the asterisk (*) causes the background color to be intensified instead. Thus, blinking and background intensity attributes are not available at the same time.

Note: This function is meaningful only on the IBM PC or compatible computers with CGA, EGA, or VGA display hardware.

Examples

■  This example saves the current SetBlink() state before passing
   control to a user-defined function.  Upon return, SetBlink() is
   restored to its original value:

   lOldBlink := SetBlink()
   MyFunc()
   SetBlink(lOldBlink)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SetCancel()Harbour implementation


⌃ | ☰

Toggle Alt+C and Ctrl+Break as program termination keys

Syntax

SetCancel([<lToggle>]) → lCurrentSetting

Arguments

lToggle changes the availability of Alt+C and Ctrl+Break as termination keys. Specifying true (.T.) allows either of these keys to terminate an application and false (.F.) disables both keys. The default is true (.T.).

Returns

SetCancel() returns the current setting as a logical value.

Description

SetCancel() is a keyboard function that toggles the state of the termination keys, Alt+C and Ctrl+Break, and reports the current state of SetCancel(). Use SetCancel() when you want to suppress a user’s ability to terminate a program without using the specified method.

Note that if Alt+C or Ctrl+Break is redefined with SET KEY, the SET KEY definition takes precedence even if SetCancel() returns true (.T.).

Warning! When SetCancel() has been set to false (.F.), the user cannot terminate a runaway program unless you provide an alternative escape mechanism.

Examples

■  This example provides an escape route from a wait state with
   SetCancel() set off:

   #define K_ALTC   302
   //
   SetCancel(.F.)              // Disable termination keys
   SET KEY K_ALTC TO AltC      // Redefine Alt-C
   .
   . <statements>
   .
   RETURN

   FUNCTION AltC
      LOCAL cScreen, nChoice, cLastColor := ;
            SetColor("W/B, N/G")
      //
      SAVE SCREEN TO cScreen
      @ 6, 20 CLEAR TO 9, 58
      @ 6, 20 TO 9, 58 DOUBLE
      @ 7, 26 SAY "Alt-C: Do you want to quit?"
      @ 8, 35 PROMPT " Yes "
      @ 8, 41 PROMPT " No "
      MENU TO nChoice
      SetColor(cLastColor)
      RESTORE SCREEN FROM cScreen
      //
      IF nChoice = 1
         QUIT
      ENDIF
      //
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SetColor()Harbour implementation


⌃ | ☰

Return the current colors and optionally set new colors

Syntax

SetColor([<cColorString>]) → cColorString

Arguments

cColorString is a character string containing a list of color attribute settings for subsequent screen painting. The following is a list of settings and related scopes:

Color Settings

    Setting        Scope

    Standard       All screen output commands and functions

    Enhanced       GETs and selection highlights

    Border         Border around screen, not supported on EGA and VGA

    Background     Not supported

    Unselected     Unselected GETs

Each setting is a foreground and background color pair separated by the slash (/) character and followed by a comma. All settings are optional. If a setting is skipped, its previous value is retained with only new values set. Settings may be skipped within the list or left off the end as illustrated in the examples below.

Returns

SetColor() returns the current color settings as a character string.

Description

SetColor() is a screen function that saves the current color setting or sets new colors for subsequent screen painting. A color string is made from several color settings, each color corresponding to different regions of the screen. As stated above, each setting is made up of a foreground and background color. Foreground defines the color of characters displayed on the screen. Background defines the color displayed behind the character. Spaces and nondisplay characters display as background.

In CA-Clipper, the settings that define color behavior are:

Standard: The standard setting governs all console, full-screen, and interface commands and functions when displaying to the screen. This includes commands such as @...PROMPT, @...SAY, and ?, as well as functions such as AChoice(), dbEdit(), and MemoEdit().

Enhanced: The enhanced setting governs highlighted displays. This includes GETs with INTENSITY ON, and the MENU TO, dbEdit(), and AChoice() selection highlight.

Border: The border is an area around the screen that cannot be written to.

Background: The background is not supported.

Unselected: The unselected setting indicates input focus by displaying the current GET in the enhanced color while other GETs are displayed in the unselected color.

In addition to colors, foreground settings can have high intensity and/or blinking attributes. With a monochrome display, high intensity enhances brightness of painted text. With a color display, high intensity changes the hue of the specified color. For example, «N» displays foreground text as black where «N+» displays the same text as gray. High intensity is denoted by «+». The blinking attribute causes the foreground text to flash on and off at rapid intervals. Blinking is denoted with «*». The attribute character can occur anywhere in the setting string, but is always applied to the foreground color regardless where it occurs. See SetBlink() for additional information.

The following colors are supported:

List of Colors

    Color          Letter    Monochrome

    Black          N, Space  Black

    Blue           B         Underline

    Green          G         White

    Cyan           BG        White

    Red            R         White

    Magenta        RB        White

    Brown          GR        White

    White          W         White

    Gray           N+        Black

    Bright Blue    B+        Bright Underline

    Bright Green   G+        Bright White

    Bright Cyan    BG+       Bright White

    Bright Red     R+        Bright White

    Bright Magenta RB+       Bright White

    Yellow         GR+       Bright White

    Bright White   W+        Bright White

    Black          U         Underline

    Inverse Video  I         Inverse Video

    Blank          X         Blank

Notes

■ Arguments are not specified: Unlike SET COLOR TO, SetColor()

with no argument does not restore colors to their default values.

■ Color numbers: SetColor() supports color letter combinations,

but not color number combinations.

Examples

■  This example assigns the current color setting to the
   variable, cColor:

   cColor:= SetColor()

■  This example uses SetColor() to save the current color setting
   and set a new one.

   cNewColor:= "BR+/N, R+/N"
   cOldColor:= SetColor(cNewColor)

■  This example uses SET COLOR TO to reset the default colors:

   SET COLOR TO
   ? SetColor()            // Result: W/N, N/W, N, N, N/W

■  These two examples specify SetColor() with missing settings:

   // Settings left off the end
   SetColor("W/N, BG+/B")
   //
   // Settings skipped within the list
   SetColor("W/N, BG+/B,,,W/N")

■  This example uses SetColor() with IsColor() to set the colors,
   depending on the screen type:

   FUNCTION DefaultColors
      IF IsColor()
         cForm := "W+/N, BG+/B,,,W/N"
         cDialog := "N/N+, BG+/B,,,N/N+"
         cAlert := "W+/R, BG+/B,,,W+/R"
      ELSE
         cForm := "W+/N, N/W,,,W/N"
         cDialog := "W+/N, N/W,,,W/N"
         cAlert := "W+/N, N/W,,,W/N"
      ENDIF
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SetCursor()Harbour implementation


⌃ | ☰

Set the cursor shape

Syntax

SetCursor([<nCursorShape>]) → nCurrentSetting

Arguments

nCursorShape is a number indicating the shape of the cursor. For simpler coding, the setcurs.ch header file provides descriptive names for the various cursor shapes as shown in the table below:

Cursor Shapes

    Shape               Value     Setcurs.ch

    None                0         SC_NONE

    Underline           1         SC_NORMAL

    Lower half block    2         SC_INSERT

    Full block          3         SC_SPECIAL1

    Upper half block    4         SC_SPECIAL2

Returns

SetCursor() returns the current cursor shape as a numeric value.

Description

SetCursor() is an environment function that controls the shape of the screen cursor. The actual shape is dependent on the current screen driver. The specified shapes appear on IBM PC and compatible computers. On other computers, the appearance may differ for each value specified.

SetCursor(0) is the same as SET CURSOR OFF, and any positive integer value of nCursorShape less than 5 is the same as SET CURSOR ON. The cursor will display as the selected shape.

Examples

■  This example uses SetCursor() to turn on a full block cursor
   for the subsequent READ.  When the READ terminates, SetCursor() turns
   off the cursor:

   #include "Setcurs.ch"
   //
   USE Customer NEW
   @ 10, 10 GET Customer->Name
   @ 11, 10 GET Customer->Phone
   //
   SetCursor(SC_SPECIAL1)        // Change cursor to a block
   READ
   SetCursor(SC_NONE)            // Turn off cursor

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is setcurs.ch.

See also

SetKey()Harbour implementation


⌃ | ☰

Assign an action block to a key

Syntax

SetKey(<nInkeyCode>, [<bAction>]) → bCurrentAction

Arguments

nInkeyCode is the Inkey() value of the key to be associated or queried.

bAction specifies a code block that is automatically executed whenever the specified key is pressed during a wait state.

Returns

SetKey() returns the action block currently associated with the specified key, or NIL if the specified key is not currently associated with a block.

Description

SetKey() is a keyboard function that sets or queries the automatic action associated with a particular key during a wait state. A wait state is any mode that extracts keys from the keyboard except for Inkey(), but including AChoice(), dbEdit(), MemoEdit(), ACCEPT, INPUT, READ and WAIT. Up to 32 keys may be assigned at any one time. At startup, the system automatically assigns the F1 key to execute a procedure or user-defined function named Help.

When an assigned key is pressed during a wait state, the Eval() function evaluates the associated bAction and the parameters, ProcName(), ProcLine(), and ReadVar(). It is, however, not necessary to list arguments when specifying bAction if you do not plan to use them within the action block.

SetKey() is like the SET KEY command which associates a procedure invocation with a key.

Examples

■  This code fragment associates an action block with a key, and
   then, after getting a key using Inkey(), executes it with the Eval()
   function:

   #include "Inkey.ch"
   SetKey(K_DN, {|cProc, nLine, cVar| MyProc(cProc, ;
                     nLine, cVar)})
   .
   . <statements>
   .
   DO WHILE .T.
      nKey := Inkey(0)
      DO CASE
      CASE (bAction := SetKey(nKey)) != NIL
         Eval(bAction, ProcName(), ProcLine(), ReadVar())
      CASE nKey = K_PGUP
         Previous()
      CASE nKey = K_PGDN
         Next()
      CASE nKey = K_ESC
         EXIT
      ENDCASE
   ENDDO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header is inkey.ch.

See also

SetMode()Harbour implementation


⌃ | ☰

Change display mode to a specified number of rows and columns

Syntax

SetMode(<nRows>, <nCols>) → lSuccess

Arguments

nRows is the number of rows in the desired display mode.

nCols is the number of columns in the desired display mode.

Returns

SetMode() returns true (.T.) if the mode change was successful; otherwise, it returns false (.F.).

Description

SetMode() is an environment function that attempts to change the mode of the display hardware to match the number of rows and columns specified. The change in screen size is reflected in the values returned by MaxRow() and MaxCol().

Note: In LLG_VIDEO_TXT mode, and when a VESA driver is present, it is possible to use the following values : 25,80 | 43,80 | 50,80 | 60,80 | 25,132 | 43,132 | 50,132 | 60,132

Examples

■  This example switches to a 43-line display mode:

   IF SetMode(43, 80)
      ? "43-line mode successfully set"
   ELSE
      ? "43-line mode not available"
   ENDIF

■  This example switches the video mode to regular text mode with
   60 rows and 132 columns:

   // Switch to text mode
   SET VIDEOMODE( LLG_VIDEO_TXT )
   // Set the video mode to the largest number of characters
   SetMode( 60,132 )

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SetPos()Harbour implementation


⌃ | ☰

Move the cursor to a new position

Syntax

SetPos(<nRow>, <nCol>) → <nRow>

Arguments

nRow and nCol define the new screen position of the cursor. These values may range from 0, 0 to MaxRow(), MaxCol().

Returns

SetPos() always returns nRow

Description

SetPos() is an environment function that moves the cursor to a new position on the screen. After the cursor is positioned, Row() and Col() are updated accordingly. To control the shape and visibility of the cursor, use the SetCursor() function.

Examples

■  This example moves the cursor to a new position then displays
   a string to the screen using a console command, ??:

   SetPos(1, 1)
   ?? "Hello world"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SetPRC()Harbour implementation


⌃ | ☰

Set PRow() and PCol() values

Syntax

SetPRC(<nRow>, <nCol>) → NIL

Arguments

nRow is the new PRow() value.

nCol is the new PCol() value.

Returns

SetPRC() always returns NIL.

Description

SetPRC() is a printer function that sends control codes to the printer without changing the tracking of the printhead position. When CA-Clipper prints, it updates the PCol() value with the number of characters sent to the printer. There is no discrimination between printable or nonprintable characters. If, for example, a string of ten characters sent to the printer contains two characters interpreted by the printer as a control code, the CA-Clipper PCol() value is incremented by ten, while the true printhead position is moved only by eight. This can lead to alignment problems. Using SetPRC(), you can compensate for control codes by resetting PCol() as shown in the example below.

SetPRC() also suppresses page ejects when printing with @...SAY. This is important when the next row position is smaller than the current row and an EJECT has not been issued. In this situation, CA-Clipper issues an automatic page eject if the next row print position is less than the current PRow() value. Using SetPRC(), you can set PRow() to a number less than the current row, thus suppressing the automatic EJECT.

Examples

■  This user-defined function, PrintCodes(), uses SetPRC() to
   send control codes to the printer without affecting PRow() and PCol()
   values:

   #include "Set.ch"
   #define ITALICS_ON   Chr(27) + "I"
   #define ITALICS_OFF   Chr(27) + "E"
   //
   SET DEVICE TO PRINTER
   @ 12, 10 SAY "This is an"
   @ PRow(), PCol() + 2 SAY PrintCodes(ITALICS_ON) + ;
            "important"
   @ PRow(), PCol() + 2 SAY PrintCodes(ITALICS_OFF) + ;
            "meeting"
   SET DEVICE TO SCREEN
   RETURN

   FUNCTION PrintCodes( cCtrlCode )
      LOCAL nRow, nCol, lPrinter
      lPrinter := Set(_SET_PRINTER, .T.)    // SET PRINTER ON
      nRow:= PRow()                         // Save printhead position
      nCol:= PCol()
      //
      ?? cCtrlCode                          // Send control code
      //
      SetPRC(nRow, nCol)
      Set(_SET_PRINTER, lPrinter)           // Restore printer setting
      RETURN ""                             // Return a null string

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SEEKHarbour implementation⌃ | ☰

Search an order for a specified key value

Syntax

SEEK <expSearch> [SOFTSEEK]

Arguments

expSearch is an expression to match with an order key value.

SOFTSEEK causes the record pointer to be moved to the next record with a higher key value after a failed order search. Default behavior moves the record pointer to Eof() after a failed order search.

Description

SEEK is a database command that searches the controlling order from the first or last key value (depending on whether the LAST keyword is specified) and proceeds until a match is found or there is a key value greater than expSearch. If there is a match, the record pointer is positioned to the identity found in the order. If SOFTSEEK is OFF (the default) and SEEK does not find a match, the record pointer is positioned to LastRec() + 1, Eof() returns true (.T.), and Found() returns false (.F.).

SOFTSEEK enables a method of searching an order 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 order 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. Found() 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.).

SEEK with the SOFTSEEK clause is, effectively, the same as performing SET SOFTSEEK and then SEEK in earlier versions of CA-Clipper except that it does not change the global setting of SOFTSEEK.

Examples

■  The following example searches for "Doe" using the SEEK
   command:

   USE Customer NEW
   SET ORDER TO Customer
   ? Set( _SET_SOFTSEEK )      // (.F.)
   SEEK "Doe"
   ? Set( _SET_SOFTSEEK )      // Still (.F.)
   IF Found()
      .
      . < statements >
      .
   ENDIF

■  The following example performs a soft seek for "Doe" using
   SOFTSEEK clause of the SEEK command:

   USE Customer NEW
   SET ORDER TO Customer
   ? Set( _SET_SOFTSEEK )      // (.F.)
   SEEK "Doe" SOFTSEEK
   ? Set( _SET_SOFTSEEK )      // Still (.F.)
   IF !Found()
      ? Customer->Name         // Returns next logical name after "Doe"
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SELECTHarbour implementation⌃ | ☰

Change the current work area

Syntax

SELECT <xnWorkArea> | <idAlias>

Arguments

xnWorkArea is the work area number between 0 and 250 inclusive. This argument is an extended expression and can be specified either as a literal number or as a numeric expression enclosed in parentheses.

idAlias is the name of an existing work area to SELECT if there is a database file open in that area.

Description

SELECT is a database command that changes work areas. CA-Clipper supports 250 work areas, with each work area a logical handle to an open database file and all of its attributes. You can refer to work areas with SELECT by number or by alias. The alias of a work area is automatically assigned when a database file is USEd in that work area or by using the ALIAS clause.

Work area 0 refers to the first empty or next available work area. Using this, you can SELECT 0 and USE xcDatabase as a method of opening database files.

Notes

■ Aliased expressions: Aliased expressions are a much more

powerful method of selecting new work areas than the SELECT command. Instead of SELECTing a work area, and then performing an operation for that work area, you can apply an alias to an expression that performs the operation. This is done by specifying the alias of the remote work area and the expression enclosed in parentheses. For example, to access the value of Eof() in an unselected work area, you would normally execute a series of statements like the following:

SELECT Remote ? Eof() SELECT Main

Using the aliased expression form, these statements become:

? Remote->(Eof())

USE...NEW: Instead of using SELECT0 and USE xcDatabase to

open a database file in a new work area, the preferred method is to USE xcDatabase NEW.

Examples

■  This example opens a series of database files by SELECTing
   each work area by number then USEing each database file in that work
   area:

   SELECT 1
   USE Customer
   SELECT 2
   USE Invoices
   SELECT 3
   USE Parts
   SELECT Customer

■  A better method is to open each database in the next available
   work area by specifying the NEW clause on the USE command line.  In
   this example USE...NEW is employed instead of SELECT0 and then USE:

   USE Customer NEW
   USE Invoices NEW

   SELECT Customer

■  This code fragment changes work areas while saving the current
   work area name to a variable using the Select() function.  After
   executing an operation for the new work area, the original work area
   is restored:

   nLastArea := Select()
   USE Newfile NEW
   //
   <statements>...
   //
   SELECT (nLastArea)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET ALTERNATEHarbour implementation⌃ | ☰

Echo console output to a text file

Syntax

SET ALTERNATE TO [<xcFile> [ADDITIVE]]
SET ALTERNATE on | OFF | <xlToggle>

Arguments

TO xcFile opens a standard ASCII text file for output with a default extension of .txt. The file name may optionally include an extension, drive letter, and/or path. You may specify xcFile either as a literal file name or as a character expression enclosed in parentheses. Note that if a file with the same name exists, it is overwritten.

ADDITIVE causes the specified alternate file to be appended instead of being overwritten. If not specified, the specified alternate file is truncated before new information is written to it.

ON causes console output to be written to the open text file.

OFF discontinues writing console output to the text file without closing the file.

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 ALTERNATE is a console command that lets you write the output of console commands to a text file. Commands such as LIST, REPORT FORM, LABEL FORM, and ? that display to the screen without reference to row and column position are console commands. Most of these commands have a TO FILE clause that performs the same function as SET ALTERNATE. Full- screen commands such as @...SAY cannot be echoed to a disk file using SET ALTERNATE. Instead you can use SET PRINTER TO xcFile with SET DEVICE TO PRINTER to accomplish this.

SET ALTERNATE has two basic forms. The TO xcFile form creates a DOS text file with a default extension of .txt and overwrites any other file with the same name. Alternate files are not related to work areas with only one file open at a time. To close an alternate file, use CLOSE ALTERNATE, CLOSE ALL, or SET ALTERNATE TO with no argument.

The on|OFF form controls the writing of console output to the current alternate file. SET ALTERNATE ON begins the echoing of output to the alternate file. SET ALTERNATE OFF suppresses output to the alternate file but does not close it.

Examples

■  This example creates an alternate file and writes the results
   of the ? command to the file for each record in the Customer database
   file:

   SET ALTERNATE TO Listfile
   SET ALTERNATE ON
   USE Customer NEW
   DO WHILE !Eof()
      ? Customer->Lastname, Customer->City
      SKIP
   ENDDO
   SET ALTERNATE OFF
   CLOSE ALTERNATE
   CLOSE Customer

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET BELLHarbour implementation⌃ | ☰

Toggle automatic sounding of the bell during full-screen operations

Syntax

SET BELL on | OFF | <xlToggle>

Arguments

ON enables the BELL.

OFF disables the BELL.

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 BELL is an environment command that toggles the sound of the bell. If SET BELL is ON, the bell sounds in the following situations:

■ The user enters a character at the last position in a GET.

■ The user attempts to enter invalid data into a GET. The data

is validated by the data type of the GET variable, the PICTURE template, and by the RANGE clause. Violating a VALID condition does not sound the bell, regardless of the SET BELL status.

To sound the bell explicitly, you can use either ?? Chr(7) or the Tone() function. Tone() is perhaps more useful since you can vary both the pitch and duration of the sound.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET CENTURYHarbour implementation⌃ | ☰

Modify the date format to include or omit century digits

Syntax

SET CENTURY on | OFF | <xlToggle>

Arguments

ON allows input and display of the century digits for dates.

OFF suppresses the input and display of the century digits for dates.

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 CENTURY modifies the current date format as set by SET DATE. SET CENTURY ON changes the date format to contain four digits for the year. With the date format set to four digits for the year, date values display with a four-digit year, and dates of any century can be input.

SET CENTURY OFF changes the date format to contain only two digits for the year. With the date format set to only two digits for the year (CENTURY OFF), the century digits of dates are not displayed and cannot be input.

Note that only the display and input format of dates is affected; date calculations maintain the century information regardless of the date format.

CA-Clipper supports all dates in the range 01/01/0100 to 12/31/2999.

Examples

■  This example shows the results of a simple SET CENTURY
   command:

   SET CENTURY OFF
   ? Date()                  // Result: 09/15/90
   SET CENTURY ON
   ? Date()                  // Result: 09/15/1990

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET COLOR*Harbour implementation⌃ | ☰

Define screen colors

Syntax

SET COLOR | COLOUR TO [[<standard>]
   [,<enhanced>] [,<border>] [,<background>]
   [,<unselected>]] | (<cColorString>)

Arguments

standard is the color that paints all console, full-screen, and interface commands and functions when displaying to the screen. This includes commands such as @...PROMPT, @...SAY, and ?; as well as functions such as AChoice(), dbEdit(), and MemoEdit().

enhanced is the color that paints highlighted displays. This includes GETs with INTENSITY ON, the MENU TO, dbEdit(), and AChoice() selection highlight.

border is the color that paints the area around the screen that cannot be written to.

background is not currently supported by any machines for which Computer Associates provides drivers. This setting is supplied for compatibility purposes only.

unselected is a color pair that provides input focus by displaying the current GET in the enhanced color while other GETs are displayed in this color.

cColorString is a character string enclosed in parentheses containing the color settings. This facility lets you specify the color settings as an expression in place of a literal string or macro variable.

SET COLOR TO with no argument restores the default colors to W/N, N/W, N, N, N/W.

Description

SET COLOR, a command synonym for the SetColor() function, defines colors for subsequent screen painting activity. Each SET COLOR command specifies a list of color settings for the five types of screen painting activity. Each setting is a foreground and background color pair separated by the slash (/) character. Foreground defines the color of characters displayed on the screen. Background defines the color displayed behind the character. Spaces and nondisplay characters display as background only.

In addition to color, a foreground setting can have an attribute, high intensity or blinking. With a monochrome display, high intensity enhances brightness of painted text. With a color display, high intensity changes the hue of the specified color making it a different color. For example, N displays foreground text as black where N+ displays the same text as gray. High intensity is denoted by +. The blinking attribute causes the foreground text to flash on and off at a rapid interval. Blinking is denoted with *. An attribute character can occur anywhere in a setting, but is always applied to the foreground color regardless where it occurs.

Each color can be specified using either a letter or a number, but numbers and letters cannot be mixed within a setting. Note that numbers are supplied for compatibility purposes and are not recommended.

All settings are optional. If a setting is skipped, its previous value is retained with only new values set. Skipping a foreground or background color within a setting sets the color to black.

The following colors are supported:

Color Table

    Color          Letter    Number  Monochrome

    Black          N, Space  0       Black

    Blue           B         1       Underline

    Green          G         2       White

    Cyan           BG        3       White

    Red            R         4       White

    Magenta        RB        5       White

    Brown          GR        6       White

    White          W         7       White

    Gray           N+        8       Black

    Bright Blue    B+        9       Bright Underline

    Bright Green   G+        10      Bright White

    Bright Cyan    BG+       11      Bright White

    Bright Red     R+        12      Bright White

    Bright Magenta RB+       13      Bright White

    Yellow         GR+       14      Bright White

    Bright White   W+        15      Bright White

    Black          U                 Underline

    Inverse Video  I                 Inverse Video

    Blank          X                 Blank

SET COLOR is a compatibility command and is not recommended. It is superseded by the SetColor() function which can return the current color as well as set a new color.

Notes

■ Monochrome monitors: Color is not supported on monochrome

monitors. CA-Clipper, however, supports the monochrome attributes inverse video (I) and underlining (U).

■ Screen drivers: SET COLOR TO, using numbers, may not be

supported by screen drivers other than the default screen driver.

Examples

■  This example uses the unselected setting to make the current
   GET red on white while the rest are black on white:

   cColor:= "W/N,R/W,,,N/W"
   SET COLOR TO (cColor)
   cOne := cTwo := Space(10)
   @ 1, 1 SAY "Enter One: " GET cOne
   @ 2, 1 SAY "Enter Two: " GET cTwo
   READ

■  In this example a user-defined function gets a password from
   the user using the blank (X) enhanced setting to hide the password as
   the user types:

   IF !DialogPassWord(12, 13, "W+/N", "FUNSUN", 3)
      ? "Sorry, your password failed"
      QUIT
   ENDIF

   FUNCTION DialogPassWord( nRow, nCol, ;
          cStandard, cPassword, nTries )
      LOCAL nCount := 1, cColor := SetColor()
      SET COLOR TO (cStandard + ", X")      // Blank input
      //
      DO WHILE nCount < nTries
         cUserEntry:= Space(6)
         @ nRow, nCol SAY  "Enter password: " GET ;
                  cUserEntry
         READ
         //
         IF LastKey() == 27
            SET COLOR TO (cColor)
            RETURN .F.

         ELSEIF cUserEntry == cPassword
            SET COLOR TO (cColor)
            RETURN .T.
         ELSE
            nCount++
         ENDIF
      ENDDO
      //
      SET COLOR TO (cColor)
      RETURN .F.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET CONFIRMHarbour implementation⌃ | ☰

Toggle required exit key to terminate GETs

Syntax

SET CONFIRM on | OFF | <xlToggle>

Arguments

ON requires the user to press an exit key to leave a GET.

OFF allows the user to leave a GET by typing past the end without pressing an exit key.

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 CONFIRM determines whether an exit key is required to leave a GET. If CONFIRM is OFF, the user can type past the end of a GET and the cursor will move to the next GET, if there is one. If there is not another GET, the READ terminates. If, however, CONFIRM is ON, an exit key must be pressed to leave the current GET.

In all cases, attempting to leave the current GET executes the RANGE or VALID clauses, unless the user presses the Esc key.

See @...GET for more information on the behavior of GETs.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET CONSOLEHarbour implementation⌃ | ☰

Toggle console display to the screen

Syntax

SET CONSOLE ON | off | <xlToggle>

Arguments

ON displays the output of console commands on the screen.

OFF suppresses the screen display of console commands.

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 CONSOLE determines whether or not console commands send output to the screen. Console commands are commands that display to the screen without reference to row and column position. In addition to sending output to the screen, console commands can simultaneously send output to the printer and/or a DOS text file. Output is sent to the printer using the TO PRINTER clause common to many console commands, or with the SET PRINTER ON command. Output is sent to a file using the TO FILE clause, SET ALTERNATE, or SET PRINTER TO.

With CONSOLE ON, console commands display to the screen. With CONSOLE OFF, the screen display of console commands is suppressed, but the echoing of output to either a file or the printer is unaffected. This lets you send the output of console commands such as REPORT and LABEL FORM to the printer without the screen display—a common occurrence.

Notes

■ Keyboard input: For console commands that accept input

(including ACCEPT, INPUT, and WAIT), SET CONSOLE affects the display of the prompts as well as the input areas. As a consequence, a SET CONSOLE OFF before one of these commands will not only prevent you from seeing what you type, but will also prevent the display of the message prompt.

■ Full-screen commands: Full-screen commands such as @...SAY

display to the screen independent of the current CONSOLE SETting. For this category of output commands, device control is performed using SET DEVICE to control whether output goes to the screen or printer, and SET PRINTER TO echo output to a file.

Examples

■  This example uses REPORT FORM to output records to the printer
   while suppressing output to the screen:

   USE Sales NEW
   SET CONSOLE OFF
   REPORT FORM Sales TO PRINTER

   SET CONSOLE ON

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET CURSORHarbour implementation⌃ | ☰

Toggle the screen cursor on or off

Syntax

SET CURSOR ON | off | <xlToggle>

Arguments

ON enables the cursor display.

OFF disables the cursor display.

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 CURSOR toggles the screen cursor on or off. When the CURSOR is OFF, keyboard entry and screen display are unaffected. The cursor is merely hidden and data entry may still be accomplished without the cursor being visible. Row() and Col() are updated as if the cursor were visible.

This command suppresses the cursor while the screen is being painted. Ideally, the only time the cursor shows in a production program is when the user is editing GETs, MemoEdit(), or some kind of line edit.

Examples

■  This example shows a typical use of SET CURSOR:

   LOCAL lAnswer := .F.
   @ 24, 0
   @ 24, 15 SAY "Do you want to QUIT? [Y/N]";
      GET lAnswer;
      PICTURE "Y"
   SET CURSOR ON
   READ
   SET CURSOR OFF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET DATEHarbour implementation⌃ | ☰

Set the date format for input and display

Syntax

SET DATE FORMAT [TO] <cDateFormat>
SET DATE [TO] AMERICAN | ansi | British | French
   | German | Italian | Japan | USA

Arguments

cDateFormat is a character expression that directly specifies the date format when the FORMAT clause is specified. cDateFormat must evaluate to a string of 12 or fewer characters.

When specified, cDateFormat is analyzed to determine the proper placement and number of digits for the day, month, and year. The position of the day, month, and year digits is determined by scanning the string for one or more occurrences of the letters d, m, and y, respectively. Other characters in the string are copied verbatim into displayed date values.

When FORMAT is not used, one of several keywords describes the date format. The following table shows the format for each keyword setting:

SET DATE Formats

    SETting   Format

    AMERICAN  mm/dd/yy

    ANSI      yy.mm.dd

    BRITISH   dd/mm/yy

    FRENCH    dd/mm/yy

    GERMAN    dd.mm.yy

    ITALIAN   dd-mm-yy

    JAPAN     yy/mm/dd

    USA       mm-dd-yy

Description

SET DATE is an environment command that sets the display format for date values. SET DATE is a global setting that affects the behavior of dates throughout a program, allowing you to control date formatting in a way that facilitates porting applications to foreign countries.

Examples

■  In this example the FORMAT clause directly specifies the date
   format:

   SET DATE FORMAT "yyyy:mm:dd"

■  This example configures the date setting at runtime by passing
   a DOS environment variable to the program, retrieving its value with
   GetEnv(), and setting DATE with the retrieved value:

   C>SET CLIP_DATE=dd/mm/yy

   In the configuration section of the application program, the date
   format is set like this:

   FUNCTION AppConfig
      SET DATE FORMAT TO GetEnv("CLIP_DATE")
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET DECIMALSHarbour implementation⌃ | ☰

Set the number of decimal places to be displayed

Syntax

SET DECIMALS TO [<nDecimals>]

Arguments

TO nDecimals is the number of decimal places to be displayed. The default value is two.

SET DECIMALS TO with no argument is equivalent to SET DECIMALS TO 0.

Description

SET DECIMALS determines the number of decimal places displayed in the results of numeric functions and calculations. Its operation depends directly on the FIXED setting. If FIXED is OFF, SET DECIMALS establishes the minimum number of decimal digits displayed by Exp(), Log(), Sqrt(), and division operations. If FIXED is ON, all numeric values are displayed with exactly the number of decimal places specified by SET DECIMALS. Note that neither SET DECIMALS nor SET FIXED affects the actual numeric precision of calculations—only the display format is affected.

To provide finer control of numeric display, you can use the PICTURE clause of @...SAY, @...GET, and the Transform() function.

Examples

■  These examples show various results of the SET DECIMALS
   command:

   SET FIXED ON
   SET DECIMALS TO 2            // The default setting
   ? 2/4                        // Result: 0.50
   ? 1/3                        // Result: 0.33
   SET DECIMALS TO 4
   ? 2/4                        // Result: 0.5000

   ? 1/3                        // Result: 0.3333

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET DEFAULTHarbour implementation⌃ | ☰

Set the CA-Clipper default drive and directory

Syntax

SET DEFAULT TO [<xcPathspec>]

Arguments

TO xcPathspec identifies a disk drive and the directory as the default and can be specified either as a literal path specification or as a character expression enclosed in parentheses. If you specify both a drive and directory, a colon must be included after the drive letter.

SET DEFAULT TO specified without an argument defaults to the current DOS drive and directory.

Description

SET DEFAULT sets the drive and directory where the application program creates and saves files, with the exception of temporary files and files created with the low-level file functions.

SET DEFAULT does not change the DOS drive and directory. When attempting to access files, the DEFAULT drive and directory are searched first. To set additional search paths for file access, use SET PATH.

Notes

■ Initial Default: When a CA-Clipper program starts, the default

drive and directory are the current DOS drive and directory. Within the program, you can change this with SET DEFAULT.

■ Running external programs: Executing a RUN command accesses

the current DOS drive and directory.

Examples

■  This example shows a typical use of SET DEFAULT:

   SET PATH TO
   ? FILE("Sales.dbf")      // Result: .F.
   //
   SET DEFAULT TO C:CLIPPERFILES
   ? FILE("Sales.dbf")      // Result: .T.
   //
   SET DEFAULT TO C:        // Change default drive
   SET DEFAULT TO          // Change to root directory

   SET DEFAULT TO ..        // Change to parent directory

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET DELETEDHarbour implementation⌃ | ☰

Toggle filtering of deleted records

Syntax

SET DELETED on | OFF | <xlToggle>

Arguments

ON ignores deleted records.

OFF processes deleted records.

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 DELETED toggles automatic filtering of records marked for deletion in all work areas. When SET DELETED is ON, most commands ignore deleted records. If, however, you refer to a record by record number (GOTO or any command that supports the RECORD scope), the record is not ignored even if marked for deletion. Additionally, SET DELETED ON has no affect on INDEX or REINDEXing.

RECALL ALL honors SET DELETED and does not recall any records.

Notes

■ Filtering deleted records in a single work area: To confine

the filtering of deleted records to a particular work area, SELECT the work area, and then SET FILTER TO Deleted().

Examples

■  This example illustrates the effect of using SET DELETED:

   USE Sales NEW
   ? LastRec()                  // Result: 84
   //
   DELETE RECORD 4
   COUNT TO nCount
   ? nCount                     // Result: 84
   //
   SET DELETED ON
   COUNT TO nCount
   ? nCount                     // Result: 83

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET DELIMITERSHarbour implementation⌃ | ☰

Toggle or define GET delimiters

Syntax

SET DELIMITERS on | OFF | <xlToggle>
SET DELIMITERS TO [<cDelimiters> | DEFAULT]

Arguments

ON displays delimiters for GET variables.

OFF suppresses the delimiter display.

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.

TO cDelimiters defines a one or two character delimiter. Specifying a single character uses the same character as both the beginning and ending delimiter. Specifying two characters uses the first as the beginning delimiter and the second as the ending delimiter.

TO DEFAULT or no delimiters SETs the delimiters to colons which are the default delimiters.

Description

SET DELIMITERS is a dual purpose command that both defines characters used to delimit GETs and toggles the automatic display of delimiters ON or OFF. The @...GET command can display delimiters that surround a Get object’s display. If DELIMITERS is ON, the delimiters add two characters to the length of the Get object display.

You can configure the delimiter characters using the TO cDelimiters clause. The DEFAULT delimiter character is the colon (:). When specifying delimiters, the beginning and ending delimiter characters can be different. If you wish to suppress either the right, left, or both delimiters, use a space instead of the delimiter character.

Typically, delimiters are unnecessary since GETs display in reverse video or enhanced color if INTENSITY is ON.

Examples

■  This example SETs DELIMITERS TO a colon and a space for the
   first GET and the square bracket characters for the second:

   LOCAL cVar := Space(5), cVar2 := Space(5)
   SET DELIMITERS ON

   SET DELIMITERS TO ": "
   @ 1, 0 SAY "Enter" GET cVar
   SET DELIMITERS TO "[]"
   @ 2, 0 SAY "Enter" GET cVar2
   READ

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET DESCENDINGHarbour implementation⌃ | ☰

Change the descending flag of the controlling order

Syntax

SET DESCENDING ON | OFF | (<lToggle>)

Arguments

ON enables the descending flag.

OFF disables the descending flag.

lToggle 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.

Note: The initial default of this setting depends on whether the controlling order was created with DESCENDING as an attribute.

Description

SET DESCENDING is functionally equivalent to ordDescend(). Refer to this function for more information.

Examples

■  The following example illustrates SET DESCENDING.  every order
   can be both ascending and descending:

   USE Customer VIA "DBFCDX"
   INDEX ON LastName TAG Last
   INDEX ON FirstName TAG First DESCENDING

   SET ORDER TO TAG Last
   // last was originally created in ascending order

   // Swap it to descending
   SET DESCENDING ON
   // Last will now be processed in descending order

   SET ORDER TO TAG First
   // First was originally created in descending order


   // Swap it to ascending
   SET DESCENDING OFF
   // First will now be processed in ascending order

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET DEVICEHarbour implementation⌃ | ☰

Direct @…SAYs to the screen or printer

Syntax

SET DEVICE TO SCREEN | printer

Arguments

TO SCREEN directs all @...SAYs to the screen and is independent of the SET PRINTER and CONSOLE settings.

TO PRINTER directs all @...SAYs to the device set with SET PRINTER TO. This can include a local printer port, a network spooler, or a file.

Description

SET DEVICE directs the output of @...SAY commands to either the screen or the printer. When DEVICE is SET TO PRINTER, @...SAY commands are sent to the printer and not echoed to the screen. In addition, @...SAY commands observe the current SET MARGIN value.

When sending @...SAYs to the printer, CA-Clipper performs an automatic EJECT whenever the current printhead row position is less than the last print row position. An EJECT resets PCol() and PRow() values to zero. To reset PCol() and PRow() to new values, use the SetPRC() function.

To send @...SAYs to a file, use SET PRINTER TO xcFile with SET DEVICE TO PRINTER.

Examples

■  This example directs @...SAYs to the printer:

   SET DEVICE TO PRINTER
   @ 2,10 SAY "Hello there"
   EJECT

■  This example directs @...SAYs to a file:

   SET PRINTER TO Output.txt
   SET DEVICE TO PRINTER
   @ 10, 10 SAY "File is: Output.txt"
   @ 11, 10 SAY Date()
   SET PRINTER TO            // Close the output file

   SET DEVICE TO SCREEN

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET EPOCHHarbour implementation⌃ | ☰

Control the interpretation of dates with no century digits

Syntax

Arguments

TO nYear specifies the base year of a 100-year period in which all dates containing only two year digits are assumed to fall.

Description

SET EPOCH is an environment command that determines the interpretation of date strings containing only two year digits. When such a string is converted to a date value, its year digits are compared with the year digits of nYear. If the year digits in the date are greater than or equal to the year digits of nYear, the date is assumed to fall within the same century as nYear. Otherwise, the date is assumed to fall in the following century.

The default value for SET EPOCH is 1900, causing dates with no century digits to be interpreted as falling within the twentieth century.

CA-Clipper supports all dates in the range 01/01/0100 to 12/31/2999.

Examples

■  This example shows the effects of SET EPOCH:

   SET DATE FORMAT TO "mm/dd/yyyy"
   ? CToD("05/27/1904")            // Result: 05/27/1904
   ? CToD("05/27/67")              // Result: 05/27/1967
   ? CToD("05/27/04")              // Result: 05/27/1904
   //
   SET EPOCH TO 1960
   ? CToD("05/27/1904")            // Result: 05/27/1904
   ? CToD("05/27/67")              // Result: 05/27/1967
   ? CToD("05/27/04")              // Result: 05/27/2004

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET ESCAPEHarbour implementation⌃ | ☰

Toggle Esc as a READ exit key

Syntax

SET ESCAPE ON | off | <xlToggle>

Arguments

ON enables Esc as a READ exit key.

OFF disables Esc as a READ exit key.

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

If SET ESCAPE is ON, Esc terminates the current READ. Any changes made to the current Get object are lost, and validation with RANGE or VALID is bypassed. When SET ESCAPE is OFF and the user presses Esc, the key press is ignored. With SET KEY, however, you can reassign Esc for special handling, regardless of the status of SET ESCAPE.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET EVENTMASKHarbour implementation⌃ | ☰

Specify events to be returned by the Inkey() function

Syntax

SET EVENTMASK TO <nEventMask>

Arguments

nEventMask specifies which events should be returned by the Inkey() function. This argument can be any combination of the following values which are defined in inkey.ch:

Inkey Constants

    Constant       Value     Description

    INKEY_MOVE     1         Mouse Events

    INKEY_LDOWN    2         Mouse Left Click Down

    INKEY_LUP      4         Mouse Left Click Up

    INKEY_RDOWN    8         Mouse Right Click Down

    INKEY_RUP      16        Mouse Right Click Up

    INKEY_KEYBOARD 128       Keyboard Events

    INKEY_ALL      159       All Mouse and Keyboard Events

If a value is not specified for SET EVENTMASK, the default value of 128 (keyboard events only) will be used.

Description

The SET EVENTMASK command specifies which events should be returned by the Inkey() function. Using this mask you can have Inkey() return only the events in which you are interested.

Examples

The following example will inform Inkey() to terminate if a keyboard
event occurs or the left mouse button has been clicked.  If no events
occur within 5 seconds, Inkey() will terminate.

   SET EVENTMASK TO INKEY_KEYBOARD + INKEY_LDOWN
   ? Inkey( 5 )

Platforms

Available on MS-DOS

See also

SET EXACT*Harbour implementation⌃ | ☰

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 CA-Clipper, 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.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET EXCLUSIVE*Harbour implementation⌃ | ☰

Establish shared or exclusive USE of database files

Syntax

SET EXCLUSIVE ON | off | <xlToggle>

Arguments

ON causes database files to be opened in exclusive (nonshared) mode.

OFF causes database files to be opened in shared mode.

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

In a network environment, SET EXCLUSIVE determines whether a USE command specified without the EXCLUSIVE or SHARED clause automatically opens database, memo, and index files EXCLUSIVE. When database files are opened EXCLUSIVE, other users cannot USE them until they are CLOSEd. In this mode, file and record locks are unnecessary.

When EXCLUSIVE is ON (the default), all database and associated files open in a nonshared (exclusive) mode unless the USE command is specified with the SHARED clause. Use EXCLUSIVE only for operations that absolutely require EXCLUSIVE USE of a database file, such as PACK, REINDEX, and ZAP.

When EXCLUSIVE is OFF, all files are open in shared mode unless the USE command is specified with the EXCLUSIVE clause. Control access by other users programmatically using RLock() and FLock().

SET EXCLUSIVE is a compatibility command and not recommended. It is superseded by the EXCLUSIVE and SHARED clauses of the USE command.

Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Notes

■ Error handling: Attempting to USE a database file already

opened EXCLUSIVE by another user generates a runtime error and sets NetErr() to true (.T.). After control returns to the point of error, you can test NetErr() to determine whether the USE failed.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET FILTERHarbour implementation⌃ | ☰

Hide records not meeting a condition

Syntax

SET FILTER TO [<lCondition>]

Arguments

TO lCondition is a logical expression that defines a specific set of current work area records accessible for processing.

SET FILTER TO without an argument deactivates the filter condition.

Description

When a FILTER condition is SET, the current work area acts as if it contains only the records that match the specified condition. A filter condition is one of the properties of a work area. Once a FILTER has been SET, the condition can be returned as a character string using the dbFilter() function.

Most commands and functions that move the record pointer honor the current filter with the exception of those commands that access records by record number. This includes GOTO, commands specified with the RECORD clause, and RELATIONs linked by numeric expression to a work area with no active index.

Once a FILTER is SET, it is not activated until the record pointer is moved from its current position. You can use GO TOP to activate it.

As with SET DELETED, a filter has no effect on INDEX and REINDEX.

Note: Although SET FILTER makes the current work area appear as if it contains a subset of records, it, in fact, sequentially processes all records in the work area. Because of this, the time required to process a filtered work area will be the same as an unfiltered work area.

Examples

■  This example filters Employee.dbf to only those records where
   the age is greater than 50:

   USE Employee INDEX Name NEW
   SET FILTER TO Age > 50
   LIST Lastname, Firstname, Age, Phone
   SET FILTER TO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET FIXEDHarbour implementation⌃ | ☰

Toggle fixing of the number of decimal digits displayed

Syntax

SET FIXED on | OFF | <xlToggle>

Arguments

ON fixes the decimal places display at the number of digits specified by SET DECIMALS.

OFF allows the operation or function to determine the number of decimal places to display.

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 FIXED toggles control of the display of decimal digits by the current DECIMALS setting. When FIXED is ON, display of all numeric output is fixed at the DECIMALS setting (two places if the SET DECIMALS default value is in effect). When FIXED is OFF, numeric output displays according to the default rules for numeric display. These are described in the «Basic Concepts» chapter of the Programming and Utilities Guide.

Note that SET FIXED and SET DECIMALS affect only the display format of numeric values and not the actual numeric precision of calculations.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET FORMAT*Harbour implementation⌃ | ☰

Activate a format when READ is executed

Syntax

SET FORMAT TO [<idProcedure>[.<ext>]]

Arguments

TO idProcedure is a format (.fmt) file, a program (.prg) file, or a procedure.

ext is the extension of the format file. If not specified, the default extension is (.fmt).

SET FORMAT TO with no argument deactivates the current format.

Description

SET FORMAT defines a procedure to execute when a READ is invoked. Unlike the interpreted environment, formats are not opened and executed at runtime. Instead, the CA-Clipper compiler treats SET FORMAT the same as a DO command. The compiler first looks to see whether it has already compiled a procedure with the same name as idProcedure. If it has, it uses that procedure for the reference. If idProcedure is not found, the compiler looks to disk for a file with the same name. If this file is not found, an external reference is generated that must be resolved at link time.

SET FORMAT is a compatibility command and not recommended.

Notes

■ Active format procedures: Unlike other dialects where each

work area can have an active format, CA-Clipper supports only one active format procedure for all work areas.

■ Screen CLEARing: CA-Clipper does not clear the screen when a

format procedure is executed.

■ Legal statements: Format procedures allow statements and

commands in addition to @...SAY and @...GET.

■ Multiple pages: CA-Clipper does not support multiple-page

format procedures.

Examples

■  This example uses a format procedure to add records to a
   database file until the user presses Esc:

   USE Sales NEW
   SET FORMAT TO SalesScr
   DO WHILE LastKey() != 27
      APPEND BLANK
      READ
   ENDDO
   RETURN

   PROCEDURE SalesScr
      @ 12, 12 SAY "Branch     : " GET  Branch
      @ 13, 12 SAY "Salesman   : " GET  Salesman
      RETURN

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET FUNCTIONHarbour implementation⌃ | ☰

Assign a character string to a function key

Syntax

SET FUNCTION <nFunctionKey> TO <cString>

Arguments

nFunctionKey is the number of the function key to receive the assignment.

TO cString specifies the character string to assign to nFunctionKey.

Description

SET FUNCTION assigns a character string to a function key numbered between 1 and 40 inclusive. When the user presses the assigned function key, cString is stuffed into the keyboard buffer. cString can include control characters, such as a Ctrl+C or Ctrl+S to perform navigation or editing actions in a wait state.

List of Function Key Mappings

    Function Key      Actual Key

    1 — 10            F1 — F10

    11 — 20           Shift+F1 — Shift+F10

    21 — 30           Ctrl+F1 — Ctrl+F10

    31 — 40           Alt+F1 — Alt+F10

Warning! In CA-Clipper, SET FUNCTION is preprocessed into SET KEY and KEYBOARD commands. This means that SET FUNCTION has the effect of clearing any SET KEY for the same key number and vice versa. This is incompatible with previous releases, which maintained separate lists of SET FUNCTION keys and SET KEY keys.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET INDEXHarbour implementation⌃ | ☰

Open one or more order bags in the current work area

Syntax

SET INDEX TO [<xcOrderBagName list>] [ADDITIVE]

Arguments

cOrderBagName list specifies order bags to be emptied into the order list of the current work area.

ADDITIVE adds order bags to an existing order list.

Description

By default, SET INDEX, without the ADDITIVE clause, clears the currently active order list, and then constructs a new order list from the orders in the specified order bags in the current work area. When several order bags are opened, the first order in the first order bag becomes the controlling order (has focus). The record pointer is initially positioned at the first logical identity in this order.

If an order list exists when you SET INDEXADDITIVE, the orders in the new order bag are added to the end of the order list. The previous controlling order continues to be the controlling order.

If no order list exists when you SET INDEXADDITIVE, the first order in the first order bag in cOrderBagName list becomes the controlling order.

During database processing, all open orders are updated whenever a key value is appended or changed, unless the order was created using a scoping condition and the key value does not match. To change the controlling order without issuing another SET INDEX command, use SET ORDER or ordSetFocus(). To add orders without closing the currently open orders, use the ADDITIVE clause.

Examples

■  This example opens a database and its associated indexes:

   USE Sales NEW
   SET INDEX TO Sales, Sales1, Sales2

■  This example opens an index without closing any indexes that
   are already open:

   SET INDEX TO Sales3 ADDITIVE

Platforms

Available on MS-DOS

See also

SET INTENSITYHarbour implementation⌃ | ☰

Toggle enhanced display of GETs and PROMPTs

Syntax

SET INTENSITY ON | off | <xlToggle>

Arguments

ON enables both standard and enhanced display colors.

OFF disables enhanced display color. All screen output then uses the current standard color.

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 INTENSITY toggles the display of GETs and menu PROMPTs between enhanced and standard color settings. When INTENSITY is OFF, GETs and SAYs appear in the standard color setting. When INTENSITY is ON, GETs appear in the enhanced color setting.

When INTENSITY is OFF, all menu PROMPTs appear in the standard color setting, and the cursor appears at the current PROMPT. If INTENSITY is ON (the default), the current PROMPT appears in the enhanced color setting, and the cursor is hidden.

Note that INTENSITY has no effect on AChoice() or dbEdit().

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET KEYHarbour implementation⌃ | ☰

Assign a procedure invocation to a key

Syntax

SET KEY <nInkeyCode> TO [<idProcedure>]

Arguments

nInkeyCode is the Inkey() value of the key that receives the assignment.

TO idProcedure specifies the name of a procedure that executes when the user presses the assigned key. If idProcedure is not specified, the current nInkeyCode definition is released.

Description

SET KEY is a keyboard command that allows a procedure to be executed from any wait state when a designated key is pressed. A wait state is any mode that extracts keys from the keyboard except for Inkey(). These modes include AChoice(), dbEdit(), MemoEdit(), ACCEPT, INPUT, READ and WAIT. After a key is redefined, pressing it executes the specified procedure, passing three automatic parameters corresponding to ProcName(), ProcLine(), and ReadVar(). The procedure and variable parameters are character data type, while the line number is numeric data type.

You may define a maximum of 32 keys at one time. At startup, the system automatically defines the F1 key to execute Help. If a procedure with this name is linked into the current program and it is visible, pressing F1 from a wait state invokes it.

Note that SET KEY procedures should preserve the state of the application (i.e., screen appearance, current work area, etc.) and restore it before exiting.

Warning! In CA-Clipper, SET FUNCTION is preprocessed into the SET KEY and KEYBOARD commands. This means that SET FUNCTION has the effect of clearing any SET KEY for the same key number and vice versa. This is incompatible with previous releases, which maintained separate lists of SET FUNCTION keys and SET KEY keys.

Notes

■ Precedence: SET KEY definitions take precedence over SET

ESCAPE and SetCancel().

CLEAR with a SET KEY procedure: Do not use CLEAR to clear the

screen within a SET KEY procedure since it also CLEARs GETs and, therefore, terminates READ. When you need to clear the screen, use CLEAR SCREEN or CLS instead.

■ Terminating a READ from a SET KEY procedure: The following

table illustrates several ways to terminate a READ from within a SET KEY procedure.

Terminating a READ from a SET KEY Procedure

       Command             Action

       CLEAR GETS          Terminates READ without saving current GET

       BREAK               Terminates READ without saving current GET

       KEYBOARD Ctrl-W     Terminates READ and saves the current GET

       KEYBOARD Esc        Terminates READ without saving current GET

Examples

■  This example uses SET KEY to invoke a procedure that presents
   a picklist of account identification numbers when the user presses F2
   while entering data into the account identification field:

   #include   "Inkey.ch"
   //
   SET KEY K_F2 TO ScrollAccounts
   USE Accounts NEW
   USE Invoices NEW
   @ 10, 10 GET Invoices->Id
   READ
   RETURN

   PROCEDURE ScrollAccounts( cProc, nLine, cVar )
      IF cVar = "ID"
         SAVE SCREEN
         Accounts->(dbEdit(10, 10, 18, 40, {"Company"}))
         KEYBOARD CHR(K_CTRL_Y) + Accounts->Id + ;
                  Chr(K_HOME)
         RESTORE SCREEN
      ELSE
         Tone(100, 2)
      ENDIF
      RETURN

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB, header file is inkey.ch.

See also

SET MARGINHarbour implementation⌃ | ☰

Set the page offset for all printed output

Syntax

SET MARGIN TO [<nPageOffset>]

Arguments

TO nPageOffset is a positive number that defines the number of column positions to indent from the left side of the page for subsequent printed output. A negative value resets the MARGIN to zero.

SET MARGIN TO with no argument resets the page offset to zero, the default value.

Description

SET MARGIN is valid for all output directed to the printer from console commands and @...SAY. With console output, the nPageOffset indent is output whenever there is a new line. With @...SAY, nPageOffset is added to each column value. SET MARGIN has no effect on screen output.

Note: Printing with @...SAY and PCol() with a MARGIN SET in most cases adds the MARGIN to each column position. This happens because PCol() accurately reflects the print column position including the last nPageOffset output. The best approach is to avoid the use of SET MARGIN with PCol() for relative column addressing.

Examples

■  This example sets a page offset of 5, and then prints a list
   from Sales.dbf:

   USE Sales NEW
   SET MARGIN TO 5
   LIST Branch, Salesman TO PRINTER
   SET MARGIN TO

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET MEMOBLOCKHarbour implementation⌃ | ☰

Change the block size for memo files

Syntax

Arguments

nSize is the memo file block size. The initial memo file block size depends on the RDD. For most drivers that support the .dbt memo file format, it is 512 bytes. However, if you are using BLOB files (.dbv memo file format) via inheritance from the DBFMEMO driver, the default is 1.

Description

SET MEMOBLOCK is functionally equivalent to calling dbInfo(DBI_MEMOBLOCKSIZE, nSize). Refer to this function for more information. SET MEMOBLOCK sets the block size for the memo file associated with the database.

Examples

■  The following example illustrates the SET MEMOBLOCK command:

   USE Inventor NEW
   SET MEMOBLOCK TO 256
   ? dbInfo(DBI_MEMOBLOCKSIZE)         // Result: 256

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET MESSAGEHarbour implementation⌃ | ☰

Set the @…PROMPT message line row

Syntax

SET MESSAGE TO [<nRow> [CENTER | CENTRE]]

Arguments

TO nRow specifies the message row position.

CENTER | CENTRE centers the message on the specified row.

Specifying SET MESSAGE TO 0 or SET MESSAGE TO without an argument suppresses the display of messages.

Description

SET MESSAGE is a menu command that defines the screen row where the @...PROMPT messages display. When a CA-Clipper program is invoked the default message row value is zero, suppressing all defined messages. Messages appear on nRow, column 0 unless the CENTER option is used.

Examples

■  This example creates a small lightbar menu with an activated
   and centered message line:

   SET MESSAGE TO 23 CENTER
   SET WRAP ON
   @ 5, 5 PROMPT "One" MESSAGE "Choice one"
   @ 6, 5 PROMPT "Two" MESSAGE "Choice two"
   MENU TO nChoice
   //
   IF nChoice == 0
      EXIT
   ELSEIF nChoice == 1
      Proc1()
   ELSEIF nChoice == 2
      Proc2()
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET OPTIMIZEHarbour implementation⌃ | ☰

Change the setting that determines whether to optimize using the open orders when processing a filtered database file

Syntax

SET OPTIMIZE ON | OFF | (<lToggle>)

Arguments

ON enables optimization.

OFF disables optimization.

lToggle 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.

Note: The initial default of this setting depends on the RDD.

Description

For RDDs that support optimization, such as DBFCDX, SET OPTIMIZE determines whether to optimize filters based on the orders open in the current work area. If this flag is ON, the RDD will optimize the search for records that meet the filter condition to the fullest extent possible, minimizing the need to read the actual data from the database file.

If this flag is OFF, the RDD will not optimize.

Examples

■  The following example enables optimization for the Inventor
   database file using the SET OPTIMIZE command:

   USE Inventor NEW VIA "DBFCDX"
   SET OPTIMIZE ON

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET ORDERHarbour implementation⌃ | ☰

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, CA-Clipper 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 CA-Clipper. 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

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET PATHHarbour implementation⌃ | ☰

Specify the CA-Clipper search path for opening files

Syntax

SET PATH TO [<xcPathspec list>]

Arguments

TO xcPathspec list identifies the paths CA-Clipper uses when searching for a file not found in the current directory. You can specify it as a literal list or as a character expression enclosed in parentheses. The list of paths can be separated by commas or semicolons. However, continuation of a SET PATH command line with a semicolon is not supported unless xcPathspec is specified as a character expression enclosed in parentheses.

Description

SET PATH allows commands and functions that open database and associated files to find and open existing files in another drive and/or directory. It does this by specifying a path list to search if a referenced file cannot be found in the DEFAULT or specified directory. Note that memo and low-level file functions respect neither the DEFAULT nor the path setting.

A path is a pointer to a directory. It consists of an optional drive letter and colon, followed by a list of directories from the root to the desired directory separated by backslash () characters. A path list is the sequence of paths to search, each separated by a comma or semicolon.

When you attempt to access a file, CA-Clipper first searches the default drive and directory. The default disk drive and directory are established by DOS when your CA-Clipper application is loaded or, during execution, by SET DEFAULT. If the file is not found, CA-Clipper then searches each path in the specified path list until the first occurrence of the file is found.

To create new files in another drive or directory, use SET DEFAULT TO xcPathspec or explicitly declare the path when specifying a new file name.

SET PATH TO with no argument releases the path list and CA-Clipper searches only the DEFAULT directory.

Examples

■  This example is a typical PATH command:

   SET PATH TO A:INVENTORY;B:VENDORS

■  This example configures a path setting at runtime by passing a
   DOS environment variable to a program, retrieving its value with
   GetEnv(), and then setting path with this value.  For example, in
   DOS:

   SET CLIP_PATH=C:APPSDATA,C:APPSPROGS

   Later in the configuration section of your application program:

   SET PATH TO (GetEnv("CLIP_PATH"))

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET PRINTERHarbour implementation⌃ | ☰

Toggle echo of console output to the printer or set the destination of printed output

Syntax

SET PRINTER on | OFF | <xlToggle>
SET PRINTER TO [<xcDevice> | <xcFile> [ADDITIVE]]

Arguments

ON echoes console output to the printer.

OFF suppresses the printing of console output.

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.

TO xcDevice identifies the name of the device where all subsequent printed output will be sent. You can specify a device name as a literal character string or a character expression enclosed in parentheses. Additionally, a device can be either local or network. SETting PRINTER TO a nonexistent device creates a file with the name of the device. When specifying device names, do not use a trailing colon.

TO xcFile identifies the name of the output file. You can specify the file name as a literal string or as a character expression enclosed in parentheses. If a file extension is not specified, .prn is assumed.

ADDITIVE causes the specified output file to be appended to instead of overwritten. If ADDITIVE is not specified, an existing output file is truncated before new information is written to it. The ADDITIVE clause is only meaningful when SETting PRINTER TO an output file.

If SET PRINTER TO is specified with no arguments, the currently specified device or file is closed and the default destination is then reselected.

Description

SET PRINTER, like many other SET commands, has two basic forms with each having its own functionality. The on|OFF form of SET PRINTER controls whether the output of console commands is echoed to the printer. Console commands generally do not specify row and column coordinates. All of these commands, except ?|??, have a TO PRINTER clause that also directs output to the printer. Output from console commands is displayed to the screen unless CONSOLE is OFF. Be aware that @...SAYs are not affected by SET PRINTER ON. To send them to the printer, use SET DEVICE TO PRINTER instead.

SET PRINTER TO determines the destination of output from all commands and functions that send output to the printer. This includes @...SAYs if DEVICE is SET TO PRINTER. Output can be sent to a device or to a file. If the destination is a device, the following names are valid: LPT1, LPT2, LPT3 (all parallel ports), COM1, and COM2 (serial ports), CON and PRN. The default device is PRN.

If the destination is a file, it is created in the current DEFAULT directory. If a file with the same name exists in the same location, it is overwritten by the new file without warning. All subsequent output to the printer is then written to this file until the file is closed using SET PRINTER TO with no argument.

Use SET PRINTER TO for:

■ Managing multiple printers by swapping ports

■ Directing output to a file for printing later or for

transferring to a remote computer via telecommunications

■ Emptying the printer spooler and resetting the default device

Notes

■ Compatibility: CA-Clipper does not support the syntax SET

PRINTER TO SPOOLER or CAPTURE. Specifying SET PRINTER with either of these options creates the files Spooler.prn or Capture.prn. The symbols are ignored.

■ End of file marks: When printer output is redirected to a

file, an end of file mark (Chr(26)) is not written when the file is closed. To terminate a file with an end of file mark, issue a ?? Chr(26) just before the SET PRINTER command that closes the file.

■ Networking: For some networks, the workstation’s printer

should first be redirected to the file server (usually by running the network spooler program).

Examples

■  This example echoes the output of the ? command to printer,
   suppressing the console screen display by SETting CONSOLE OFF:

   USE Customer NEW
   SET PRINTER ON
   SET CONSOLE OFF
   DO WHILE !Eof()
      ? Customer->Name, Customer->Phone
      SKIP
   ENDDO
   EJECT
   SET PRINTER OFF
   SET CONSOLE ON
   CLOSE
   RETURN

■  This example directs printer output to LPT1 and empties the
   print spooler upon completion:

   SET PRINTER TO LPT1
   <Printing statements>...
   SET PRINTER TO            // Empty the print spooler

■  This example sends printer output to a text file, overwriting
   an existing file with the same name:

   SET PRINTER TO Prnfile.txt
   SET DEVICE TO PRINTER
   SET PRINTER ON
   //
   @ 0, 0 SAY "This goes to Prnfile.txt"
   ? "So will this!"
   //
   SET DEVICE TO SCREEN
   SET PRINTER OFF
   SET PRINTER TO            // Close the print file

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET PROCEDURE*Harbour implementation⌃ | ☰

Compile procedures and functions into the current object (.OBJ) file

Syntax

SET PROCEDURE TO [<idProgramFile>[.<ext>]]

Arguments

TO idProgramFile is the name of the procedure file to compile into the current object file. It can optionally include a path and/or drive designator.

ext is the optional extension of the procedure. If not specified, .prg is assumed.

SET PROCEDURE TO with no argument is ignored.

Description

SET PROCEDURE directs the compiler to compile all procedures and user- defined functions declared within the specified procedure file into the current object (.OBJ) file.

SET PROCEDURE is a compatibility command and not recommended. It has been superseded by other facilities more appropriate to the compiled environment (e.g., the compiler script (.clp)) file.

See the CA-Clipper «Compiler» chapter in the Programming and Utilities Guide for a full discussion of program architecture and configuration.

Platforms

Available on MS-DOS

See also

#include, DO*, FUNCTION, PROCEDURE, RETURN

SET RELATIONHarbour implementation⌃ | ☰

Relate two work areas by a key value or record number

Syntax

SET RELATION TO [<expKey> | <nRecord> INTO <xcAlias>]
   [, [TO] <expKey2> | <nRecord2> INTO <xcAlias2>...]
   [ADDITIVE]

Arguments

TO expKey is an expression that performs a SEEK in the child work area each time the record pointer moves in the parent work area. For this to work, the child work area must have an index in USE.

TO nRecord is an expression that performs a GOTO to the matching record number in the child work area each time the record pointer moves in the parent work area. If nRecord evaluates to RecNo(), the relation uses the parent record number to perform a GOTO to the same record number in the child work area. For a numeric expression type of relation to execute correctly, the child work area must not have an index in USE.

INTO xcAlias identifies the child work area and can be specified either as the literal alias name or as a character expression enclosed in parentheses.

ADDITIVE adds the specified child relations to existing relations already set in the current work area. If this clause is not specified, existing relations in the current work area are released before the new child relations are set.

SET RELATION TO with no arguments releases all relations defined in the current work area.

Description

SET RELATION is a database command that links a parent work area to one or more child work areas using a key expression, record number, or numeric expression. Each parent work area can be linked to as many as eight child work areas. A relation causes the record pointer to move in the child work area in accordance with the movement of the record pointer in the parent work area. If no match is found in the child work area, the child record pointer is positioned to LastRec() + 1, Eof() returns true (.T.), and Found() returns false (.F.).

The method of linking the parent and child work areas depends on the type of expKey and presence of an active index in the child work area. If the child work area has an active index, the lookup is a standard SEEK. If the child work area does not have an active index and the type of expKey is numeric, a GOTO is performed in the child work area instead.

Notes

■ Cyclical relations: Do not relate a parent work area to itself

either directly or indirectly.

■ Soft seeking: SET RELATION does not support SOFTSEEK and

always behaves as if SOFTSEEK is OFF even if SOFTSEEK is ON. This means that if a match is not found in the child work area, the child record pointer is always positioned to LastRec() + 1.

■ Record number relations: To relate two work areas based on

matching record numbers, use RecNo() for the SET RELATION TO expression and make sure the child work area has no active indexes.

Examples

■  This example relates three work areas in a multiple parent-
   child configuration with Customer related to both Invoices and Zip:

   USE Invoices INDEX Invoices NEW
   USE Zip INDEX Zipcode NEW
   USE Customer NEW
   SET RELATION TO CustNum INTO Invoices, Zipcode INTO Zip
   LIST Customer, Zip->City, Invoices->Number, ;
            Invoices->Amount

■  Sometime later, you can add a new child relation using the
   ADDITIVE clause, like this:

   USE BackOrder INDEX BackOrder NEW
   SELECT Customer

   SET RELATION TO CustNum INTO BackOrder ADDITIVE

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET SCOPEHarbour implementation⌃ | ☰

Change the top and/or bottom boundaries for scoping key values in the controlling order

Syntax

SET SCOPE TO [<expNewTop> [, <expNewBottom>]]

Arguments

expNewTop is the top range of key values that will be included in the controlling order’s current scope. expNewTop can be an expression that matches the data type of the key expression in the controlling order or a code block that returns the correct data type.

expNewBottom is the bottom range of key values that will be included in the controlling order’s current scope. expNewBottom can be an expression that matches the data type of the key expression in the controlling order or a code block that returns the correct data type.

Note: If expNewBottom is not specified, expNewTop is taken for both the top and bottom range values.

Description

SET SCOPE, when used with no arguments, clears the top and bottom scopes; this is equivalent to ordScope(0, NIL) followed by ordScope(1, NIL). If expNewTop is specified alone, SET SCOPE sets the top and bottom scope to the indicated value (i.e., ordScope(0, expNewTop) followed by ordScope(1, expNewTop). If both expNewTop and expNewBottom are specified, SET SCOPE sets the top and bottom scope as indicated (i.e., ordScope(0, expNewTop) followed by ordScope(1, expNewBottom). Refer to the ordScope() function for more information.

Examples

■  The following example illustrates the SET SCOPE command:

   USE Inventor NEW
   INDEX ON PartNo TO Parts

   SET SCOPE TO 1750, 2000
   // Only part numbers between 1750 and 2000 will be used

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET SCOPEBOTTOMHarbour implementation⌃ | ☰

Change the bottom boundary for scoping key values in the controlling order

Syntax

SET SCOPEBOTTOM TO [<expNewBottom>]

Arguments

expNewBottom is the bottom range of key values that will be included in the controlling order’s current scope. expNewBottom can be an expression that matches the data type of the key expression in the controlling order or a code block that returns the correct data type.

Description

SET SCOPEBOTTOM, when used with the expNewBottom argument, is functionally equivalent to ordScope(1, expNewBottom). SET SCOPEBOTTOM, when used with no argument, is functionally equivalent to ordScope(1, NIL). Refer to the ordScope() function for more information.

Examples

■  The following example illustrates the SET SCOPEBOTTOM command:

   USE Inventor NEW
   INDEX ON PartNo TO Parts

   SET SCOPEBOTTOM TO 1000
   // Only part numbers less than or equal to 1000
   // will be used.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET SCOPETOPHarbour implementation⌃ | ☰

Change the top boundary for scoping key values in the controlling order

Syntax

SET SCOPETOP TO [<expNewTop>]

Arguments

expNewTop is the top range of key values that will be included in the controlling order’s current scope. expNewTop can be an expression that matches the data type of the key expression in the controlling order or a code block that returns the correct data type.

Description

SET SCOPETOP, when used with the expNewTop argument, is functionally equivalent to ordScope(0, expNewTop). SET SCOPETOP, when used with no argument, is functionally equivalent to ordScope(0, NIL). Refer to the ordScope() function for more information.

Examples

■  The following example illustrates the SET SCOPETOP command:

   USE Inventor NEW
   INDEX ON PartNo TO Parts

   SET SCOPETOP TO 1000
   // Only part numbers greater than or equal to 1000
   // will be used.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET SCOREBOARDHarbour implementation⌃ | ☰

Toggle the message display from READ or MemoEdit()

Syntax

SET SCOREBOARD ON | off | <xlToggle>

Arguments

ON allows the display of messages from READ and MemoEdit() on line zero of the screen.

OFF suppresses these messages.

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 SCOREBOARD controls whether or not messages from READ and MemoEdit() display on line zero. When SCOREBOARD is ON, READ displays messages for RANGE errors, invalid dates, and insert status. MemoEdit() displays an abort query message and the insert status.

To suppress the automatic display of these messages, SET SCOREBOARD OFF.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET SOFTSEEKHarbour implementation⌃ | ☰

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

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET TYPEAHEADHarbour implementation⌃ | ☰

Set the size of the keyboard buffer

Syntax

SET TYPEAHEAD TO <nKeyboardSize>

Arguments

TO nKeyboardSize specifies the number of keystrokes the keyboard buffer can hold from a minimum of zero to a maximum of 4096. The default size of the keyboard buffer is machine-dependent but 16 is the minimum size.

Description

SET TYPEAHEAD defines the size of the CA-Clipper keyboard buffer that caches keystrokes input directly by the user. SET TYPEAHEAD, however, does not affect the number of characters that can be stuffed programmatically using the KEYBOARD command. When executed, SET TYPEAHEAD clears the keyboard buffer and sets the size to nKeyboardSize.

When TYPEAHEAD is SET TO zero, keyboard polling is suspended. An explicit request for keyboard input, however, will temporarily enable the keyboard and read any pending keystrokes from the BIOS buffer. Calling NextKey() constitutes such an explicit request. NextKey() reads any pending keystrokes from the BIOS buffer and returns the Inkey() value of the first keystroke read, or zero if no keystrokes are pending.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET UNIQUE*Harbour implementation⌃ | ☰

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.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SET VIDEOMODEHarbour implementation⌃ | ☰

Change the current video mode of the current application

Syntax

SET VIDEOMODE TO <nVideoMode>

Arguments

nVideoMode is a numeric value representing a particular video mode.

Description

SET VIDEOMODE changes the current display to text mode and different graphic modes. There are two modes supported by CA-Clipper: LLG_VIDEO_TEXT and LLG_VIDEO_VGA_640_480_16.

Notes

When switching from LLG_VIDEO_TEXT to LLG_VIDEO_VGA_640_480_16, all displayed text lines are converted to the equivalent graphic display. This conversion does not happen when switching back to LLG_VIDEO_TEXT mode.

If you wish to have a part of your application switch to LLG_VIDEO_VGA_640_480_16 mode and clear the screen, issue the CLS command before switching modes.

Platforms

Available on MS-DOS

File

Libraries are CLIPPER.LIB and LLIBG.LIB.

See also

SET WRAP*Harbour implementation⌃ | ☰

Toggle wrapping of the highlight in menus

Syntax

SET WRAP on | OFF | <xlToggle>

Arguments

ON enables the highlight to wrap around when navigating a lightbar menu.

OFF disables wrapping when navigating a lightbar menu.

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 WRAP is a menu command that toggles wrapping of the highlight in an @...PROMPT menu from the first menu item to the last menu item and vice versa. When WRAP is ON and the last menu item is highlighted, Right arrow or Down arrow moves the highlight to the first menu item. Likewise, when the first menu item is highlighted, Left arrow or Up arrow moves the highlight to the last menu item.

When WRAP is OFF, pressing Up arrow or Left arrow from the first menu item or Down arrow or Right arrow from the last menu item does nothing.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SKIPHarbour implementation⌃ | ☰

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 in the Programming and Utilities Guide 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

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SoundEx()Harbour implementation


⌃ | ☰

Convert a character string to «soundex» form

Syntax

SoundEx(<cString>) → cSoundexString

Arguments

cString is the character string to convert.

Returns

SoundEx() returns a four-digit character string in the form A999.

Description

SoundEx() is a character function that indexes and searches for sound- alike or phonetic matches. It is used in applications where the precise spelling of character keys is not known or where there is a high probability of misspelled names. Misspelling is common in real-time transaction systems where the data entry operator is receiving information over the telephone. SoundEx() works by bringing sound-alikes together under the same key value. Note, however, the soundex method is not absolute. Keys that are quite different can result in the same soundex value.

Examples

■  This example builds an index using SoundEx() to create the key
   values.  It then searches for a value found in the Salesman field:

   USE Sales
   INDEX ON SoundEx(Salesman) TO Salesman
   SEEK SoundEx("Smith")
   ? Found(), Salesman            // Result: .T. Smith

■  Here, a search is made for the same key as above but with a
   different spelling:

   SEEK SoundEx("Smythe")
   ? Found(), Salesman            // Result: .T. Smith

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/SOUNDEX.C.

See also

INDEX, LOCATE, SEEK, SET SOFTSEEK

SORTHarbour implementation⌃ | ☰

Copy to a database (.dbf) file in sorted order

Syntax

SORT TO <xcDatabase> ON <idField1> [/[A | D][C]]
   [, <idField2> [/[A | D][C]]...]
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]

Arguments

TO xcDatabase is the name of the target file for the sorted records and can be specified either as a literal file name or as a character expression enclosed in parentheses. Unless otherwise specified, the new file is assigned a (.dbf) extension.

ON idField is the sort key and must be a field variable.

/[A|D][C] specifies how xcDatabase is to be sorted. /A sorts in ascending order. /D sorts in descending order. /C sorts in dictionary order by ignoring the case of the specified character field. The default SORT order is ascending.

scope is the portion of the current database file to SORT. The default is ALL records.

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

FOR lCondition specifies the conditional set of records to SORT within the given scope.

Description

SORT is a database command that copies records from the current work area to another database file in sorted order. CA-Clipper SORTs character fields in accordance with the ASCII value of each character within the string unless the /C option is specified. This option causes the database file to be sorted in dictionary order—capitalization is ignored. Numeric fields are sorted in numeric order, date fields are sorted chronologically, and logical fields are sorted with true (.T.) as the high value. Memo fields cannot be sorted.

SORT performs as much of its operation as possible in memory, and then, it spools to a uniquely named temporary disk file. This temporary file can be as large as the size of the source database file. Note also that a SORT uses up three file handles: the source database file, the target database file, and the temporary file.

In a network environment, you must lock the database file to be SORTed with FLock() or USE it EXCLUSIVEly.

Notes

■ Deleted source records: If DELETED is OFF, SORT copies deleted

records to the target database file; however, the deleted records do not retain their deleted status. No record is marked for deletion in the target file regardless of its status in the source file.

If DELETED is ON, deleted records are not copied to the target database file. Similarly, filtered records are ignored during a SORT and are not included in the target file.

Examples

■  This example copies a sorted subset of a mailing list to a
   smaller list for printing:

   USE Mailing INDEX Zip
   SEEK "900"
   SORT ON LastName, FirstName TO Invite WHILE Zip = "900"
   USE Invite NEW
   REPORT FORM RsvpList TO PRINTER

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Space()Harbour implementation


⌃ | ☰

Return a string of spaces

Syntax

Space(<nCount>) → cSpaces

Arguments

nCount is the number of spaces to be returned, up to a maximum of 65,535 (64 K).

Returns

Space() returns a character string. If nCount is zero, Space() returns a null string («»).

Description

Space() is a character function that returns a specified number of spaces. It is the same as Replicate(«», nCount). Space() can initialize a character variable before associating it with a GET. Space() can also pad strings with leading or trailing spaces. Note, however, that the PadC(), PadL(), and PadR() functions are more effective for this purpose.

Examples

■  This example uses Space() to initialize a variable for data
   input:

   USE Customer NEW
   MEMVAR->Name = Space(Len(Customer->Name))
   @ 10,10 SAY "Customer Name" GET MEMVAR->Name
   READ

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Sqrt()Harbour implementation


⌃ | ☰

Return the square root of a positive number

Syntax

Arguments

nNumber is a positive number for which the square root is to be computed.

Returns

Sqrt() returns a numeric value calculated to double precision. The number of decimal places displayed is determined solely by SET DECIMALS regardless of SET FIXED. A negative nNumber returns zero.

Description

Sqrt() is a numeric function used anywhere in a numeric calculation to compute a square root (e.g., in an expression that calculates standard deviation).

Examples

■  These examples show various results of Sqrt():

   SET DECIMALS TO 5
   //
   ? Sqrt(2)                 // Result: 1.41421
   ? Sqrt(4)                 // Result: 2.00000
   ? Sqrt(4) ** 2            // Result: 4.00000
   ? Sqrt(2) ** 2            // Result: 2.00000

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Str()Harbour implementation


⌃ | ☰

Convert a numeric expression to a character string

Syntax

Str(<nNumber>, [<nLength>], [<nDecimals>]) → cNumber

Arguments

nNumber is the numeric expression to be converted to a character string.

nLength is the length of the character string to return, including decimal digits, decimal point, and sign.

nDecimals is the number of decimal places to return.

Returns

Str() returns nNumber formatted as a character string. If the optional length and decimal arguments are not specified, Str() returns the character string according to the following rules:

Results of Str() with No Optional Arguments

    Expression               Return Value Length

    Field Variable           Field length plus decimals

    Expressions/constants    Minimum of 10 digits plus decimals

    Val()                    Minimum of 3 digits

    Month()/Day()            3 digits

    Year()                   5 digits

    RecNo()                  7 digits

Description

Str() is a numeric conversion function that converts numeric values to character strings. It is commonly used to concatenate numeric values to character strings. Str() has applications displaying numbers, creating codes such as part numbers from numeric values, and creating index keys that combine numeric and character data.

Str() is like Transform(), which formats numeric values as character strings using a mask instead of length and decimal specifications.

The inverse of Str() is Val(), which converts character numbers to numerics.

Notes

■ If nLength is less than the number of whole number digits in

nNumber, Str() returns asterisks instead of the number.

■ If nLength is less than the number of decimal digits

required for the decimal portion of the returned string, CA-Clipper rounds the number to the available number of decimal places.

■ If nLength is specified but nDecimals is omitted (no

decimal places), the return value is rounded to an integer.

Examples

■  These examples demonstrate the range of values returned by
   Str(), depending on the arguments specified:

   nNumber:= 123.45
   ? Str(nNumber)                   // Result:  123.45
   ? Str(nNumber, 4)                // Result:  123
   ? Str(nNumber, 2)                // Result:  **
   ? Str(nNumber * 10, 7, 2)        // Result:  1234.50
   ? Str(nNumber * 10, 12, 4)       // Result:  1234.5000
   ? Str(nNumber, 10, 1)            // Result:  1234.5

■  This example uses Str() to create an index with a compound key
   of order numbers and customer names:

   USE Customer NEW
   INDEX ON Str(NumOrders, 9) + CustName TO CustOrd

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

StrTran()Harbour implementation


⌃ | ☰

Search and replace characters within a character string or memo field

Syntax

StrTran(<cString>, <cSearch>,
   [<cReplace>], [<nStart>], [<nCount>]) → cNewString

Arguments

cString is the character string or memo field to be searched.

cSearch is the sequence of characters to be located.

cReplace is the sequence of characters with which to replace cSearch. If this argument is not specified, the specified instances of the search argument are replaced with a null string («»).

nStart is the first occurrence that will be replaced. If this argument is omitted, the default is one. If this argument is equal to or less than zero, StrTran() returns an empty string.

nCount is the number of occurrences to be replaced. If this argument is not specified, the default is all.

Returns

StrTran() returns a new character string with the specified instances of cSearch replaced with cReplace.

Description

StrTran() is a character function that performs a standard substring search within a character string. When it finds a match, it replaces the search string with the specified replacement string. All instances of cSearch are replaced unless nStart or nCount is specified. Note that StrTran() replaces substrings and, therefore, does not account for whole words.

Examples

■  This example uses StrTran() to establish a postmodern analog
   to a famous quotation:

   cString:= "To compute, or not to compute?"
   ? StrTran(cString, "compute", "be")
   // Result: To be, or not to be?

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Stuff()Harbour implementation


⌃ | ☰

Delete and insert characters in a string

Syntax

Stuff(<cString>, <nStart>,
   <nDelete>, <cInsert>) → cNewString

Arguments

cString is the target character string into which characters are inserted and deleted.

nStart is the starting position in the target string where the insertion/deletion occurs.

nDelete is the number of characters to be deleted.

cInsert is the string to be inserted.

Returns

Stuff() returns a copy of cString with the specified characters deleted and with cInsert inserted.

Description

Stuff() is a character function that deletes nDelete characters from cString beginning at the nStart position. Then, it inserts cInsert into the resulting string beginning at nStart to form the return string. With this, Stuff() can perform the following six operations:

■ Insert: If nDelete is zero, no characters are removed from

cString. cInsert is then inserted at nStart, and the entire string is returned. For example, Stuff(«My dog has fleas.», 12, 0, «no» ) returns «My dog has no fleas.»

■ Replace: If cInsert is the same length as nDelete,

cInsert replaces characters beginning at nStart. The same number of characters are deleted as are inserted, and the resulting string is the same length as the original. For example, Stuff(«My dog has fleas.», 12, 5, «bones») returns «My dog has bones.»

■ Delete: If cInsert is a null string («»), the number of

characters specified by nDelete are removed from cString, and the string is returned without any added characters. For example, Stuff(«My dog has fleas.», 1, 3, «») returns «dog has fleas.»

■ Replace and insert: If cInsert is longer than nDelete, all

characters from nStart up to nDelete are replaced and the rest of cInsert is inserted. Since more characters are inserted than are deleted, the resulting string is always longer than the original. For example, Stuff(«My dog has fleas.», 8, 3, «does not have») returns «My dog does not have fleas.»

■ Replace and delete: If the length of cInsert is less than

nDelete, more characters are deleted than inserted. The resulting string, therefore, is shorter than the original. For example, Stuff(«My dog has fleas.», 8, 3, «is») returns «My dog is fleas.»

■ Replace and delete rest: If nDelete is greater than or equal

to the number of characters remaining in cString beginning with nStart, all remaining characters are deleted before cInsert is inserted. For example, Stuff(«My dog has fleas.», 8, 10, «is.») returns «My dog is.»

Examples

■  These examples demonstrate the six basic operations of
   Stuff():

   // Insert
   ? Stuff("ABCDEF", 2, 0, "xyz")      // Result: AxyzBCDEF
   // Replace
   ? Stuff("ABCDEF", 2, 3, "xyz")      // Result: AxyzEF
   // Delete
   ? Stuff("ABCDEF", 2, 2, "")         // Result: ADEF
   // Replace and insert
   ? Stuff("ABCDEF", 2, 1, "xyz")      // Result: AxyzCDEF
   // Replace and delete
   ? Stuff("ABCDEF", 2, 4, "xyz")      // Result: AxyzF
   // Replace and delete rest
   ? Stuff("ABCDEF", 2, 10, "xyz")     // Result: Axyz

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/STUFF.C.

See also

STATIC⌃ | ☰

Declare and initialize static variables and arrays

Syntax

STATIC <identifier> [[:= <initializer>], ... ]

Arguments

identifier is the name of the variable or array to declare static. If the identifier is followed by square brackets ([ ]), it is created as an array. If the identifier is an array, the syntax for specifying the number of elements for each dimension can be array[nElements, nElements2,…] or array[nElements] [nElements2]… The maximum number of elements is 4096. The maximum number of dimensions is limited only by available memory.

initializer is the optional assignment of a value to a new static variable. An initializer for a static variable consists of the inline assignment operator (:=) followed by a compile-time constant expression consisting entirely of constants and operators or a literal array. If no explicit initializer is specified, the variable is given an initial value of NIL. In the case of an array, each element is NIL. Array identifiers cannot be given values with an initializer.

Note: The macro operator (&) cannot be used in a STATIC declaration statement.

Description

The STATIC statement declares variables and arrays that have a lifetime of the entire program but are only visible within the entity that creates them. Static variables are visible only within a procedure or user-defined function if declared after a PROCEDURE or FUNCTION statement. Static variables are visible to all procedures and functions in a program (.prg) file (i.e., have filewide scope) if they are declared before the first procedure or user-defined function definition in the file. Use the /N compiler option to compile a program with filewide variable scoping.

All static variables in a program are created when the program is first invoked, and all values specified in a static initializer are assigned to the variable before the beginning of program execution.

Declarations of static variables within a procedure or user-defined function must occur before any executable statement including PRIVATE, PUBLIC, and PARAMETERS. If a variable of the same name is declared FIELD, LOCAL, or MEMVAR within the body of a procedure or user-defined function, a compiler error occurs and no object (.OBJ) file is generated.

The maximum number of static variables in a program is limited only by available memory.

Notes

■ Inspecting static variables within the Debugger: To access

static variable names within the CA-Clipper debugger, you must compile program (.prg) files using the /B option so that static variable information is included in the object (.OBJ) file.

■ Macro expressions: You may not refer to static variables

within macro expressions or variables. If a static variable is referred to within a macro expression or variable, a private or public variable of the same name will be accessed instead. If no such variable exists, a runtime error will be generated.

■ Memory files: Static variables cannot be SAVED to or RESTOREd

from memory (.mem) files.

■ Type of a static local variable: Since Type() uses the macro

operator (&) to evaluate its argument, you cannot use Type() to determine the type of a local or static variable or an expression containing a local or static variable reference. The ValType() function provides this facility by evaluating the function argument and returning the data type of its return value.

Examples

■  This example declares static variables both with and without
   initializers:

   STATIC aArray1[20, 10], aArray2[20][10]
   STATIC cVar, cVar2
   STATIC cString := "my string", var
   STATIC aArray := {1, 2, 3}

■  This example manipulates a static variable within a user-
   defined function.  In this example, a count variable increments
   itself each time the function is called:

   FUNCTION MyCounter( nNewValue )
      STATIC nCounter := 0         // Initial value assigned once
      IF nNewValue != NIL
         nCounter:= nNewValue      // New value for nCounter
      ELSE
         nCounter++                // Increment nCounter
      ENDIF
      RETURN nCounter

■  This example demonstrates a static variable declaration that
   has filewide scope.  In this code fragment, aArray is visible to both
   procedures that follow the declaration:

   STATIC aArray := {1, 2, 3, 4}

   FUNCTION One
      ? aArray[1]                  // Result: 1
      RETURN NIL

   FUNCTION Two
      ? aArray[3]                  // Result: 3
      RETURN NIL

Platforms

Available on MS-DOS

See also

STORE*Harbour implementation⌃ | ☰

Assign a value to one or more variables

Syntax

STORE <exp> TO <idVar list>
<idVar> = <exp>
<idVar> := [ <idVar2> := ...] <exp>

Arguments

exp is a value of any data type that is assigned to the specified variables.

TO idVar list defines a list of one or more local, static, public, private, or field variables that are assigned the value exp. If any idVar is not visible or does not exist, a private variable is created and assigned exp.

Description

STORE assigns a value to one or more variables of any storage class. The storage classes of CA-Clipper variables are local, static, field, private, and public. STORE is identical to the simple assignment operators (=) and (:=). In fact, a STORE statement is preprocessed into an assignment statement using the inline operator (:=). Like all of the assignment operators, STORE assigns to the most recently declared and visible variable referenced by idVar. If, however, the variable reference is ambiguous (i.e., not declared at compile time or not explicitly qualified with an alias), it is assumed to be MEMVAR. At runtime, if no private or public variable exists with the specified name, a private variable is created.

To override a declaration, you can specify the idVar prefaced by an alias. If idVar is a field variable, use the name of the work area. For private and public variables, you can use the memory variable alias (MEMVAR->). To assign to a field variable in the currently selected work area (as opposed to a particular named work area), you can use the field alias (FIELD->).

As a matter of principle, all variables other than field variables should be declared. Preface field variables with the alias. Use of private and public variables is discouraged since they violate basic principles of modular programming and are much slower than local and static variables.

Note that the STORE command is a compatibility command and not recommended for any assignment operation. CA-Clipper provides assignment operators that supersede the STORE command, including the inline assignment operator (:=), the increment and decrement operators (++) and (—), and the compound assignment operators (+=, -=, *=, /=). Refer to the Operators and Variables sections of the «Basic Concepts» chapter in the Programming and Utilities Guide for more information.

Notes

■ Assigning a value to an entire array: In CA-Clipper, neither

the STORE command nor the assignment operators can assign a single value to an entire array. Use the AFill() function for this purpose.

■ Memo fields: Assigning a memo field to a variable assigns a

character value to that variable.

Examples

■  These statements create and assign values to undeclared
   private variables:

   STORE "string" TO cVar1, cVar2, cVar3
   cVar1:= "string2"
   cVar2:= MEMVAR->cVar1

■  These statements assign multiple variables using both STORE
   and the inline assignment operator (:=).  The methods produce
   identical code:

   STORE "value" to cVar1, cVar2, cVar3
   cVar1 := cVar2 := cVar3 := "value"

■  These statements assign values to the same field referenced
   explicitly with an alias.  The first assignment uses the field alias
   (FIELD->), where the second uses the actual alias name:

   USE Sales NEW
   FIELD->CustBal = 1200.98
   Sales->CustBal = 1200.98

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SubStr()Harbour implementation


⌃ | ☰

Extract a substring from a character string

Syntax

SubStr(<cString>, <nStart>, [<nCount>]) → cSubstring

Arguments

cString is the character string from which to extract a substring. It can be up to 65,535 (64K) bytes, the maximum character string size in CA-Clipper.

nStart is the starting position in cString. If nStart is positive, it is relative to the leftmost character in cString. If nStart is negative, it is relative to the rightmost character in the cString.

nCount is the number of characters to be extracted. If omitted, the substring begins at nStart and continues to the end of the string. If nCount is greater than the number of characters from nStart to the end of cString, the excess numbers are ignored.

Returns

SubStr() returns a character string.

Description

SubStr() is a character function that extracts a substring from another character string or memo field. SubStr() is related to the Left() and Right() functions which extract substrings beginning with leftmost and rightmost characters in cString, respectively.

The SubStr(), Right(), and Left() functions are often used with both the At() and RAt() functions to locate either the first and/or the last position of a substring before extracting it. They are also used to display or print only a portion of a character string.

Examples

■  These examples extract the first and last name from a
   variable:

   cName:= "Biff Styvesent"
   ? SubStr(cName, 1, 4)               // Result: Biff
   ? SubStr(cName, 6)                  // Result: Styvesent
   ? SubStr(cName, Len(cName) + 2)     // Result: null string
   ? SubStr(cName, -9)                  // Result: Styvesent
   ? SubStr(cName, -9, 3)               // Result: Sty

■  This example uses SubStr() with At() and RAt() to create a
   user-defined function to extract a file name from a file
   specification:

   ? FileBase("C:PRGMYFILE.OBJ")      // Result: MYFILE.OBJ

   FUNCTION FileBase( cFile )
      LOCAL nPos
      IF (nPos := RAt("", cFile)) != 0
         RETURN SubStr(cFile, nPos + 1)
      ELSEIF (nPos := At(":", cFile)) != 0
         RETURN SubStr(cFile, nPos + 1)
      ELSE
         RETURN cFile
      ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

SUMHarbour implementation⌃ | ☰

Sum numeric expressions and assign results to variables

Syntax

SUM <nExp list> TO <idVar list>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]

Arguments

nExp list is the list of numeric values to sum for each record processed.

TO idVar list identifies the receiving variables to be assigned assign the results of the sum. Variables that either do not exist or are not visible are created as private variables. idVar list must contain the same number of elements as nExp list.

scope is the portion of the current database file to SUM. The default scope is ALL records.

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

FOR lCondition specifies the conditional set of records to SUM within the given scope.

Description

SUM is a database command that totals a series of numeric expressions for a range of records in the current work area and assigns the results to a series of variables. The variables specified in idVar list can be field, local, private, public, or static.

Note that the nExp list is required and not optional as it is in other dialects.

Examples

■  This example illustrates the use of SUM:

   LOCAL nTotalPrice, nTotalAmount
   USE Sales NEW
   SUM Price * .10, Amount TO nTotalPrice, nTotalAmount
   //
   ? nTotalPrice               // Result: 151515.00
   ? nTotalAmount              // Result: 150675.00

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

TBColumn class⌃ | ☰

Provide column objects for TBrowse objects

Description

A TBColumn object is a simple object containing the information needed to fully define one data column of a TBrowse object.

Methods link

TBColumnNew() Create a new TBColumn object


TBColumnNew(cHeading, bBlock) → oTBColumn

Returns

Returns a new TBColumn object with the specified heading and data retrieval block. Other elements of the TBColumn object can be assigned directly using the syntax for assigning exported instance variables.

Exported Instance Variables


block Code block to retrieve data for the column


block (Assignable)

Contains a code block that retrieves data for the column. Any code block is valid, and no block arguments are supplied when the block is evaluated. The code block must return the appropriate data value for the column.

cargo User-definable variable


cargo (Assignable)

Contains a value of any data type provided as a user-definable slot, allowing arbitrary information to be attached to a TBColumn and retrieved later.

colorBlock Code block that determines color of data items


colorBlock (Assignable)

Contains an optional code block that determines the color of data items as they are displayed. If present, this block is executed each time a new value is retrieved via the TBColumn:block (the data retrieval block). The newly retrieved data value is passed as an argument to the TBColumn:colorBlock, which must return an array containing four numeric values. The values returned are used as indexes into the color table of the TBrowse object as described in the TBColumn:defColor reference below.

The TBColumn:colorBlock allows display colors for data items based on the value of the data being displayed. For example, negative numbers may be displayed in a different color than positive numbers.

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Properties Workbench window for that item.

colSep Column separator character


colSep (Assignable)

Contains an optional character string that draws a vertical separator to the left of this column if there is another column to the left of it. If no value is supplied for TBColumn:colSep, the value contained in TBrowse:colSep is used instead.

defColor Array of numeric indexes into the color table


defColor (Assignable)

Contains an array of four numeric values used as indexes into the color table in the TBrowse object. The first value determines the unselected color which displays data values when the browse cursor is not on the data value being displayed. The second value determines the selected color. The selected color displays the current browse cell. The third color displays the heading. The fourth color displays the footing.

The default value for TBColumn:defColor is {1, 2, 1, 1}. This causes the first two colors in the TBrowse color table to be used for unselected and selected, respectively. Note that colors set using TBColumn:colorBlock override those set by TBColumn:defColor.

footing (Assignable)

Contains a character value that defines the footing for this data column.

footSep Footing separator character


footSep (Assignable)

Contains a character value that draws a horizontal line between the data values and the footing. If it does not contain a character value, TBrowse:footSep is used instead.

heading (Assignable)

Contains a character value that defines the heading for this data column.

headSep Heading separator character


headSep (Assignable)

Contains an optional character string that draws a horizontal separator between the heading and the data values. If it does not contain a character value, the TBrowse:headSep is used instead.

picture Character string controlling column formatting and editing


picture (Assignable)

Contains an optional character string that controls formatting and editing of the column. See the @...GET entry in the Reference Guide, Volume 1 for more information on PICTURE strings.

postBlock Code block validating values


postBlock (Assignable)

Contains an optional code block that validates a newly entered or modified value contained within a given cell.. If present, the TBColumn:postBlock should contain an expression that evaluates to true (.T.) for a legal value and false (.F.) for an illegal value.

The TBColumn object itself ignores this variable. It is typically used by the standard READ command.

During postvalidation, the TBColumn:postBlock is passed a reference to the current Get object as an argument.

preBlock Code block determining editing


preBlock (Assignable)

Contains an optional code block that decides whether editing should be permitted. If present, the TBColumn:preBlock should evaluate to true (.T.) if the cursor enters the editing buffer; otherwise, it should evaluate to false (.F.).

The TBColumn object itself ignores this variable. It is typically used by the standard READ command.

During prevalidation, the TBColumn:preBlock is passed a reference to the current Get object as an argument.

width Column display width


width (Assignable)

Contains a numeric value that defines the display width for the column. If TBColumn:width is not explicitly set, the width of the column will be the greater of the length of the heading, the length of the footing, or the length of the data at the first evaluation of TBColumn:block.

If this instance variable is explicitly set, the width of the column will be TBColumn:width. Displayed headings, footings, and data will all be truncated to this width when necessary. The width of the displayed data will be the length at the first evaluation of TBColumn:block for all data types other than character. Character data will be extended to TBColumn:width for display purposes.

setstyle() Maintains dictionary within object


setstyle(nStyle, [lSetting]) → self

TBColumn:setStyle() maintains a dictionary within a TBColumn object. This dictionary, which is simply an array, contains a set of logical values that determine behaviors associated with a TBrowse column. nStyle refers to the element in the dictionary that contains the style. lSetting indicates whether the style should be permitted or denied. Set to true (.T.) to allow the behavior to occur; otherwise, set to false (.F.) to prohibit it. CA-Clipper reserves the first three elements of the dictionary for predefined styles.

You may add custom styles to a TBColumn object by specifying any unused element of the dictionary. A maximum of 4096 definitions is available. When adding new styles to the dictionary, use the TBC_CUSTOM constant to ensure that the new styles will not interfere with the predefined ones. This guarantees that if more predefined styles are added in future releases of CA-Clipper, the positions of your styles in the dictionary will be adjusted automatically.

Styles are used by neither the TBColumn object nor the TBrowse object. The style dictionary is merely a convenient method of associating behaviors with a TBColumn object. The functions that query and implement these behaviors are external to the object. An example of this can be found in BrowSys.prg in the clip53samples subdirectory.

TBColumn Styles

       Number  TBrowse.ch     Meaning

       1       TBC_READWRITE  Can the user modify the data in the column’s

                              cells?

       2       TBC_MOVE       Can the user move the column to another

                              position in the browse?

       3       TBC_SIZE       Can the user modify the width of the column?

       4       TBC_CUSTOM     First available element for custom styles.

Tbrowse.ch contains manifest constants for TBColumn:SetStyle().

Note: TBC_MOVE and TBC_SIZE are not implemented in CA-Clipper 5.3. They are reserved for future usage.

Examples

■  This example is a code fragment that creates a TBrowse object
   and adds some TBColumn objects to it:

   USE Customer NEW
   //

   // Create a new TBrowse object
   objBrowse := TBrowseDB(1, 1, 23, 79)
   //

   // Create some new TBColumn objects and
   // add them to the TBrowse object
   objBrowse:addColumn(TBColumnNew("Customer", ;
         {|| Customer->Name}))
   objBrowse:addColumn(TBColumnNew("Address", ;
         {|| Customer->Address}))
   objBrowse:addColumn(TBColumnNew("City", ;
         {|| Customer->City}))
   .
   . <statements to actually browse the data>
   .
   CLOSE Customer

   For more information on TBrowse, refer to the "Introduction to
   TBrowse" chapter in the Programming and Utilities Guide.  For a fully
   operational example of a TBrowse object, see TbDemo.prg located in
   CLIP53SOURCESAMPLE.

Platforms

Available on MS-DOS

See also

TBrowse class⌃ | ☰

Provide objects for browsing table-oriented data

Description

A TBrowse object is a general purpose browsing mechanism for table-oriented data. TBrowse objects provide a sophisticated architecture for acquiring, formatting, and displaying data. Data retrieval and file positioning are performed via user-supplied code blocks, allowing a high degree of flexibility and interaction between the browsing mechanism and the underlying data source. The format of individual data items can be precisely controlled via the TBColumn data retrieval code blocks; overall display formatting and attributes can be controlled by sending appropriate messages to the TBrowse object.

Note: TBrowse has a memory limit of 200 fields.

A TBrowse object relies on one or more TBColumn objects. A TBColumn object contains the information necessary to define a single column of the browse table (see TBColumn class in this chapter).

During operation, a TBrowse object retrieves data by evaluating code blocks. The data is organized into rows and columns and displayed within a specified rectangular region of the screen. The TBrowse object maintains an internal browse cursor. The data item on which the browse cursor rests is displayed in a highlighted color. (The actual screen cursor is also positioned to the first character of this data item.)

Initially, the browse cursor is placed on the data item at the top left of the browse display. Messages can then be sent to the TBrowse object to navigate the displayed data, causing the browse cursor to move. These messages are normally sent in response to user keystrokes.

New data is automatically retrieved as required by navigation requests. When navigation proceeds past the edge of the visible rectangle, rows or columns beyond that edge are automatically brought into view. When new rows are brought into view, the underlying data source is repositioned by evaluating a code block.

Note: TBrowse objects do not clear the entire window before output during redisplay operations. Part of the window may still be cleared when data from the existing display is scrolled.

Methods link

TBrowseDB() Create a new TBrowse object for browsing a database file


TBrowseDB(nTop, nLeft, nBottom, nRight)

→ oTBrowse

Returns

TBrowseDB() returns a new TBrowse object with the specified coordinate settings and default code blocks for data source positioning within database files. The coordinate settings are defined by nTop, nLeft, nBottom, and nRight. The default code blocks execute the GO TOP, GO BOTTOM, and SKIP operations. Note that TBrowseDB() creates an object with no column objects. To make the TBrowse object usable, you must add a column for each field to be displayed.

TBrowseNew(nTop, nLeft, nBottom, nRight)

→ oTBrowse

Returns

TBrowseNew() returns a new TBrowse object with the specified coordinate settings defined by nTop, nLeft, nBottom, and nRight. The TBrowse object is created with no columns and no code blocks for data positioning. These must be provided before the TBrowse object can be used.

Exported Instance Variables


autoLite Logical value to control highlighting


autoLite (Assignable)

Contains a logical value. When autoLite is set to true (.T.), the stabilize method automatically highlights the current cell as part of stabilization. The default for autoLite is true (.T.).

border Character value defining characters drawn around object


border (Assignable)

Contains a character value that defines the characters that comprise the box that is drawn around the TBrowse object on the screen. Its length must be either zero or eight characters. If not specified, the browse appears without a border. When present, the browse occupies the region of the screen specified by TBrowse:nTop + 1, TBrowse:nLeft + 1, TBrowse:nBottom — 1, TBrowse:nRight — 1. This effectively decreases the number of screen rows and columns that the browse occupies by two.

cargo User-definable variable


cargo (Assignable)

Contains a value of any data type provided as a user-definable slot. TBrowse:cargo allows arbitrary information to be attached to a TBrowse object and retrieved later.

colCount Number of browse columns


colCount

Contains a numeric value indicating the total number of data columns in the browse. For each column, there is an associated TBColumn object.

colorSpec Color table for the TBrowse display


colorSpec (Assignable)

Contains a character string defining a color table for the TBrowse display. As a default, the current SetColor() value is copied into this variable when the TBrowse object is created.

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Properties Workbench window for that item.

colPos Current cursor column position


colPos (Assignable)

Contains a numeric value indicating the data column where the browse cursor is currently located. Columns are numbered from 1, starting with the leftmost column.

colSep Column separator character


colSep (Assignable)

Contains a character value that defines a column separator for TBColumns that do not contain a column separator of their own (see TBColumn class in this chapter for more information).

footSep Footing separator character


footSep (Assignable)

Contains a character value that defines a footing separator for TBColumn objects not containing a footing separator of their own (see TBColumn class in this chapter).

freeze Number of columns to freeze


freeze (Assignable)

Contains a numeric value that defines the number of data columns frozen on the left side of the display. Frozen columns are always visible, even when other columns are panned off the display.

goBottomBlock Code block executed by TBrowse:goBottom()


goBottomBlock (Assignable)

Contains a code block executed in response to the TBrowse:goBottom() message. This block is responsible for repositioning the data source to the last record displayable in the browse. Typically the data source is a database file, and this block contains a call to a user- defined function that executes a GO BOTTOM command.

goTopBlock Code block executed by TBrowse:goTop()


goTopBlock (Assignable)

Contains a code block that is executed in response to the TBrowse:goTop() message. This block is responsible for repositioning the data source to the first record displayable in the browse. Typically the data source is a database file, and this block contains a call to a user-defined function that executes a GO TOP command.

headSep Heading separator character


headSep (Assignable)

Contains a character value that defines a heading separator for TBColumn objects not containing a heading separator of their own (see TBColumn class in this chapter).

hitBottom Indicates the end of available data


hitBottom (Assignable)

Contains a logical value indicating whether an attempt was made to navigate beyond the end of the available data. TBrowse:hitBottom contains true (.T.) if an attempt was made; otherwise it contains false (.F.). During stabilization, the TBrowse object sets this variable if TBrowse:skipBlock indicates it was unable to skip forward as many records as requested.

hitTop Indicates the beginning of available data


hitTop (Assignable)

Contains a logical value indicating whether an attempt was made to navigate past the beginning of the available data. TBrowse:hitTop contains true (.T.) if an attempt was made; otherwise it contains false (.F.). During stabilization, the TBrowse object sets this variable if TBrowse:skipBlock indicates that it was unable to skip backward as many records as requested.

leftVisible Indicates position of leftmost unfrozen column in display


leftVisible

Contains a numeric value indicating the position of the leftmost unfrozen column visible in the browse display. If every column is frozen in the display, TBrowse:leftVisible contains zero.

mColPos Numeric value indicating mouse position


mColPos (Assignable)

Contains a numeric value indicating the data column where the mouse cursor is currently located. Columns are numbered from 1, starting with the leftmost column.

message Character string displayed on status bar


message (Assignable)

Contains a character string that is displayed on the GET system’s status bar line when the TBrowse is utilized within the GET system. Typically, it describes the anticipated contents of, or user response to, the browse. Refer to @ ...GET TBROWSE and the READ command for details pertaining to the GET system’s status bar.

mRowPos Numeric value indicating the data row of the mouse position


mRowPos (Assignable)

Contains a numeric value indicating the data row where the mouse cursor is currently located. Data rows are numbered from 1, starting with the topmost data row. Screen rows containing headings, footings, or separators are not considered data rows.

nBottom Bottom row number for the TBrowse display


nBottom (Assignable)

Contains a numeric value defining the bottom screen row used for the TBrowse display.

nLeft Leftmost column for the TBrowse display


nLeft (Assignable)

Contains a numeric value defining the leftmost screen column used for the TBrowse display.

nRight Rightmost column for the TBrowse display


nRight (Assignable)

Contains a numeric value defining the rightmost screen column used for the TBrowse display.

nTop Top row number for the TBrowse display


nTop (Assignable)

Contains a numeric value defining the top screen row used for the TBrowse display.

rightVisible Indicates position of rightmost unfrozen column in display


rightVisible

Contains a numeric value indicating the position of the rightmost unfrozen column visible in the browse display. If all columns visible in the display are frozen, TBrowse:rightVisible contains zero.

rowCount Number of visible data rows in the TBrowse display


rowCount

Contains a numeric value indicating the number of data rows visible in the browse display. Only data rows are included in the count. Rows occupied by headings, footings, or separators are not included.

rowPos Current cursor row position


rowPos (Assignable)

Contains a numeric value indicating the data row where the browse cursor is currently located. Data rows are numbered from 1, starting with the topmost data row. Screen rows containing headings, footings, or separators are not considered data rows.

skipBlock Code block used to reposition data source


skipBlock (Assignable)

Contains a code block that repositions the data source. During stabilization, this code block is executed with a numeric argument when the TBrowse object needs to reposition the data source. The numeric argument passed to the block represents the number of records to be skipped. A positive value means skip forward, and a negative value means skip backward. A value of zero indicates that the data source does not need to be repositioned, but the current record may need to be refreshed. Typically, the data source is a database file, and this block calls a user-defined function that executes a SKIP command to reposition the record pointer.

The block must return the number of rows (positive, negative, or zero) actually skipped. If the value returned is not the same as the value requested, the TBrowse object assumes that the skip operation encountered the beginning or end of file.

stable Indicates if the TBrowse object is stable


stable (Assignable)

Contains a logical value indicating whether the TBrowse object is stable. It contains true (.T.) if the TBrowse object is stable; otherwise, it contains false (.F.). The browse is considered stable when all data has been retrieved and displayed, the data source has been repositioned to the record corresponding to the browse cursor, and the current cell has been highlighted. When navigation messages are sent to the TBrowse object, TBrowse:stable is set to false (.F.). After stabilization is performed using the TBrowse:stabilize() message, TBrowse:stable is set to true (.T.).

down() Moves the cursor down one row


down() → self

Moves the browse cursor down one row. If the cursor is already on the bottom row, the display is scrolled up and a new row is brought into view. If the data source is already at the logical end of file and the browse cursor is already on the bottom row, TBrowse:hitBottom is set true (.T.).

end() Moves the cursor to the rightmost visible data column


end() → self

Moves the browse cursor to the rightmost data column currently visible.

goBottom() Repositions the data source to the bottom of file


goBottom() → self

Repositions the data source to logical bottom of file (by evaluating the TBrowse:goBottomBlock), refills the display with the bottommost available data, and moves the browse cursor to the lowermost data row for which data is available. The pan position of the window is not changed.

goTop() Repositions the data source to the top of file


goTop() → self

Repositions the data source to the logical beginning of file (by evaluating the TBrowse:goTopBlock), refills the display with the topmost available data, and moves the browse cursor to the uppermost data row for which data is available. The pan position of the window is not changed.

home() Moves the cursor to the leftmost visible data column


home() → self

Moves the browse cursor to the leftmost unfrozen column on the display.

Left() Moves the cursor left one column


Left() → self

Moves the browse cursor left one data column. If the cursor is already on the leftmost displayed column, the display is panned and the previous data column (if there is one) is brought into view.

pageDown() Repositions the data source downward


pageDown() → self

Repositions the data source downward and refills the display. If the data source is already at the logical end of file (i.e., the bottommost available record is already shown), the browse cursor is simply moved to the lowermost row containing data. If the data source is already at the logical end of file and the browse cursor is already on the bottom row, TBrowse:hitBottom is set true (.T.).

pageUp() Repositions the data source upward


pageUp() → self

Repositions the data source upward and refills the display. If the data source is already at logical beginning of file (i.e., the topmost available record is already shown), the browse cursor is simply moved to the top data row. If the data source is already at logical beginning of file and the browse cursor is already on the first data row, TBrowse:hitTop is set true (.T.).

panEnd() Moves the cursor to the rightmost data column


panEnd() → self

Moves the browse cursor to the rightmost data column, causing the display to be panned completely to the right.

panHome() Moves the cursor to the leftmost visible data column


panHome() → self

Moves the browse cursor to the leftmost data column, causing the display to be panned all the way to the left.

panLeft() Pans left without changing the cursor position


panLeft() → self

Pans the display without changing the browse cursor, if possible. When the screen is panned with TBrowse:panLeft(), at least one data column out of view to the left is brought into view, while one or more columns are panned off screen to the right.

panRight() Pans right without changing the cursor position


panRight() → self

Pans the display without changing the browse cursor, if possible. When the screen is panned with TBrowse:panRight(), at least one data column out of view to the right is brought into view, while one or more columns are panned off the screen to the left.

Right() Moves the cursor right one column


Right() → self

Moves the browse cursor right one data column. If the cursor is already at the right edge, the display is panned and the next data column (if there is one) is brought into view.

up() Moves the cursor up one row


up() → self

Moves the browse cursor up one row. If the cursor is already on the top data row, the display is scrolled down and a new row is brought into view. If the data source is already at the logical beginning of file and the browse cursor is already on the top data row, TBrowse:hitTop is set true (.T.).

addColumn() Adds a TBColumn object to the TBrowse object


addColumn(oColumn) → self

Adds a new TBColumn object to the TBrowse object and TBrowse:colCount is increased by one.

applyKey() Evaluates the code block


applyKey(nKey) → nResult

Evaluates the code block associated with nKey that is contained within the TBrowse:setKey() dictionary. nResult, which is the code block’s return value, specifies the manner in which the key was processed.

TBrowse:ApplyKey() Return Values

       Constant      Value   Meaning

       TBR_EXIT      -1      User request for the browse to lose input focus

       TBR_CONTINUE   0      Code block associated with <nKey> was evaluated

       TBR_EXCEPTION  1      Unable to locate <nKey> in the dictionary, key

                             was not processed

Tbrowse.ch contains manifest constants for the TBrowse:applyKey() return values.

Previously, before TBrowse:applyKey() was available, a TBrowse was typically maintained by placing an Inkey() and a case structure within a while loop. For example:

WHILE (.T.)

oTB:ForceStable() nKey := Inkey(0) DO CASE CASE (nKey == K_UP)

oTB:Up()

CASE (nKey == K_DOWN)

oTB:Down()

. . . CASE (nKey := K_ESC)

EXIT

ENDCASE

ENDDO

Because this code was external to the browse, it did not encapsulate the relationship between a key press and its effect on the browse. TBrowse:applyKey() resolves this by placing the key and its associated code block in a dictionary within the TBrowse object. This effectively makes creating and managing a browse simple, yet flexible. For example:

WHILE (.T.)

oTB:ForceStable() IF (oTB:ApplyKey(Inkey(0)) == TBR_EXIT)

EXIT

ENDIF

ENDDO

colorRect() Alters the color of a rectangular group of cells


colorRect(aRect, aColors) → self

Directly alters the color of a rectangular group of cells. aRect is an array of four numbers (top, left, bottom, and right). The numbers refer to cells within the data area of the browse display, not to screen coordinates. aColors is an array of two numbers. The numbers are used as indexes into the color table for the browse. These colors will become the normal and highlighted colors for the cells within the specified rectangle.

Cells that are colored using colorRect retain their color until they are scrolled off the screen up or down. Horizontal panning has no affect on these colors and, in fact, cells that are currently off screen left or right can be colored even if they are not visible.

This example colors the entire virtual window (on and off screen):

aRect := {1, 1, browse:rowCount, browse:colCount} browse:colorRect(aRect, {2, 1})

colWidth() Returns the display width of a particular column


colWidth(nColumn) → nWidth

Returns the display width of column number nColumn as known to the browse. If nColumn is out of bounds, not supplied, or not a number, the method returns zero.

configure() Reconfigures the internal settings of the TBrowse object


configure() → self

Causes the TBrowse object to re-examine all instance variables and TBColumn objects, reconfiguring its internal settings as required. This message can force reconfiguration when a TBColumn object is modified directly.

deHilite() Dehighlights the current cell


deHilite() → self

Causes the current cell (the cell to which the browse cursor is positioned) to be «dehighlighted.» This method is designed for use when TBrowse:autoLite is set to false (.F.).

delColumn() Delete a column object from a browse


delColumn(nPos) → oColumn

This new method allows a column to be deleted from a browse. The return value is a reference to the column object being deleted, so that the column object may be preserved.

forceStable() Performs a full stabilization


forceStable()

Performs a full stabilization of the TBrowse. It is analogous to the following code, only slightly faster:

DO WHILE .NOT. oBrowse:stabilize() ENDDO

getColumn() Gets a specific TBColumn object


getColumn(nColumn) → oColumn

Returns the TBColumn object specified by nColumn.

hilite() Highlights the current cell


hilite() → self

Causes the current cell (the cell to which the browse cursor is positioned) to be highlighted. This method is designed for use when TBrowse:autoLite is set to false (.F.).

HitTest() Indicates position of mouse cursor relative to TBrowse


HitTest(nRow, nColumn) → nHitTest

Determines if the screen position specified by nRow and nColumn is on the TBrowse object.

Applicable Hit Test Return Values

       Value  Constant       Description

       0      HTNOWHERE      The screen position is not within the region of

                             the screen that the TBrowse occupies

       -1     HTTOPLEFT      The screen position is on the TBrowse border’s

                             top-left corner

       -2     HTTOP          The screen position is on the TBrowse’s top

                             border

       -3     HTTOPRIGHT     The screen position is on the TBrowse border’s

                             top-right corner

       -4     HTRIGHT        The screen position is on the TBrowse’s right

                             border

       -5     HTBOTTOMRIGHT  The screen position is on the TBrowse border’s

                             bottom-right corner

       -6     HTBOTTOM       The screen position is on the TBrowse’s bottom

                             border

       -7     HTBOTTOMLEFT   The screen position is on the TBrowse border’s

                             bottom-left corner

       -8     HTLEFT         The screen position is on the TBrowse’s left

                             border

       -5121  HTCELL         The screen position is on a cell

       -5122  HTHEADING      The screen position is on a heading

       -5123  HTFOOTING      The screen position is on a footing

       -5124  HTHEADSEP      The screen position is on the heading separator

                             line

       -5125  HTFOOTSEP      The screen position is on the footing separator

                             line

       -5126  HTCOLSEP       The screen position is on a column separator

                             line

Button.ch contains manifest constants for the TBrowse:hitTest() return values.

insColumn() Insert a column object in a browse


insColumn(nPos, oColumn) → oColumn

This method allows a column object to be inserted into the middle of a browse. The return value is a reference to the column object being inserted.

invalidate() Forces redraw during next stabilization


invalidate() → self

TBrowse:invalidate() causes the next stabilization of the TBrowse object to redraw the entire TBrowse display, including headings, footings, and all data rows. Note that sending this message has no effect on the values in the data rows: it simply forces the display to be updated during the next stabilization. To force the data to be refreshed from the underlying data source, send the TBrowse:refreshAll() message.

refreshAll() Causes all data to be refreshed during the next stabilize


refreshAll() → self

Internally marks all data rows as invalid, causing them to be refilled and redisplayed during the next stabilization loop.

refreshCurrent() Causes current row to be refreshed on next stabilize


refreshCurrent() → self

Internally marks the current data row as invalid, causing it to be refilled and redisplayed during the next stabilization loop.

setColumn() Replaces one TBColumn object with another


setColumn(nColumn, oColumnNew) → oColumnCurrent

Replaces the TBColumn object indicated by nColumn with the TBColumn object specified by oColumnNew. The value returned is the current TBColumn object.

SetKey() Gets/sets a code block associated with an Inkey() value


SetKey(nKey [, bBlock]) → bPrevious

Gets and optionally sets the code block indicated by bBlock that is associated with the Inkey value specified by nKey. When replacing an existing keypress/code block definition, it returns the previous code block; otherwise, it returns the current one.

TBrowse:SetKey() Default Keypress/Code Block Definitions

       Inkey Value    Associated Code Block

       K_DOWN         { | oTB, nKey | oTB:Down(), TBR_CONTINUE }

       K_END          { | oTB, nKey | oTB:End(), TBR_CONTINUE }

       K_CTRL_PGDN    { | oTB, nKey | oTB:GoBottom(), TBR_CONTINUE }

       K_CTRL_PGUP    { | oTB, nKey | oTB:GoTop(), TBR_CONTINUE }

       K_HOME         { | oTB, nKey | oTB:Home(), TBR_CONTINUE }

       K_LEFT         { | oTB, nKey | oTB:Left(), TBR_CONTINUE }

       K_PGDN         { | oTB, nKey | oTB:PageDown(), TBR_CONTINUE }

       K_PGUP         { | oTB, nKey | oTB:PageUp(), TBR_CONTINUE }

       K_CTRL_END     { | oTB, nKey | oTB:PanEnd(), TBR_CONTINUE }

       K_CTRL_HOME    { | oTB, nKey | oTB:PanHome(), TBR_CONTINUE }

       K_CTRL_LEFT    { | oTB, nKey | oTB:PanLeft(), TBR_CONTINUE }

       K_CTRL_RIGHT   { | oTB, nKey | oTB:PanRight(), TBR_CONTINUE }

       K_RIGHT        { | oTB, nKey | oTB:Right(), TBR_CONTINUE }

       K_UP           { | oTB, nKey | oTB:Up(), TBR_CONTINUE }

       K_ESC          { | oTB, nKey | TBR_EXIT}

       K_LBUTTONDOWN  { | oTB, nKey | TBMouse(oTB, MRow(), MCol()) }

Key handlers may be queried, added, replaced, and removed from the dictionary. For example:

oTB:SetKey(K_ESC, { | oTB, nKey | TBR_EXIT })

A default key handler may be declared by specifying a value of 0 for nKey. Its associated code block will be evaluated each time TBrowse:ApplyKey() is called with a key value that is not contained in the dictionary. For example:

oTB:SetKey(0, { | oTB, nKey | DefTBProc(oTB, nKey) }

The example above calls a function named DefTBProc() when nKey is not contained in the dictionary.

To remove a keypress/code block definition, specify NIL for bBlock. For example:

oTB:SetKey(0, NIL }

setstyle() Maintains a dictionary within an object


setstyle(nStyle, [lSetting]) → self

TBrowse:setStyle() maintains a dictionary within a TBrowse object. This dictionary, which is simply an array, contains a set of logical values that determine behaviors associated with a TBrowse object. nStyle refers to the element in the dictionary that contains the style. lSetting indicates whether the style should be permitted or denied. Set to true (.T.) to allow the behavior to occur; otherwise, set to false (.F.) to prohibit it. CA-Clipper reserves the first four elements of the dictionary for predefined styles.

You may add custom styles to a TBrowse object by specifying any unused element of the dictionary. A maximum of 4096 definitions is available. When adding new styles to the dictionary, use the TBR_CUSTOM constant to ensure that the new styles will not interfere with the predefined ones. This guarantees that if more predefined styles are added in future releases of CA-Clipper, the positions of your styles in the dictionary will be adjusted automatically.

Styles are not utilized by the TBrowse object. The style dictionary is merely a convenient method of associating behaviors with a browse. The functions that query and implement these behaviors are external to the object. An example of this can be found in BrowSys.prg in the clip53samples subdirectory.

TBrowse Styles

       Number  TBrowse.ch     Meaning

       1       TBR_APPEND     Can the user add new information?

       2       TBR_MODIFY     Can the user modify the data in the browse’s

                              cells?

       3       TBR_MOVE       Can the user move the column to another

                              position in the browse?

       4       TBR_SIZE       Can the user modify the width of the column?

       5       TBR_CUSTOM     First available element for custom styles.

Tbrowse.ch contains manifest constants for TBrowse:setStyle().

Note: TBR_MOVE and TBR_SIZE are not implemented in CA-Clipper 5.3. They are reserved for future usage.

stabilize() Performs incremental stabilization


stabilize() → lStable

Performs incremental stabilization. Each time this message is sent, some part of the stabilization process is performed. Stabilization is performed in increments so that it can be interrupted by a keystroke or other asynchronous event.

If the TBrowse object is already stable, a value of true (.T.) is returned. Otherwise, a value of false (.F.) is returned indicating that further stabilization messages should be sent. The browse is considered stable when all data has been retrieved and displayed, the data source has been repositioned to the record corresponding to the browse cursor, and the current cell has been highlighted.

Examples

For fully operational examples of a TBrowse object, refer to
"Introduction to TBrowse" in the Programming and Utilities Guide and to
TbDemo.prg located in CLIP53SOURCESAMPLE.

Platforms

Available on MS-DOS

See also

TEXT*Harbour implementation⌃ | ☰

Display a literal block of text

Syntax

TEXT [TO PRINTER] [TO FILE <xcFile>]
   <text>...
ENDTEXT

Arguments

text is the block of literal characters to be displayed to the screen. Text is displayed exactly as formatted.

TO PRINTER echoes the display to the printer.

TO FILE xcFile echoes the display to the specified file. xcFile may be specified as a literal file name or as a character expression enclosed in parentheses. If no extension is specified, .txt is assumed.

Description

TEXT...ENDTEXT is a console command construct that displays a block of text to the screen, optionally echoing output to the printer and/or a text file. To suppress output to the screen while printing or echoing output to a file, SET CONSOLE OFF before the TEXT command line.

Text within the TEXT construct displays exactly as formatted, including any indentation. Hard carriage returns are output as new lines, soft carriage returns as the character Chr(141). Macro variables found within TEXT...ENDTEXT are expanded. However, macro expressions are not.

TEXT...ENDTEXT is a compatibility command and not recommended. CA-Clipper has other facilities for text processing and output. For example, MemoLine() in combination with MLCount() can word wrap long strings according to a specified line length. ? or @...SAY can display formatted text extracted from a long string with MemoLine().

Examples

■  This example demonstrates how to use TEXT...ENDTEXT to print a
   form letter:

   USE Sales NEW
   DO WHILE !Eof()
      FormLetter()
      SKIP
   ENDDO
   RETURN

   FUNCTION FormLetter
      LOCAL dDate := DToC(Date()), cSalesman := ;
               RTrim(Salesman)
      TEXT TO PRINTER
      &dDate.
      Dear &cSalesman.,
      How are you!
      ENDTEXT
      EJECT
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Time()Harbour implementation


⌃ | ☰

Return the system time

Syntax

Returns

Time() returns the system time as a character string in the form hh:mm:ss. hh is hours in 24-hour format, mm is minutes, and ss is seconds.

Description

Time() is a time function that displays the system time on the screen or prints it on a report. Time() is related to Seconds() which returns the integer value representing the number of seconds since midnight. Seconds() is generally used in place of Time() for time calculations.

Examples

■  These examples show the results of Time() used with SubStr()
   to extract the hour, minutes, and seconds digits:

   ? Time()                       // Result: 10:37:17
   ? SubStr(Time(), 1, 2)         // Result: 10
   ? SubStr(Time(), 4, 2)         // Result: 37
   ? SubStr(Time(), 7, 2)         // Result: 17

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Tone()Harbour implementation


⌃ | ☰

Sound a speaker tone for a specified frequency and duration

Syntax

Tone(<nFrequency>, <nDuration>) → NIL

Arguments

nFrequency is a positive numeric value indicating the frequency of the tone to be sounded.

nDuration is a positive numeric value indicating the duration of the tone measured in increments of 1/18 of a second. For example, an nDuration value of 18 represents one second.

For both arguments, non-integer values are truncated—not rounded—to their integer portion.

Returns

Tone() always returns NIL.

Description

Tone() is a sound function that indicates various program states to the user. These can be error states, boundary conditions, or the end of a time-consuming process. For example, an error state would sound an error tone before alerting the user with a message or interactive dialog box. A boundary condition might indicate that the user is attempting to move the cursor past the top or bottom of a column in a TBrowse object. A batch process also might indicate its completion with a sound to alert the user, in case the user has turned away from the screen.

Tone() works by sounding the speaker at the specified frequency for the specified duration. The duration is measured in increments of 1/18 of a second. The frequency is measured in hertz (cycles per second). Frequencies of less than 20 are inaudible. The table below shows the frequencies of standard musical notes.

Note: Tone() works only on IBM PC and 100 percent compatible computers.

Table of Musical Notes

    Pitch   Frequency    Pitch     Frequency

    C       130.80       mid C     261.70

    C#      138.60       C#        277.20

    D       146.80       D         293.70

    D#      155.60       D#        311.10

    E       164.80       E         329.60

    F       174.60       F         349.20

    F#      185.00       F#        370.00

    G       196.00       G         392.00

    G#      207.70       G#        415.30

    A       220.00       A         440.00

    A#      233.10       A#        466.20

    B       246.90       B         493.90

                         C         523.30

Examples

■  This example is a beep function that indicates that a batch
   operation has completed:

   FUNCTION DoneBeep
      Tone(300, 1)
      Tone(100, 1)
      Tone(300, 1)
      Tone(100, 1)
      RETURN NIL

■  This example is a tone sequence that indicates invalid
   keystrokes or boundary conditions:

   FUNCTION ErrorBeep
      Tone(100, 3)
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB, source file is SOURCE/SAMPLE/EXAMPLEA.ASM.

See also

TopBarMenu class⌃ | ☰

Create a top bar menu

Description

The top bar menu is used as a main menu in which pop-up menus reside.

Methods link

TopBar() Create a new TopBarMenu object


TopBar(nRow, nLeft, nRight) → oTopBar

Arguments

nRow is a numeric value that indicates the screen row of the top bar menu. This value is assigned to the TopBarMenu:row instance variable.

nLeft is a numeric value that indicates the left screen column of the top bar menu. This value is assigned to the TopBarMenu:left instance variable.

nRight is a numeric value that indicates the right screen column of the top bar menu. This value is assigned to the TopBarMenu:right instance variable.

Returns

Returns a TopBarMenu object when all of the required arguments are present; otherwise, TopBar() returns NIL.

Exported Instance Variables


cargo User-definable variable


cargo (Assignable)

Contains a value of any type that is ignored by the TopBarMenu object. TopBarMenu:cargo is provided as a user-definable slot allowing arbitrary information to be attached to a TopBarMenu object and retrieved later.

colorSpec Indicates colors used by the top bar menu’s display() method


colorSpec (Assignable)

Contains a character string that indicates the color attributes that are used by the top bar menu’s display() method. The string must contain six color specifiers.

TopBarMenu Color Attributes

       Position     Applies To                          Default Value from

       in colorSpec                                     System Color Setting

       1            The top bar menu items that are not       Unselected

                    selected

       2            The selected top bar menu item            Enhanced

       3            The accelerator key for unselected top    Background

                    bar menu items

       4            The accelerator key for the selected top  Enhanced

                    bar menu item

       5            Disabled top bar menu items               Standard

       6            The top bar menu’s border                 Border

Note: The colors available to a DOS application are more limited than those for a Windows application. The only colors available to you here are listed in the drop-down list box of the Properties Workbench window for that item.

current Numeric value indicating which item is selected


current (Assignable)

Contains a numeric value that indicates which item is selected.

itemCount Numeric value indicating total number of items in TopBarMenu


itemCount

Contains a numeric value that indicates the total number of items in the TopBarMenu object.

left Numeric value indicating the top bar menu’s leftmost column


left (Assignable)

Contains a numeric value that indicates the top bar menu’s leftmost column

right Numeric value indicating the top bar menu’s rightmost column


right (Assignable)

Contains a numeric value that indicates the top bar menu’s rightmost column

row Numeric value indicating row where the top bar menu appears


row (Assignable)

Contains a numeric value that indicates the row that the top bar menu appears on.

addItem() Appends a new item to a top bar menu


oTopBar:addItem(oMenuItem) → self

oMenuItem is the MenuItem object to be added.

addItem() is a method of the TopBarMenu class that is used for appending a new item to a top bar menu.

delItem() Removes an item from a top bar menu


oTopBar:delItem(nPosition) → self

nPosition is a numeric value that indicates the position in the top bar menu of the item to be deleted.

delItem() is a method of the TopBarMenu class that is used for removing an item from a top bar menu. When an item is deleted, the items which follow it move up a line.

display() Shows a top bar menu and its items on the screen


oTopBar:display() → self

display() is a method of the TopBarMenu class that is used for showing a top bar menu and its items on the screen. It also shows the status bar description for menu items that contain one. display() uses the values of the following instance variables to correctly show the list in its current context, in addition to providing maximum flexibility in the manner a top bar menu appears on the screen: colorSpec, current, itemCount, left, right, and row.

Note: See the MenuModal() function in this guide for more information about displaying and activating a top menu bar.

getFirst() Determines position of the first selectable item in a menu


oTopBar:getFirst() → nPosition

Returns a numeric value that indicates the position within the top bar menu of the first selectable item. getFirst() returns 0 in the event that the top bar menu does not contain a selectable item.

getFirst() is a method of the TopBarMenu class that is used for determining the position of the first selectable item in a top bar menu. The term selectable is defined as a menu item that is enabled and whose caption is not a menu separator.

Note: getFirst() does not change the currently selected menu item. In order to change the currently selected top bar menu item, you must call the TopBarMenu:select() method.

getItem() Accesses a MenuItem object after it has been added to a menu


oTopBar:getItem(nPosition) → self

nPosition is a numeric value that indicates the position in the top bar menu of the item that is being retrieved.

getItem() is a method of the TopBarMenu class that is used for accessing a MenuItem object after it has been added to a top bar menu.

getLast() Determines position of the last selectable item in a menu


oTopBar:getLast() → nPosition

Returns a numeric value that indicates the position within the top bar menu of the last selectable item. getLast() returns 0 in the event that the top bar menu does not contain a selectable item.

getLast() is a method of the TopBarMenu class that is used for determining the position of the last selectable item in a top bar menu. The term selectable is defined as a menu item that is enabled and whose caption, is not a menu separator.

Note: getLast() does not change the currently selected menu item. In order to change the currently selected top bar menu item, you must call the TopBarMenu:select() method.

getNext() Determines position of the next selectable item in a menu


oTopBar:getNext() → nPosition

Returns a numeric value that indicates the position within the top bar menu of the next selectable item. getNext() returns 0 in the event that the current item is the last selectable item or the top bar menu does not contain a selectable item.

getNext() is a method of the TopBarMenu class that is used for determining the position of the next selectable item in a top bar menu. getNext() searches for the next selectable item starting at the item immediately after the current item. The term selectable is defined as a menu item that is enabled and whose caption is not a menu separator.

Note: getNext() does not change the currently selected menu item. In order to change the currently selected top bar menu item, you must call the TopBarMenu:select() method.

getPrev() Determines position of previous selectable item in a menu


oTopBar:getPrev() → nPosition

Returns a numeric value that indicates the position within the top bar menu of the previous selectable item. getPrev() returns 0 in the event that the current item is the first selectable item or the top bar menu does not contain a selectable item.

getPrev() is a method of the TopBarMenu class that is used for determining the position of the previous selectable item in a top bar menu. getPrev() searches for the previous selectable item starting at the item immediately before the current item. The term selectable is defined as a menu item that is enabled and whose caption is not a menu separator.

Note: getPrev() does not change the currently selected menu item. In order to change the currently selected top bar menu item, you must call the TopBarMenu:select() method.

getAccel() Determines if a key press is interpreted as a user request


oTopBar:getAccel(nInkeyValue) → nPosition

nInkeyValue is a numeric value that indicates the inkey value to be checked.

Returns a numeric value that indicates the position in the top bar menu of the first item whose accelerator key matches that which is specified by nInkeyValue. The accelerator key is defined using the & character in MenuItem:caption.

getAccel() is a method of the TopBarMenu class that is used for determining whether a key press should be interpreted as a user request to evoke the data variable of a particular top bar menu item.

HitTest() Indicates position of mouse cursor relative to menu


oTopBar:hitTest(nMouseRow, nMouseCol)

→ nHitStatus

nMouseRow is a numeric value that indicates the current screen row position of the mouse cursor.

nMouseCol is a numeric value that indicates the current screen column position of the mouse cursor.

Returns a numeric value that indicates the relationship of the mouse cursor with the top bar menu.

Hit Test Return Values

       Value   Constant       Description

       > 0     Not applicable The position in the top bar menu of the item

                              whose region the mouse is within

       0       HTNOWHERE      The mouse cursor is not within the region of

                              the screen that the top bar menu occupies

       -1      HTTOPLEFT      The mouse cursor is on the top-left corner of

                              the top bar menu’s border

       -2      HTTOP          The mouse cursor is on the top bar menu’s top

                              border

       -3      HTTOPRIGHT     The mouse cursor is on the top-right corner of

                              the top bar menu’s border

       -4      HTRIGHT        The mouse cursor is on the top bar menu’s right

                              border

       -5      HTBOTTOMRIGHT  The mouse cursor is on the bottom-right corner

                              the top bar menu’s border

       -6      HTBOTTOM       The mouse cursor is on the top bar menu’s

                              bottom border

       -7      HTBOTTOMLEFT   The mouse cursor is on the bottom-left corner

                              of the top bar menu’s border

       -8      HTLEFT         The mouse cursor is on the top bar menu’s left

                              border

Button.ch contains manifest constants for the TopBarMenu:hitTest() return value.

HitTest() is a method of the TopBarMenu class that is used for determining if the mouse cursor is within the region of the screen that the Top bar menu occupies.

insItem() Inserts a new item in a top bar menu


oTopBar:insItem(nPosition, oMenuItem) → self

nPosition is a numeric value that indicates the position at which the new menu item is inserted.

oMenuItem is the MenuItem object to be inserted.

insItem() is a method of the TopBarMenu class that is used for inserting a new item in a top bar menu.

Select() Changes the selected item


oTopBar:select(nPosition) → self

nPosition indicates the position in the top bar menu of the item to be selected.

Select() is a method of the TopBarMenu class that is used for changing the selected item. Its state is typically changed when one of the arrow keys is pressed or the mouse’s left button is pressed when its cursor is within the top bar menu’s screen region.

setItem() Replaces a MenuItem object after it has been added to a menu


oTopBar:setItem(nPosition, oMenuItem) → self

nPosition is a numeric value that indicates the position in the top bar menu of the item that is being retrieved.

oMenuItem is the MenuItem object that replaces the one in the top bar menu specified by nPosition.

setItem() is a method of the TopBarMenu class that is used for replacing a MenuItem object after it has been added to a top bar menu. After the setItem() method is called, the display() method needs to be called in order to refresh the menu.

Examples

See the Menu.prg sample file in the CLIP53SOURCESAMPLE directory.
This example demonstrates combining TopBarMenu, PopUpMenu, and MenuItem
objects to create a menu with a number of available choices.  See
"Introduction to the Menu System" in the Programming and Utilities Guide
for more information about using this class.

Platforms

Available on MS-DOS

See also

TOTALHarbour implementation⌃ | ☰

Summarize records by key value to a database (.dbf) file

Syntax

TOTAL ON <expKey> [FIELDS <idField list>]
   TO <xcDatabase>
   [<scope>] [WHILE <lCondition>] [FOR <lCondition>]

Arguments

ON expKey defines the group of records that produce a new record in the target database file. To make the summarizing operation accurate, the source database file should be INDEXed or SORTed on this expression.

FIELDS idField list specifies the list of numeric fields to TOTAL. If the FIELDS clause is not specified, no numeric fields are totaled. Instead each numeric field in the target file contains the value for the first record matching the key expression.

TO xcDatabase is the name of the target file that will contain the copy of the summarized records. Specify this argument as a literal file name or as a character expression enclosed in parentheses. Unless otherwise specified, TOTAL assumes a .dbf extension.

scope is the portion of the current database file to TOTAL. The default is ALL records.

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

FOR lCondition specifies the conditional set of records to TOTAL within the given scope.

Description

TOTAL is a database command that sequentially processes the current database file, summarizing records by the specified key value and copying them to a new database file. TOTAL works by first copying the structure of the current database file to xcDatabase, except for memo fields. It then sequentially scans the current database file within the specified scope of records. As each record with a unique expKey value is encountered, that record is copied to the new database file. The values of numeric fields specified in idField list from successive records with the same expKey value are added to fields with the same names in xcDatabase. Summarization proceeds until a record with a new key value is encountered. The process is then repeated for this record.

Since TOTAL processes the source database file sequentially, it must be INDEXed or SORTed in expKey order for the summarization to be correct.

To successfully TOTAL numeric fields, the source numeric fields must be large enough to hold the largest total possible for that numeric field. If not, a runtime error is generated.

Notes

■ Deleted source records: If DELETED is OFF, deleted records in

the source file are TOTALed. Records in the target xcDatabase inherit the deleted status of the first matching record in the source file, just as nontotaled fields inherit their values. If DELETED is ON, however, none of the deleted source records are TOTALed.

Examples

■  In this example, a database file is TOTALed ON the key
   expression of the controlling index using a macro expression.  When
   the macro expression is encountered, the expression is evaluated and
   the resulting character string is substituted for the TOTAL <expKey>
   argument:

   USE Sales INDEX Branch NEW
   TOTAL ON &(IndexKey(0)) FIELDS Amount TO Summary

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

AVERAGE, INDEX, SORT, SUM

Transform()Harbour implementation


⌃ | ☰

Convert any value into a formatted character string

Syntax

Transform(<exp>, <cSayPicture>) → cFormatString

Arguments

exp is the value to be formatted. This expression can be any valid CA-Clipper data type except array, code block, and NIL.

cSayPicture is a string of picture and template characters that describes the format of the returned character string.

Returns

Transform() converts exp to a formatted character string as defined by cSayPicture.

Description

Transform() is a conversion function that formats character, date, logical, and numeric values according to a specified picture string that includes a combination of picture function and template strings. Transform() formats data for output to the screen or the printer in the same manner as the PICTURE clause of the @...SAY command.

■ Function string: A picture function string specifies

formatting rules that apply to the Transform() return value as a whole, rather than to particular character positions within exp. The function string consists of the @ character, followed by one or more additional characters, each of which has a particular meaning (see table below). If a function string is present, the @ character must be the leftmost character of the picture string, and the function string must not contain spaces. A function string may be specified alone or with a template string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

Transform() Functions

       Function     Action

       B            Displays numbers left-justified

       C            Displays CR after positive numbers

       D            Displays date in SET DATE format

       E            Displays date in British format

       R            Nontemplate characters are inserted

       X            Displays DB after negative numbers

       Z            Displays zeros as blanks

       (            Encloses negative numbers in parentheses

       !            Converts alphabetic characters to uppercase

■ Template string: A picture template string specifies

formatting rules on a character-by-character basis. The template string consists of a series of characters, some of which have special meanings (see table below). Each position in the template string corresponds to a position in the value of the exp argument. Because Transform() uses a template, it can insert formatting characters such as commas, dollar signs, and parentheses.

Characters in the template string that have no assigned meanings are copied literally into the return value. If the @R picture function is used, these characters are inserted between characters of the return value; otherwise, they overwrite the corresponding characters of the return value. A template string may be specified alone or with a function string. If both are present, the function string must precede the template string, and the two must be separated by a single space.

Transform() Templates

       Template     Action

       A,N,X,9,#    Displays digits for any data type

       L            Displays logicals as «T» or «F»

       Y            Displays logicals as «Y» or «N»

       !            Converts an alphabetic character to uppercase

       $            Displays a dollar sign in place of a leading space in a

                    numeric

       *            Displays an asterisk in place of a leading space in a

                    numeric

       .            Specifies a decimal point position

       ,            Specifies a comma position

Examples

■  This example formats a number into a currency format using a
   template:

   ? Transform(123456, "$999,999")    // Result: $123,456

■  This example formats a character string using a function:

   ? Transform("to upper", "@!")      // Result: TO UPPER

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Trim()→ RTrim()Harbour implementation


⌃ | ☰

Remove trailing spaces from a character string

Syntax

Trim(<cString>) → cTrimString

Arguments

cString is the character string to be copied without trailing spaces.

Returns

Trim() returns a copy of cString with the trailing spaces removed. If cString is a null string («») or all spaces, Trim() returns a null string («»).

Description

Trim() is a character function that formats character strings. It is useful when you want to delete trailing spaces while concatenating strings. This is typically the case with database fields which are stored in fixed-width format. For example, you can use Trim() to concatenate first and last name fields to form a name string.

Trim() is related to LTrim(), which removes leading spaces, and AllTrim(), which removes both leading and trailing spaces. The inverse of AllTrim(), LTrim(), and RTrim() are the PadC(), PadR(), and PadL() functions which center, right-justify, or left-justify character strings by padding them with fill characters.

Notes

■ Space characters: The Trim() function treats carriage

returns, line feeds, and tabs as space characters and removes these as well.

Examples

■  This is a user-defined function in which Trim() formats city,
   state, and zip code fields for labels or form letters:

   FUNCTION CityState(cCity, cState, cZip)
      RETURN Trim(cCity) + ", " ;
       + Trim(cState) + "  " + cZip

■  In this example the user-defined function, CityState(),
   displays a record from Customer.dbf:

   USE Customer INDEX CustName NEW
   SEEK "Kate"

   ? CityState(City, State, ZipCode)
   // Result: Athens, GA 10066

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Type()Harbour implementation


⌃ | ☰

Determine the type of an expression

Syntax

Arguments

cExp is a character expression whose type is to be determined. cExp can be a field, with or without the alias, a private or public variable, or an expression of any type.

Returns

Type() returns one of the following characters:

Type() Return Values

    Returns   Meaning

    A         Array

    B         Block

    C         Character

    D         Date

    L         Logical

    M         Memo

    N         Numeric

    O         Object

    U         NIL, local, or static

    UE        Error syntactical

    UI        Error indeterminate

Description

Type() is a system function that returns the type of the specified expression. It can test expression validity as long as the expression uses CLIPPER.LIB functions and does not reference local or static variables, user-defined functions, or built-in functions supplied in EXTEND.LIB.

Type() is like ValType() but uses the macro operator (&) to determine the type of the argument. This precludes the use of Type() to determine the type of local and static variables. ValType(), by contrast, evaluates an expression and determines the data type of the return value. This lets you determine the type of user-defined functions as well as local and static variables.

Notes

■ Array references: References to private and public arrays

return «A.» References to array elements return the type of the element.

IF(): To return the appropriate data type for an IF()

expression, Type() evaluates the condition, and then, returns the type of the evaluated path. If either the IF() condition or the evaluated path are invalid, Type() returns «UE.»

■ Testing parameters: Type() can only test the validity of

parameters received using the PARAMETERS statement. Testing a parameter declared as part of a FUNCTION or PROCEDURE declaration always returns «U» because local parameters do not have a symbol in the symbol table. To determine whether an argument was skipped or left off the end of the argument list, compare the parameter to NIL or use ValType().

■ User-defined and EXTEND.LIB functions: If a reference is made

anywhere in an expression to a function not found in CLIPPER.LIB (a user-defined or EXTEND.LIB function), Type() returns «UI.» If the user-defined function is not linked into the current program, Type() returns «U.»

Examples

■  These examples demonstrate various results from invocations of
   Type():

   ? Type('SubStr("Hi There", 4, 5)')      // Result: C
   ? Type("UDF()")                         // Result: UI
   ? Type('IF(.T., "true", 12)')           // Result: C

■  This example shows two methods for testing for the existence
   and type of declared parameters:

   FUNCTION TestParams
      PARAMETERS cParam1, nParam2
      IF cParam1 = NIL
         ? "First parameter was not passed"
         cParam1 := "Default value"
      ENDIF

      IF Type('nParam2') == "U"
         ? "Second parameter was not passed"
      ENDIF
      .
      . <statements>
      .
      RETURN NIL

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

TYPEHarbour implementation⌃ | ☰

Display the contents of a text file

Syntax

TYPE <xcFile> [TO PRINTER] [TO FILE <xcOutFile>]

Arguments

xcFile is the name of the file, including extension, to be displayed to the screen. This argument may be specified as a literal file name or as a character expression enclosed in parentheses. xcFile must be specified with an extension if it has one.

TO PRINTER echoes the display to the printer.

TO FILE xcOutFile echoes the display to the specified file. xcOutFile may be specified either as a literal file name or as a character expression enclosed in parentheses. If no extension is specified, .txt is added.

Description

TYPE is a console command that displays the contents of a text file to the screen, optionally echoing the display to the printer and/or another text file. To suppress output to the screen while printing or echoing output to a file, SET CONSOLE OFF before the TYPE invocation.

If xcFile is specified without a path and/or drive designator, TYPE searches the current DEFAULT directory, and then, the current PATH. If xcOutFile is specified without a path and/or drive designator, TYPE creates the file in the current DEFAULT directory.

TYPE performs no special formatting on the listing. There are no special headings or pagination when the output is sent to the printer.

To pause output, use Ctrl-S. Note that you cannot interrupt a listing with Esc.

Examples

■  This example illustrates the TYPE command:

   TYPE Main.prg TO PRINTER

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

See also

UNLOCKHarbour implementation⌃ | ☰

Release file/record locks set by the current user

Syntax

Arguments

ALL releases all current locks in all work areas. If not specified, only the lock in the current work area is released.

Description

UNLOCK is a network command that releases file or record locks set by the current user. Use it when you want to release the current lock without setting a new lock. Both FLock() and RLock() release the current lock before setting a new one.

After an UNLOCK, an update to a shared database file and associated index and memo files becomes visible to DOS and other applications, but is not guaranteed to appear on disk until you perform a COMMIT or close the file.

Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information on the principles of locking and update visibility.

Notes

SET RELATION: UNLOCK does not automatically release a record

lock along a RELATION chain unless you UNLOCK ALL.

Examples

■  This example attempts an update operation that requires a
   record lock.  If the RLock() is successful, the record is updated
   with a user-defined function and the RLock() is released with UNLOCK:

   USE Sales INDEX Salesman SHARED NEW
   IF RLock()
      UpdateRecord()
      UNLOCK
   ELSE
      ? "Record update failed"
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Updated()Harbour implementation


⌃ | ☰

Determine whether a GET changed during a READ

Syntax

Returns

Updated() returns true (.T.) if data in a GET is added or changed; otherwise, it returns false (.F.).

Description

Updated() determines whether characters were successfully entered into a GET from the keyboard during the most current READ. Each time READ executes, Updated() is set to false (.F.). Then, any change to a GET entered from the keyboard sets Updated() to true (.T.) after the user successfully exits the GET. If the user presses Esc before exiting the first GET edited, Updated() remains false (.F.). Once Updated() is set to true (.T.), it retains this value until the next READ is executed.

Within a SET KEY or VALID procedure, you can change the current GET variable using the KEYBOARD command or by assigning a new value with one of the many assignment operators. Changing the variable with KEYBOARD is the same as if the user had entered the change directly from the keyboard, and Updated() is set accordingly. However, since Updated() reflects only those changes made from the keyboard, an assignment to the GET variable does not affect Updated().

Examples

■  This example assigns field values from Customer.dbf to
   variables and edits them.  If the user changes any of the values, the
   field variables for the current record are updated with the new
   values:

   USE Customer NEW
   CLEAR
   MEMVAR->Customer = Customer->Customer
   MEMVAR->Address = Customer->Address
   @ 1, 1 SAY "Name:" GET MEMVAR->Customer
   @ 2, 1 SAY "Address:" GET MEMVAR->Address
   READ
   //
   IF Updated()
      Customer->Customer := MEMVAR->Customer
      Customer->Address := MEMVAR->Address
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Upper()Harbour implementation


⌃ | ☰

Convert lowercase characters to uppercase

Syntax

Upper(<cString>) → cUpperString

Arguments

cString is the character string to be converted.

Returns

Upper() returns a copy of cString with all alphabetical characters converted to uppercase. All other characters remain the same as in the original string.

Description

Upper() is a character function that converts lowercase and mixed case strings to uppercase. It is related to Lower() which converts uppercase and mixed case strings to lowercase. Upper() is related to the IsUpper() and IsLower() functions which determine whether a string begins with an uppercase or lowercase letter.

Upper() is generally used to format character strings for display purposes. It can, however, be used to normalize strings for case- independent comparison or INDEXing purposes.

Examples

■  These examples illustrate the effects of Upper():

   ? Upper("a string")           // Result: A STRING
   ? Upper("123 char = <>")      // Result: 123 CHAR = <>

■  This example uses Upper() as part of a case-independent
   condition:

   USE Customer INDEX CustName NEW
   LIST CustName FOR "KATE" $ Upper(Customer)

■  Upper() is also useful for creating case-independent index key
   expressions:

   USE Customer NEW
   INDEX ON Upper(Last) TO CustLast

■  Later, use the same expression to look up Customers:

   MEMVAR->Last = Space(15)
   @ 10, 10 GET MEMVAR->Last
   READ

   SEEK Upper(MEMVAR->Last)

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

UPDATEHarbour implementation⌃ | ☰

Update current database file from another database file

Syntax

UPDATE FROM <xcAlias>
   ON <expKey> [RANDOM]
   REPLACE <idField> WITH <exp>
   [, <idField2> WITH    <exp2>...]

Arguments

FROM xcAlias specifies the alias of the work area used to update records in the current work area. This argument may be specified either as a literal file name or as a character expression enclosed in parentheses.

ON expKey specifies the expression that defines matching records in the FROM work area.

REPLACE idField specifies a field in the current work area to replace with a new value.

WITH exp specifies the value to replace into the current field. You must reference any field contained in the FROM work area with the correct alias.

RANDOM allows records in the FROM database file to be in any order. If this option is specified, the current database file must be indexed on expKey.

Description

UPDATE is a database command that replaces fields in the current work area with values from another work area based on the specified key expression. UPDATE is designed to update only current work area records based on a one-to-one or one-to-many relation with the FROM work area. This means that UPDATE can only update records in the current work area with unique key values. When there is more than one instance of a key value, only the first record with the key value is updated. The FROM work area, however, can have duplicate key values.

There are two formulations of the command depending on whether the FROM work area records are sorted or indexed on expKey or not. If RANDOM is not specified, both the current work area and the FROM work area must be indexed or sorted in expKey order. If RANDOM is specified, the current work area must be indexed by expKey, but the FROM work area records can be in any order.

To use UPDATE in a network environment, the current database file must be locked with FLock() or USEed EXCLUSIVEly. The FROM database file may be used in any mode. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Notes

■ Deleted records: If DELETED is OFF, deleted records in both

source files are processed. Records in the file being updated retain their deleted status and are not affected by the deleted status of records in the FROM file. If DELETED is ON, however, no deleted records are processed from either source file.

Examples

■  This example UPDATEs the Customer database file with
   outstanding invoice amounts:

   USE Invoices NEW
   USE Customer INDEX Customer NEW
   UPDATE FROM Invoices ON Last;
      REPLACE Owed WITH Owed + Invoices->Amount RANDOM

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

dbCreateIndex(), INDEX, JOIN, REPLACE, SET UNIQUE*, SORT

Used()Harbour implementation


⌃ | ☰

Determine whether a database file is in USE

Syntax

Returns

Used() returns true (.T.) if there is a database file in USE; otherwise, it returns false (.F.).

Description

Used() is a database function that determines whether there is a database file in USE in a particular work area. By default, Used() 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.

Examples

■  This example determines whether a database file is in USE in
   the current work area:

   USE Customer NEW
   ? Used()               // Result: .T.
   CLOSE
   ? Used()               // Result: .F.

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

USEHarbour implementation⌃ | ☰

Open an existing database (.dbf) and its associated files

Syntax

USE [<xcDatabase>
   [INDEX <xcIndex list>]
   [ALIAS <xcAlias>] [EXCLUSIVE | SHARED]
   [NEW] [READONLY]
   [VIA <cDriver>]]

Arguments

xcDatabase is the name of the database file to be opened and may be specified either as a literal file name or as a character expression enclosed in parentheses.

INDEX xcIndex list specifies the names of 1 to 15 index files to be opened in the current work area. Specify each index as a literal file name or as a character expression enclosed in parentheses. The first index in the list becomes the controlling index. If you specify an xcIndex as an expression and the value returned is spaces or NIL, it is ignored.

ALIAS xcAlias specifies the name to associate with the work area when the database file is opened. You may specify the alias name as a literal name or as a character expression enclosed in parentheses. A valid xcAlias may be any legal identifier (i.e., it must begin with an alphabetic character and may contain numeric or alphabetic characters and the underscore). Within a single application, CA-Clipper will not accept duplicate aliases. If this clause is omitted, the alias defaults to the database file name.

EXCLUSIVE opens the database file for nonshared use in a network environment. All other users are denied access until the database file is CLOSEd.

SHARED opens the database file for shared use in a network environment. Specifying this clause overrides the current EXCLUSIVE setting.

NEW opens xcDatabase in the next available work area making it the current work area. If this clause is not specified, xcDatabase is opened in the current work area.

READONLY opens xcDatabase with a read-only attribute. This lets you open database files marked read-only. If you cannot open the xcDatabase this way, a runtime error is generated. If this clause is not specified, xcDatabase is opened as read-write.

VIA cDriver specifies the replaceable database driver (RDD) with which to process the current work area. cDriver is the name of the RDD specified as a character expression. If cDriver is specified as a literal value, it must be enclosed in quotes.

If the VIA clause is omitted, the DBFNTX driver is used by default. Note that if the specified driver is not linked, an unrecoverable error occurs.

In no arguments are specified, the database file open in the current work area is closed.

Description

USE opens an existing database (.dbf) file, its associated memo (.dbt) file, and optionally associated index (.ntx or .ndx) file(s) in the current or the next available work area. In CA-Clipper, there are 250 work areas with a maximum of 255 total files open in DOS 3.3 and above. Before USE opens a database file and its associated files, it closes any active files already open in the work area. When a database file is first opened, the record pointer is positioned at the first logical record in the file (record one, if there is no index file specified).

In a network environment, you may open database files as EXCLUSIVE or SHARED. EXCLUSIVE precludes the USE of the database file by other users until the file is closed. SHARED allows other users to USE the database file for concurrent access. If the database file is SHARED, responsibility for data integrity falls upon the application program. In CA-Clipper, FLock() and RLock() are the two basic means of denying other users access to a particular work area or record. If a USE is specified and neither EXCLUSIVE nor SHARED is specified, the database file is opened according to the current EXCLUSIVE setting. In CA-Clipper, all USE commands should explicitly specify how the database file is to be opened, EXCLUSIVE or SHARED. The implicit open mode specified by SET EXCLUSIVE is supplied for compatibility purposes only and not recommended.

Opening a database file in a network environment requires some special handling to be successful. First, attempt to USE the database file without specifying the INDEX list. Then, test for the success of the operation using NetErr(). If NetErr() returns false (.F.), the open operation succeeded and you can SET INDEX TO the index list. A USE will fail in a network environment if another user has EXCLUSIVE USE of the database file. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information on opening files in a network environment.

You can open index files with USE or SET INDEX. The first index in the list of indexes defines the current ordering of records when they are accessed. This index is referred to as the controlling index. You can change the current controlling index without closing any files by using the SET ORDER command.

To close a database and its associated files in the current work area, specify USE or CLOSE with no arguments. To close database files in all work areas, use CLOSE DATABASEs. To close index files in the current work area without closing the database file, use CLOSE INDEX or SET INDEX TO with no arguments.

Refer to the «Basic Concepts» chapter in the Programming and Utilities Guide for more information about the CA-Clipper database paradigm.

Notes

■ Setting the maximum open files: Control of the number of file

handles available to a CA-Clipper application is controlled by a combination of the CONFIG.SYS FILES command, and the F parameter of the CLIPPER environment variable. The F parameter specifies the maximum number of files that can be opened at any one time within the current CA-Clipper program. CA-Clipper determines the number of files that can be opened using the smaller of the two parameters. For example, if the FILES command is set to 120 and the F parameter is set to 50, the maximum number of files that can be opened is 50. In a network environment, file handles also need to be set in the network configuration file.

The file limit is controlled by the operating system. Under DOS versions less than 3.3, the maximum number of files that can be opened at one time is 20 files. In DOS versions 3.3 and greater, the maximum limit is 255 files.

■ Opening the same database file in more than one work area:

Although opening a database file in more than one work area is possible in a network environment, this practice is strongly discouraged. If done, each file must be opened with a different alias, otherwise a runtime error will occur.

■ Opening two database files with the same names, in different

directories: Although opening two database files with the same names in different directories is possible, the database files MUST have unique alias names; otherwise, a runtime error will occur.

Examples

■  This example opens a shared database file with associated
   index files in a network environment.  If NetErr() returns false
   (.F.), indicating the USE was successful, the indexes are opened:

   USE Accounts SHARED NEW
   IF !NetErr()
      SET INDEX TO AcctNames, AcctZip
   ELSE
      ? "File open failed"
      BREAK
   ENDIF

■  This example opens a database file with several indexes
   specified as extended expressions.  Note how the array of index names
   is created as a constant array:

   xcDatabase = "MyDbf"
   xcIndex = {"MyIndex1", "MyIndex2", "MyIndex3"}
   USE (xcDatabase) INDEX (xcIndex[1]), ;
         (xcIndex[2]), (xcIndex[3])

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Val()Harbour implementation


⌃ | ☰

Convert a character number to numeric type

Syntax

Arguments

cNumber is the character expression to be converted.

Returns

Val() returns cNumber converted to a numeric value including decimal digits.

Description

Val() is a character conversion function that converts a character string containing numeric digits to a numeric value. When Val() is executed, it evaluates cNumber until a second decimal point, the first non-numeric character, or the end of the expression is encountered. Leading spaces are ignored. When SET FIXED is ON, Val() returns the number of decimal places specified by SET DECIMALS, rounding cNumber if it is specified with more digits than the current DECIMALS value. As with all other functions that round, digits between zero and four are rounded down, and digits between five and nine are rounded up. When SET FIXED is OFF, Val() returns the number of decimal places specified in cNumber.

Val() is the opposite of Str() and Transform(), which convert numeric values to character strings.

Examples

■  These examples illustrate Val() with SET FIXED ON and SET
   DECIMALS TO 2:

   SET DECIMALS TO 2
   SET FIXED ON
   //
   ? Val("12.1234")         // Result:   12.12
   ? Val("12.1256")         // Result:   12.13
   ? Val("12A12")           // Result:   12
   ? Val("A1212")           // Result:      0
   ? Val(Space(0))          // Result:      0
   ? Val(Space(1))          // Result:      0
   ? Val(" 12.12")          // Result:   12.12

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

ValType()Harbour implementation


⌃ | ☰

Determine the data type returned by an expression

Syntax

Arguments

exp is an expression of any type.

Returns

ValType() returns a single character representing the data type returned by exp. ValType() returns one of the following characters:

ValType() Return Values

    Returns   Meaning

    A         Array

    B         Block

    C         Character

    D         Date

    L         Logical

    M         Memo

    N         Numeric

    O         Object

    U         NIL

Description

ValType() is a system function that takes a single argument, evaluates it, and returns a one-character string describing the data type of the return value. It is similar to Type(), but differs by actually evaluating the specified argument and determining the type of the return value. For this reason, you can determine the type of local and static variables, user-defined functions, and EXTEND.LIB functions. Type(), by contrast, uses the macro operator (&) to evaluate the type of its argument. Note that if the argument does not exist, an error («undefined error») will occur, unlike TYPE which will return «U.»

Examples

■  These examples show the return values for several data types:

   ? ValType(1)                // Result: N
   ? ValType("GOOB")           // Result: C
   ? ValType(NIL)              // Result: U
   ? ValType(array)            // Result: A
   ? ValType(block)            // Result: B

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Version()Harbour implementation


⌃ | ☰

Returns CA-Clipper version

Syntax

Returns

Version() returns the version number of the CA-Clipper library, EXTEND.LIB, as a character value.

Description

Version() is an environment function that returns the version of the CA-Clipper library, EXTEND.LIB.

Platforms

Available on MS-DOS

File

Library is EXTEND.LIB.

WAIT*Harbour implementation⌃ | ☰

Suspend program processing until a key is pressed

Syntax

WAIT [<expPrompt>] [TO <idVar>]

Arguments

expPrompt is an expression of any data type displayed as a prompt. If no expPrompt is specified, the default prompt displayed is: «Press any key to continue…»

TO idVar is the variable, of any storage class, that holds the value of the key pressed as a character value. If idVar does not exist or is not visible, it is created as a private variable and then assigned the character value.

Description

WAIT is a console command and wait state that displays a prompt after sending a carriage return/line feed to the screen. It then waits for the user to press a key. If the TO clause is specified, idVar is assigned the keystroke as a character value. If an Alt or Ctrl key is pressed, WAIT assigns Chr(0) to idVar. Non-alphanumeric values entered by pressing an Alt-keypad combination assign the specified character. If the character can be displayed, it is echoed to the screen. Function keys are ignored unless assigned with SET FUNCTION or SET KEY.

WAIT is a compatibility command and, therefore, is not recommended for general usage. It is superseded by both @...GET/READ and Inkey() for getting single character input.

Notes

WAITing without a prompt: To pause execution without

displaying a prompt, specify WAIT, null string («»), or Inkey(0). The latter is recommended since it does not disturb the current screen cursor position.

Examples

■  This example illustrates how to store the WAIT keystroke as an
   array element:

   aVar := Array(6)

   WAIT "Press a key..." TO aVar[1]
   ? aVar[1]                  // Result: key pressed in
                              // response to WAIT
   ? aVar[2]                  // Result: NIL
   ? ValType(aVar)            // Result: A
   ? ValType(aVar[1])         // Result: C

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

Word()*Harbour implementation


⌃ | ☰

Convert CALL command numeric parameters from double to integer values

Syntax

Arguments

nNumber is the numeric value to be converted to an integer specified in the range of plus or minus 32,767, inclusive.

Returns

Used as an argument for the CALL command, Word() returns an integer. In all other contexts, it returns NIL.

Description

Word() is a numeric conversion function that converts numeric parameters of the CALL command from double to integer values. Word() is a compatibility command and, therefore, not recommended. Both the CALL command and the Word() function are superseded by facilities provided by the Extend System. Refer to the «Using the Extend System» chapter in the Technical Reference Guide for more information.

Examples

■  This example uses Word() as an argument of the CALL command:

   CALL Cproc WITH Word(30000), "Some text"

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

Year()Harbour implementation


⌃ | ☰

Convert a date value to the year as a numeric value

Syntax

Arguments

dDate is the date value to be converted.

Returns

Year() returns the year of the specified date value including the century digits as a four-digit numeric value. The value returned is not affected by the current DATE or CENTURY format. Specifying a null date (CToD(«»)) returns zero.

Description

Year() is a date conversion function that converts a date value to a numeric year value. Use it in calculations for things like periodic reports or for formatting date displays.

Year() is a member of a group of functions that return components of a date value as numeric values. The group includes Day() and Month() which return the day and month values as numeric values.

Examples

■  These examples illustrate Year() using the system date:

   ? Date()                    // Result: 09/20/90
   ? Year(Date())              // Result: 1990
   ? Year(Date()) + 11         // Result: 2001

■  This example creates a user-defined function using Year() to
   format a date value in the following form: month day, year.

   ? MDY(Date())               // Result: September 20, 1990

   FUNCTION MDY( dDate )
      RETURN CMonth(dDate) + " " + ;
            LTrim(Str(Day(dDate)));
         + "," + Str(Year(dDate))

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

ZAPHarbour implementation⌃ | ☰

Remove all records from the current database file

Syntax

Description

ZAP is a database command that permanently removes all records from files open in the current work area. This includes the current database file, index files, and associated memo file. Disk space previously occupied by the ZAPped files is released to the operating system. ZAP performs the same operation as DELETE ALL followed by PACK, but is almost instantaneous in comparison.

To ZAP in a network environment, the current database file must be USEd EXCLUSIVEly. Refer to the «Network Programming» chapter in the Programming and Utilities Guide for more information.

Examples

■  This example demonstrates a typical ZAP operation in a network
   environment:

   USE Sales EXCLUSIVE NEW
   IF !NetErr()
      SET INDEX TO Sales, Branch, Salesman
      ZAP
      CLOSE Sales
   ELSE
      ? "Zap operation failed"
      BREAK
   ENDIF

Platforms

Available on MS-DOS

File

Library is CLIPPER.LIB.

See also

CA-Clipper 5.3⌃ | ☰

Copyright

Description

The Guide To CA-Clipper, Copyright (C) Computer Associates 1994

Platforms

Available on MS-DOS

Tag

Copyright

ASCII Chart⌃ | ☰

ASCII Chart

Description

ASCII Chart

 Dec   Hex  Char         Dec   Hex  Char   Dec   Hex  Char   Dec   Hex  Char

   0   00h   ?   NUL  │   64   40h   @  │  128   80h   Ç  │  192   C0h   └

   1   01h   ?   SOH  │   65   41h   A  │  129   81h   ü  │  193   C1h   ┴

   2   02h   ?   STX  │   66   42h   B  │  130   82h   é  │  194   C2h   ┬

   3   03h   ?   ETX  │   67   43h   C  │  131   83h   â  │  195   C3h   ├

   4   04h   ?   EOT  │   68   44h   D  │  132   84h   ä  │  196   C4h   ─

   5   05h   ?   ENQ  │   69   45h   E  │  133   85h   à  │  197   C5h   ┼

   6   06h   ?   ACK  │   70   46h   F  │  134   86h   å  │  198   C6h   ╞

   7   07h   ?   BEL  │   71   47h   G  │  135   87h   ç  │  199   C7h   ╟

   8   08h   ?   BS   │   72   48h   H  │  136   88h   ê  │  200   C8h   ╚

   9   09h   ?   HT   │   73   49h   I  │  137   89h   ë  │  201   C9h   ╔

  10   0Ah   ?   LF   │   74   4Ah   J  │  138   8Ah   è  │  202   CAh   ╩

  11   0Bh   ?   VT   │   75   4Bh   K  │  139   8Bh   ï  │  203   CBh   ╦

  12   0Ch   ?   FF   │   76   4Ch   L  │  140   8Ch   î  │  204   CCh   ╠

  13   0Dh   ?   CR   │   77   4Dh   M  │  141   8Dh   ì  │  205   CDh   ═

  14   0Eh   ?   SO   │   78   4Eh   N  │  142   8Eh   Ä  │  206   CEh   ╬

  15   0Fh   ?   SI   │   79   4Fh   O  │  143   8Fh   Å  │  207   CFh   ╧

  16   10h   ?   DLE  │   80   50h   P  │  144   90h   É  │  208   D0h   ╨

  17   11h   ?   DC1  │   81   51h   Q  │  145   91h   æ  │  209   D1h   ╤

  18   12h   ?   DC2  │   82   52h   R  │  146   92h   Æ  │  210   D2h   ╥

  19   13h   ?   DC3  │   83   53h   S  │  147   93h   ô  │  211   D3h   ╙

  20   14h   ?   DC4  │   84   54h   T  │  148   94h   ö  │  212   D4h   ╘

  21   15h   ?   NAK  │   85   55h   U  │  149   95h   ò  │  213   D5h   ╒

  22   16h   ?   SYN  │   86   56h   V  │  150   96h   û  │  214   D6h   ╓

  23   17h   ?   ETB  │   87   57h   W  │  151   97h   ù  │  215   D7h   ╫

  24   18h   ?   CAN  │   88   58h   X  │  152   98h   ÿ  │  216   D8h   ╪

  25   19h   ?   EM   │   89   59h   Y  │  153   99h   Ö  │  217   D9h   ┘

  26   1Ah   ?   SUB  │   90   5Ah   Z  │  154   9Ah   Ü  │  218   DAh   ┌

  27   1Bh   ?   ESC  │   91   5Bh   [  │  155   9Bh   ¢  │  219   DBh   █

  28   1Ch   ?   FS   │   92   5Ch     │  156   9Ch   £  │  220   DCh   ▄

  29   1Dh   ?   GS   │   93   5Dh   ]  │  157   9Dh   ¥  │  221   DDh   ▌

  30   1Eh   ?   RS   │   94   5Eh   ^  │  158   9Eh   ₧  │  222   DEh   ▐

  31   1Fh   ?   US   │   95   5Fh   _  │  159   9Fh   ƒ  │  223   DFh   ▀

  32   20h            │   96   60h   `  │  160   A0h   á  │  224   E0h   α

  33   21h   !        │   97   61h   a  │  161   A1h   í  │  225   E1h   ß

  34   22h   »        │   98   62h   b  │  162   A2h   ó  │  226   E2h   Γ

  35   23h   #        │   99   63h   c  │  163   A3h   ú  │  227   E3h   π

  36   24h   $        │  100   64h   d  │  164   A4h   ñ  │  228   E4h   Σ

  37   25h   %        │  101   65h   e  │  165   A5h   Ñ  │  229   E5h   σ

  38   26h   &        │  102   66h   f  │  166   A6h   ª  │  230   E6h   µ

  39   27h   ‘        │  103   67h   g  │  167   A7h   º  │  231   E7h   τ

  40   28h   (        │  104   68h   h  │  168   A8h   ¿  │  232   E8h   Φ

  41   29h   )        │  105   69h   i  │  169   A9h   ⌐  │  233   E9h   Θ

  42   2Ah   *        │  106   6Ah   j  │  170   AAh   ¬  │  234   EAh   Ω

  43   2Bh   +        │  107   6Bh   k  │  171   ABh   ½  │  235   EBh   δ

  44   2Ch   ,        │  108   6Ch   l  │  172   ACh   ¼  │  236   ECh   ∞

  45   2Dh   —        │  109   6Dh   m  │  173   ADh   ¡  │  237   EDh   φ

  46   2Eh   .        │  110   6Eh   n  │  174   AEh   «  │  238   EEh   ε

  47   2Fh   /        │  111   6Fh   o  │  175   AFh   »  │  239   EFh   ∩

  48   30h   0        │  112   70h   p  │  176   B0h   ░  │  240   F0h   ≡

  49   31h   1        │  113   71h   q  │  177   B1h   ▒  │  241   F1h   ±

  50   32h   2        │  114   72h   r  │  178   B2h   ▓  │  242   F2h   ≥

  51   33h   3        │  115   73h   s  │  179   B3h   │  │  243   F3h   ≤

  52   34h   4        │  116   74h   t  │  180   B4h   ┤  │  244   F4h   ⌠

  53   35h   5        │  117   75h   u  │  181   B5h   ╡  │  245   F5h   ⌡

  54   36h   6        │  118   76h   v  │  182   B6h   ╢  │  246   F6h   ÷

  55   37h   7        │  119   77h   w  │  183   B7h   ╖  │  247   F7h   ≈

  56   38h   8        │  120   78h   x  │  184   B8h   ╕  │  248   F8h   °

  57   39h   9        │  121   79h   y  │  185   B9h   ╣  │  249   F9h   ∙

  58   3Ah   :        │  122   7Ah   z  │  186   BAh   ║  │  250   FAh   ·

  59   3Bh   ;        │  123   7Bh   {  │  187   BBh   ╗  │  251   FBh   √

  60   3Ch   <        │  124   7Ch   |  │  188   BCh   ╝  │  252   FCh   ⁿ

  61   3Dh   =        │  125   7Dh   }  │  189   BDh   ╜  │  253   FDh   ²

  62   3Eh   >        │  126   7Eh   ~  │  190   BEh   ╛  │  254   FEh   ■

  63   3Fh   ?        │  127   7Fh   ?  │  191   BFh   ┐  │  255   FFh    

Platforms

Available on MS-DOS

Tag

Tables

Box Characters⌃ | ☰

Box Characters

Description

Box Characters

    218   196   194    191                   201   205   203    187

      ┌──────────┬─────┐                       ╔══════════╦═════╗

  179 │     197  │     │ 179               186 ║     206  ║     ║ 186

      │         │     │                       ║         ║     ║

  195 ├──────────┼─────┤ 180               204 ╠══════════╬═════╣ 185

      │          │     │                       ║          ║     ║

      └──────────┴─────┘                       ╚══════════╩═════╝

    192   196   193    217                   200   205   202    188

    213   205   209    184                   214   196   210    183

      ╒══════════╤═════╕                       ╓──────────╥─────╖

  179 │     216  │     │ 179               186 ║     215  ║     ║ 186

      │         │     │                       ║         ║     ║

  198 ╞══════════╪═════╡ 181               199 ╟──────────╫─────╢ 182

      │          │     │                       ║          ║     ║

      ╘══════════╧═════╛                       ╙──────────╨─────╜

    212   205   207    190                   211   196   208    189

Platforms

Available on MS-DOS

Tag

Tables

Colors⌃ | ☰

Colors

Description

Colors

 Color                 Monochrome │ Color                    Monochrome

 Black, Space  N   0   Black      │ Gray            N+   8   Black

 Blue          B   1   Underline  │ Bright Blue     B+   9   Bright Underline

 Green         G   2   White      │ Bright Green    G+  10   Bright White

 Cyan          BG  3   White      │ Bright Cyan     BG+ 11   Bright White

 Red           R   4   White      │ Bright Red      R+  12   Bright White

 Magenta       RB  5   White      │ Bright Magenta  RB+ 13   Bright White

 Brown         GR  6   White      │ Yellow          GR+ 14   Bright White

 White         W   7   White      │ Bright White    W+  15   Bright White

 Black         U       Underline

 Inverse       I       Inverse video

 Black         X       Blank

? Note

If numbers are used and the background color is greater than 7, the foreground color is displayed blinking. If letters are used and the high intensity attribute is applied to the background color, the foreground color is displayed in high intensity.

Platforms

Available on MS-DOS

Tag

Tables

See also

Inkey Codes⌃ | ☰

Inkey Codes

Description

Inkey Codes

 Cursor Movement Keys                        │ Editing Keys

 Uparrow, Ctrl-E             5  K_UP         │ Del, Ctrl-G        7  K_DEL

 Dnarrow, Ctrl-X            24  K_DOWN       │ Tab, Ctrl-I        9  K_TAB

 Leftarrow, Ctrl-S          19  K_LEFT       │ Shift-Tab        271  K_SH_TAB

 Rightarrow, Ctrl-D          4  K_RIGHT      │ Ins, Ctrl-V       22  K_INS

 Home, Ctrl-A                1  K_HOME       │ Backspace, Ctrl-H  8  K_BS

 End,  Ctrl-F                6  K_END        │ Ctrl-Backspace   127  K_CTRL_BS

 PgUp, Ctrl-R               18  K_PGUP       ├───────────────────────────────────

 PgDn, Ctrl-C                3  K_PGDN       │ Function Keys

 Ctrl-Leftarrow, Ctrl-Z     26  K_CTRL_LEFT  ├──────────────────────────────────

 Ctrl-Rightarrow, Ctrl-B     2  K_CTRL_RIGHT │ F1, Ctrl-        28  K_F1

 Ctrl-Home, Ctrl-]          29  K_CTRL_HOME  │ F2                -1  K_F2

 Ctrl-End, Ctrl-W           23  K_CTRL_END   │ F3                -2  K_F3

 Ctrl-PgUp, Ctrl-Hyphen     31  K_CTRL_PGUP  │ F4                -3  K_F4

 Ctrl-PgDn, Ctrl-^          30  K_CTRL_PGDN  │ F5                -4  K_F5

 Ctrl-Return                10  K_CTRL_RET   │ F6                -5  K_F6

 Ctrl-ScrollLock             3  K_CTRL_C     │ F7                -6  K_F7

 Esc, Ctrl-[                27  K_ESC        │ F8                -7  K_F8

 Return, Ctrl-M             13  K_RETURN     │ F9                -8  K_F9

 Enter, Ctrl-M              13  K_ENTER      │ F10               -9  K_F10

Alt and Ctrl Keys

 Alt-A  286 K_ALT_A│ Alt-N 305 K_ALT_N│ Ctrl-A  1 K_CTRL_A│ Ctrl-N 14 K_CTRL_N

 Alt-B  304 K_ALT_B│ Alt-O 280 K_ALT_O│ Ctrl-B  2 K_CTRL_B│ Ctrl-O 15 K_CTRL_O

 Alt-C  302 K_ALT_C│ Alt-P 281 K_ALT_P│ Ctrl-C  3 K_CTRL_C│ Ctrl-P 16 K_CTRL_P

 Alt-D  288 K_ALT_D│ Alt-Q 272 K_ALT_Q│ Ctrl-D  4 K_CTRL_D│ Ctrl-Q 17 K_CTRL_Q

 Alt-E  274 K_ALT_E│ Alt-R 275 K_ALT_R│ Ctrl-E  5 K_CTRL_E│ Ctrl-R 18 K_CTRL_R

 Alt-F  289 K_ALT_F│ Alt-S 287 K_ALT_S│ Ctrl-F  6 K_CTRL_F│ Ctrl-S 19 K_CTRL_S

 Alt-G  290 K_ALT_G│ Alt-T 276 K_ALT_T│ Ctrl-G  7 K_CTRL_G│ Ctrl-T 20 K_CTRL_T

 Alt-H  291 K_ALT_H│ Alt-U 278 K_ALT_U│ Ctrl-H  8 K_CTRL_H│ Ctrl-U 21 K_CTRL_U

 Alt-I  279 K_ALT_I│ Alt-V 303 K_ALT_V│ Ctrl-I  9 K_CTRL_I│ Ctrl-V 22 K_CTRL_V

 Alt-J  292 K_ALT_J│ Alt-W 273 K_ALT_W│ Ctrl-J 10 K_CTRL_J│ Ctrl-W 23 K_CTRL_W

 Alt-K  293 K_ALT_K│ Alt-X 301 K_ALT_X│ Ctrl-K 11 K_CTRL_K│ Ctrl-X 24 K_Ctrl_X

 Alt-L  294 K_ALT_L│ Alt-Y 277 K_ALT_Y│ Ctrl-L 12 K_CTRL_L│ Ctrl-Y 25 K_Ctrl_Y

 Alt-M  306 K_ALT_M│ Alt-Z 300 K_ALT_Z│ Ctrl-M 13 K_CTRL_M│ Ctrl-Z 26 K_CTRL_Z

 Shift, Alt, and Ctrl-Function Keys

Shift-F1 -10 K_SH_F1 │ Ctrl-F1 -20 K_CTRL_F1 │ Alt-F1 -30 K_ALT_F1 Shift-F2 -11 K_SH_F2 │ Ctrl-F2 -21 K_CTRL_F2 │ Alt-F2 -31 K_ALT_F2 Shift-F3 -12 K_SH_F3 │ Ctrl-F3 -22 K_CTRL_F3 │ Alt-F3 -32 K_ALT_F3 Shift-F4 -13 K_SH_F4 │ Ctrl-F4 -23 K_CTRL_F4 │ Alt-F4 -33 K_ALT_F4 Shift-F5 -14 K_SH_F5 │ Ctrl-F5 -24 K_CTRL_F5 │ Alt-F5 -34 K_ALT_F5 Shift-F6 -15 K_SH_F6 │ Ctrl-F6 -25 K_CTRL_F6 │ Alt-F6 -35 K_ALT_F6 Shift-F7 -16 K_SH_F7 │ Ctrl-F7 -26 K_CTRL_F7 │ Alt-F7 -36 K_ALT_F7 Shift-F8 -17 K_SH_F8 │ Ctrl-F8 -27 K_CTRL_F8 │ Alt-F8 -37 K_ALT_F8 Shift-F9 -18 K_SH_F9 │ Ctrl-F9 -28 K_CTRL_F9 │ Alt-F9 -38 K_ALT_F9 Shift-F10 -19 K_SH_F10 │ Ctrl-F10 -29 K_CTRL_F10 │ Alt-F10 -39 K_ALT_F10

Platforms

Available on MS-DOS

Tag

Tables

Picture Codes⌃ | ☰

Picture Codes

Description

Picture Codes

 Say Picture Functions

 B  Display numbers left-justified    │ X  Display DB after negative numbers

 C  Display CR after positive numbers │ Z  Display zeros as blanks

 D  Display date in SET DATE format   │ (  Enclose negative numbers in parens

 E  Display date in British format    │ !  Convert alpha characters to upper

 R  Insert non-template characters    │

 Say Picture Template Symbols

 A  Display digits for any data type  │ !  Convert alpha character to upper

 N   »                                │ $  Display dollar sign instead of

 X   »                                │    leading space in a numeric

 9   »                                │ *  Display asterisk instead of

 #   »                                │    leading space in a numeric

 L  Display logicals as «T» or «F»    │ .  Specify a decimal point position

 Y  Display logicals as «Y» or «N»    │ ,  Specify a comma position

 Get Picture Functions

 A     C     Allow only alpha characters

 B     N     Display numbers left-justified

 C     N     Display CR after positive numbers

 D     D,N   Display dates in SET DATE format

 E     D,N   Display dates with day and month inverted

             independent of the current DATE SETting,

             numerics with comma and period reverse

 K     All   Delete default text if first key is not a cursor key

 R     C     Insert non-template characters in the display but do not

             save in the Get variable

 S<n>  C     Allows horizontal scrolling within a Get.  <n> is an integer

             that specifies the width of the region

 X     N     Display DB after negative numbers

 Z     N     Display zero as blanks

 (     N     Display negative numbers in parentheses with leading spaces

 )     N     Display negative numbers in parentheses without leading spaces

 !     C     Convert alphabetic character to upper case

 Get Picture Template Symbols

 A    Allow only alphabetic characters

 N    Allow only alphabetic and numeric characters

 X    Allow any character

 9    Allow digits for any data type including sign for numerics

 #    Allow digits, signs and spaces for any data type

 L    Allow only T, F, Y or N

 Y    Allow only Y or N

 !    Convert alphabetic character to upper case

 $    Display a dollar sign in place of a leading space in a numeric

 *    Display an asterisk in place of a leading space in a numeric

 .    Display a decimal point

 ,    Display a comma

Platforms

Available on MS-DOS

Tag

Tables

Reserved Words⌃ | ☰

Reserved Words

Description

Reserved Word and Function Names

 IF        │ AADD   CTOD     EXP        INT     MONTH      ROW      TIME

 ELSE      │ ABS    DATE     FCOUNT     LASTREC PCOL       RTRIM    TRANSFORM

 ELSEIF    │ ASC    DAY      FIELDNAME  LEN     PCOUNT     SECONDS  TRIM

 ENDIF     │ AT     DELETED  FILE       LOCK    PROW       SELECT   TYPE

 WHILE     │ BREAK  DEVPOS   FLOCK      LOG     RECCOUNT   SETPOS   UPPER

 ENDCASE   │ BOF    DOW      FOUND      LOWER   RECNO      SPACE    VAL

 ENDDO     │ CDOW   DTOC     IF         LTRIM   REPLICATE  SQRT     VALTYPE

 FUNCTION  │ CHR    DTOS     IIF        MAX     RLOCK      STR      WORD

 PROCEDURE │ CMONTH EMPTY    INKEY      MIN     ROUND      SUBSTR   YEAR

           │ COL    EOF

? Notes

■ Reserved words cannot be used for variable, procedure, or user-defined function names.

■ Reserved functions are built into the compiler and therefore cannot be redefined by an application.

■ Abbreviations of reserved words and functions of four or more characters are also reserved.

All identifiers that begin with one or more underscore characters (_) are designated as system identifiers and are therefore reserved.

Platforms

Available on MS-DOS

Tag

Tables

Special Characters⌃ | ☰

Special Characters

Description

Special Characters

 Arrows                     │  Blocks          │  Currency

  ?  30   ?  24  ?  18      │  ░ 176  █  219   │  ¢  155  Cents

  ?  31   ?  25  ?  23      │         ▌  221   │  £  156  Pounds

  ?  16   ?  26             │  ▒ 177  ▄  220   │  ¥  157  Yen

  ?  17   ?  27  ?  29      │         ?  222   │  ƒ  159  Francs

                            │  ▓ 178  ▀  223   │  $  36   Dollars

 Foreign ──────┬────────────┴──┬───────────────┼─ Greek ──────────────────────

  131 â        │  130 é  É 144 │  150 û        │  α 224          Alpha   a

  132 ä  Ä 142 │  140 î        │  129 ü  Ü 154 │  ß 225          Beta    b

  133 à        │  139 ï        │  151 ù        │  Γ 226          Gamma   g

  160 á        │  147 ô        │  163 ú        │  δ 235          Delta   d

  134 å  Å 143 │  148 ö  Ö 153 │  152 ÿ        │  Θ 233          Theta   th

  145 æ  Æ 146 │  149 ò        │  225 ß        │  µ 230          Mu      m

  135 ç  Ç 128 │  162 ó        │               │  π 227          Pi      p

  136 ê        │  164 ñ  Ñ 165 │               │  σ 229  Σ 228   Sigma   s

  137 ë        │  141 ì        │               │  τ 231          Tau     t

  138 è        │  161 í        │               │  φ 237  Φ 232   Phi     ph

               │               │               │  Ω 234          Omega

 Mathematical ─┴───────────────┴───┬───────────┴──────────────────────────────

  Å  143                           │  ÷  246  Division

  ε  238  Is an element of         │  ≈  247  Nearly equal

  ∩  239  Intersection             │  °  248  Degree

  ≡  240  Identical to, congruent  │  ∙  249  Multiplied by

  ±  241  Plus or minus            │  ·  250

  ≥  242  Greater than or equal to │  √  251  Square root

  ≤  243  Less than or equal to    │  ⁿ  252  Nth power

                                   │  ²  253  Squared (second power)

                                   │  ∞  236  Infinity

  ⌠  244  Integral                 │  ⌠ 244   Integral

  ⌡  245                           │  │ 179

                                   │  ⌡ 245

 Bullets ───┬──────────┬─ Other ───┼──────────────────────────────────────────

  ?  7      │  ?  5    │  ª  166   │  »  175

  ?  4      │  ?  6    │  º  167   │  ?  19

  ∙  249    │  ?  11   │  ¿  168   │  ?  20   Paragraph or Return character

  ·  250    │  ?  12   │  ¡  173   │  ?  21   Section number

  ?  3      │  *  42   │  «  174   │  ₧  158

Platforms

Available on MS-DOS

Tag

Tables

Unsupported dBASE Items⌃ | ☰

Unsupported dBASE Items

Description

dBASE Commands and Functions Not Supported by CA-Clipper

 Some dBASE commands and functions are not supported by CA-Clipper.

 CA-Clipper does not support any of the commands that are used primarily

 in the interactive or «dot prompt» mode.  In the interactive mode, you

 may instantly query the various databases without writing a program,

 however, CA-Clipper has been designed to compile and execute programs

 significantly faster than can be accomplished in the interactive mode.

 The dBASE commands and functions that are not supported by CA-Clipper

 are listed in the table below.

 CA-Clipper Equivalents of dBASE Commands & Functions:

 dBASE Command/Function   │ CA-Clipper Equivalent

                          │

 APPEND                   │ DBU.EXE

 ASSIST                   │ DBU.EXE

 BROWSE                   │ Browse(), dbEdit(), TBrowse Class

 CHANGE                   │ DBU.EXE

 CLEAR FIELDS             │ n/a

 CREATE/MODIFY LABEL      │ RL.EXE

 CREATE/MODIFY QUERY      │ n/a

 CREATE/MODIFY REPORT     │ RL.EXE

 CREATE/MODIFY SCREEN     │ n/a

 CREATE/MODIFY STRUCTURE  │ DBU.EXE

 CREATE/MODIFY VIEW       │ DBU.EXE

 EDIT                     │ DBU.EXE

 ERROR()                  │ Error:genCode, Error:osCode,

                          │ Error:SubCode messages

 EXPORT TO                │ n/a

 HELP                     │ The Guide To CA-Clipper

 IMPORT FROM              │ n/a

 INSERT                   │ n/a

 LIST/DISPLAY FILES       │ DBU.EXE

 LIST/DISPLAY HISTORY     │ The CA-Clipper Debugger

 LIST/DISPLAY MEMORY      │ The CA-Clipper Debugger

 LIST/DISPLAY STATUS      │ The CA-Clipper Debugger

 LIST/DISPLAY STRUCTURE   │ The CA-Clipper Debugger

 LOAD                     │ RTLINK.EXE

 LOGOUT                   │ n/a

 MESSAGE()                │ Error:description message

 MODIFY COMMAND           │ PE.EXE

 ON ERROR                 │ ErrorBlock()

 ON ESCAPE                │ SET KEY User function

 ON KEY                   │ SET KEY User function

 RESUME                   │ RETURN false (.F.) from an error handling block

                          │ if Error:canDefault contains true (.T.)

 RETRY                    │ RETURN true (.T.) from an error handling block

                          │ if Error:canRetry contains true (.T.)

 RETURN TO MASTER         │ BEGIN SEQUENCE…BREAK…END

 SET                      │ The CA-Clipper Debugger

 SET CARRY                │ n/a

 SET CATALOG              │ n/a

 SET COLOR ON | OFF       │ n/a

 SET DEBUG                │ AltD()

 SET DOHISTORY            │ The CA-Clipper Debugger

 SET ECHO                 │ The CA-Clipper Debugger

 SET ENCRYPTION           │ n/a

 SET FIELDS               │ DBU.EXE

 SET HEADING              │ n/a

 SET HELP                 │ n/a

 SET HISTORY              │ n/a

 SET MEMOWIDTH            │ MemoLine(), MemoEdit(), MLCount()

 SET MENUS                │ n/a

 SET MESSAGE              │ n/a

 SET SAFETY               │ n/a

 SET STATUS               │ n/a

 SET TALK                 │ The CA-Clipper Debugger

 SET TITLE                │ n/a

 SET VIEW                 │ DBU.EXE

Platforms

Available on MS-DOS

Tag

Tables

Code overview

This document describes the overall code layout and major code flow of
Klipper.

Directory Layout

The src/ directory contains the C source for the micro-controller
code. The src/atsam/, src/atsamd/, src/avr/,
src/linux/, src/lpc176x/, src/pru/, and src/stm32/
directories contain architecture specific micro-controller code. The
src/simulator/ contains code stubs that allow the micro-controller
to be test compiled on other architectures. The src/generic/
directory contains helper code that may be useful across different
architectures. The build arranges for includes of «board/somefile.h»
to first look in the current architecture directory (eg,
src/avr/somefile.h) and then in the generic directory (eg,
src/generic/somefile.h).

The klippy/ directory contains the host software. Most of the host
software is written in Python, however the klippy/chelper/
directory contains some C code helpers. The klippy/kinematics/
directory contains the robot kinematics code. The klippy/extras/
directory contains the host code extensible «modules».

The lib/ directory contains external 3rd-party library code that
is necessary to build some targets.

The config/ directory contains example printer configuration
files.

The scripts/ directory contains build-time scripts useful for
compiling the micro-controller code.

The test/ directory contains automated test cases.

During compilation, the build may create an out/ directory. This
contains temporary build time objects. The final micro-controller
object that is built is out/klipper.elf.hex on AVR and
out/klipper.bin on ARM.

Micro-controller code flow

Execution of the micro-controller code starts in architecture specific
code (eg, src/avr/main.c) which ultimately calls sched_main()
located in src/sched.c. The sched_main() code starts by running
all functions that have been tagged with the DECL_INIT() macro. It
then goes on to repeatedly run all functions tagged with the
DECL_TASK() macro.

One of the main task functions is command_dispatch() located in
src/command.c. This function is called from the board specific
input/output code (eg, src/avr/serial.c,
src/generic/serial_irq.c) and it runs the command functions
associated with the commands found in the input stream. Command
functions are declared using the DECL_COMMAND() macro (see the
protocol document for more information).

Task, init, and command functions always run with interrupts enabled
(however, they can temporarily disable interrupts if needed). These
functions should avoid long pauses, delays, or do work that lasts a
significant time. (Long delays in these «task» functions result in
scheduling jitter for other «tasks» — delays over 100us may become
noticeable, delays over 500us may result in command retransmissions,
delays over 100ms may result in watchdog reboots.) These functions
schedule work at specific times by scheduling timers.

Timer functions are scheduled by calling sched_add_timer() (located in
src/sched.c). The scheduler code will arrange for the given
function to be called at the requested clock time. Timer interrupts
are initially handled in an architecture specific interrupt handler
(eg, src/avr/timer.c) which calls sched_timer_dispatch() located
in src/sched.c. The timer interrupt leads to execution of schedule
timer functions. Timer functions always run with interrupts disabled.
The timer functions should always complete within a few micro-seconds.
At completion of the timer event, the function may choose to
reschedule itself.

In the event an error is detected the code can invoke shutdown() (a
macro which calls sched_shutdown() located in src/sched.c).
Invoking shutdown() causes all functions tagged with the
DECL_SHUTDOWN() macro to be run. Shutdown functions always run with
interrupts disabled.

Much of the functionality of the micro-controller involves working
with General-Purpose Input/Output pins (GPIO). In order to abstract
the low-level architecture specific code from the high-level task
code, all GPIO events are implemented in architecture specific
wrappers (eg, src/avr/gpio.c). The code is compiled with gcc’s
«-flto -fwhole-program» optimization which does an excellent job of
inlining functions across compilation units, so most of these tiny
gpio functions are inlined into their callers, and there is no
run-time cost to using them.

Klippy code overview

The host code (Klippy) is intended to run on a low-cost computer (such
as a Raspberry Pi) paired with the micro-controller. The code is
primarily written in Python, however it does use CFFI to implement
some functionality in C code.

Initial execution starts in klippy/klippy.py. This reads the
command-line arguments, opens the printer config file, instantiates
the main printer objects, and starts the serial connection. The main
execution of G-code commands is in the process_commands() method in
klippy/gcode.py. This code translates the G-code commands into
printer object calls, which frequently translate the actions to
commands to be executed on the micro-controller (as declared via the
DECL_COMMAND macro in the micro-controller code).

There are four threads in the Klippy host code. The main thread
handles incoming gcode commands. A second thread (which resides
entirely in the klippy/chelper/serialqueue.c C code) handles
low-level IO with the serial port. The third thread is used to process
response messages from the micro-controller in the Python code (see
klippy/serialhdl.py). The fourth thread writes debug messages to
the log (see klippy/queuelogger.py) so that the other threads
never block on log writes.

Code flow of a move command

A typical printer movement starts when a «G1» command is sent to the
Klippy host and it completes when the corresponding step pulses are
produced on the micro-controller. This section outlines the code flow
of a typical move command. The kinematics document
provides further information on the mechanics of moves.

  • Processing for a move command starts in gcode.py. The goal of
    gcode.py is to translate G-code into internal calls. A G1 command
    will invoke cmd_G1() in klippy/extras/gcode_move.py. The
    gcode_move.py code handles changes in origin (eg, G92), changes in
    relative vs absolute positions (eg, G90), and unit changes (eg,
    F6000=100mm/s). The code path for a move is: _process_data() -> _process_commands() -> cmd_G1(). Ultimately the ToolHead class is
    invoked to execute the actual request: cmd_G1() -> ToolHead.move()

  • The ToolHead class (in toolhead.py) handles «look-ahead» and tracks
    the timing of printing actions. The main codepath for a move is:
    ToolHead.move() -> MoveQueue.add_move() -> MoveQueue.flush() -> Move.set_junction() -> ToolHead._process_moves().

    • ToolHead.move() creates a Move() object with the parameters of the
      move (in cartesian space and in units of seconds and millimeters).
    • The kinematics class is given the opportunity to audit each move
      (ToolHead.move() -> kin.check_move()). The kinematics classes are
      located in the klippy/kinematics/ directory. The check_move() code
      may raise an error if the move is not valid. If check_move()
      completes successfully then the underlying kinematics must be able
      to handle the move.
    • MoveQueue.add_move() places the move object on the «look-ahead»
      queue.
    • MoveQueue.flush() determines the start and end velocities of each
      move.
    • Move.set_junction() implements the «trapezoid generator» on a
      move. The «trapezoid generator» breaks every move into three parts:
      a constant acceleration phase, followed by a constant velocity
      phase, followed by a constant deceleration phase. Every move
      contains these three phases in this order, but some phases may be of
      zero duration.
    • When ToolHead._process_moves() is called, everything about the
      move is known — its start location, its end location, its
      acceleration, its start/cruising/end velocity, and distance traveled
      during acceleration/cruising/deceleration. All the information is
      stored in the Move() class and is in cartesian space in units of
      millimeters and seconds.
  • Klipper uses an
    iterative solver
    to generate the step times for each stepper. For efficiency reasons,
    the stepper pulse times are generated in C code. The moves are first
    placed on a «trapezoid motion queue»: ToolHead._process_moves() -> trapq_append() (in klippy/chelper/trapq.c). The step times are then
    generated: ToolHead._process_moves() -> ToolHead._update_move_time() -> MCU_Stepper.generate_steps() -> itersolve_generate_steps() -> itersolve_gen_steps_range() (in
    klippy/chelper/itersolve.c). The goal of the iterative solver is to
    find step times given a function that calculates a stepper position
    from a time. This is done by repeatedly «guessing» various times
    until the stepper position formula returns the desired position of
    the next step on the stepper. The feedback produced from each guess
    is used to improve future guesses so that the process rapidly
    converges to the desired time. The kinematic stepper position
    formulas are located in the klippy/chelper/ directory (eg,
    kin_cart.c, kin_corexy.c, kin_delta.c, kin_extruder.c).

  • Note that the extruder is handled in its own kinematic class:
    ToolHead._process_moves() -> PrinterExtruder.move(). Since
    the Move() class specifies the exact movement time and since step
    pulses are sent to the micro-controller with specific timing,
    stepper movements produced by the extruder class will be in sync
    with head movement even though the code is kept separate.

  • After the iterative solver calculates the step times they are added
    to an array: itersolve_gen_steps_range() -> stepcompress_append()
    (in klippy/chelper/stepcompress.c). The array (struct
    stepcompress.queue) stores the corresponding micro-controller clock
    counter times for every step. Here the «micro-controller clock
    counter» value directly corresponds to the micro-controller’s
    hardware counter — it is relative to when the micro-controller was
    last powered up.

  • The next major step is to compress the steps: stepcompress_flush() -> compress_bisect_add() (in klippy/chelper/stepcompress.c). This
    code generates and encodes a series of micro-controller «queue_step»
    commands that correspond to the list of stepper step times built in
    the previous stage. These «queue_step» commands are then queued,
    prioritized, and sent to the micro-controller (via
    stepcompress.c:steppersync and serialqueue.c:serialqueue).

  • Processing of the queue_step commands on the micro-controller starts
    in src/command.c which parses the command and calls
    command_queue_step(). The command_queue_step() code (in
    src/stepper.c) just appends the parameters of each queue_step
    command to a per stepper queue. Under normal operation the
    queue_step command is parsed and queued at least 100ms before the
    time of its first step. Finally, the generation of stepper events is
    done in stepper_event(). It’s called from the hardware timer
    interrupt at the scheduled time of the first step. The
    stepper_event() code generates a step pulse and then reschedules
    itself to run at the time of the next step pulse for the given
    queue_step parameters. The parameters for each queue_step command
    are «interval», «count», and «add». At a high-level, stepper_event()
    runs the following, ‘count’ times: do_step(); next_wake_time = last_wake_time + interval; interval += add;

The above may seem like a lot of complexity to execute a movement.
However, the only really interesting parts are in the ToolHead and
kinematic classes. It’s this part of the code which specifies the
movements and their timings. The remaining parts of the processing is
mostly just communication and plumbing.

Adding a host module

The Klippy host code has a dynamic module loading capability. If a
config section named «[my_module]» is found in the printer config file
then the software will automatically attempt to load the python module
klippy/extras/my_module.py . This module system is the preferred
method for adding new functionality to Klipper.

The easiest way to add a new module is to use an existing module as a
reference — see klippy/extras/servo.py as an example.

The following may also be useful:

  • Execution of the module starts in the module level load_config()
    function (for config sections of the form [my_module]) or in
    load_config_prefix() (for config sections of the form
    [my_module my_name]). This function is passed a «config» object and
    it must return a new «printer object» associated with the given
    config section.
  • During the process of instantiating a new printer object, the config
    object can be used to read parameters from the given config
    section. This is done using config.get(), config.getfloat(),
    config.getint(), etc. methods. Be sure to read all values from the
    config during the construction of the printer object — if the user
    specifies a config parameter that is not read during this phase then
    it will be assumed it is a typo in the config and an error will be
    raised.
  • Use the config.get_printer() method to obtain a reference to the
    main «printer» class. This «printer» class stores references to all
    the «printer objects» that have been instantiated. Use the
    printer.lookup_object() method to find references to other printer
    objects. Almost all functionality (even core kinematic modules) are
    encapsulated in one of these printer objects. Note, though, that
    when a new module is instantiated, not all other printer objects
    will have been instantiated. The «gcode» and «pins» modules will
    always be available, but for other modules it is a good idea to
    defer the lookup.
  • Register event handlers using the printer.register_event_handler()
    method if the code needs to be called during «events» raised by
    other printer objects. Each event name is a string, and by
    convention it is the name of the main source module that raises the
    event along with a short name for the action that is occurring (eg,
    «klippy:connect»). The parameters passed to each event handler are
    specific to the given event (as are exception handling and execution
    context). Two common startup events are:

    • klippy:connect — This event is generated after all printer objects
      are instantiated. It is commonly used to lookup other printer
      objects, to verify config settings, and to perform an initial
      «handshake» with printer hardware.
    • klippy:ready — This event is generated after all connect handlers
      have completed successfully. It indicates the printer is
      transitioning to a state ready to handle normal operations. Do not
      raise an error in this callback.
  • If there is an error in the user’s config, be sure to raise it
    during the load_config() or «connect event» phases. Use either
    raise config.error("my error") or raise printer.config_error("my error") to report the error.
  • Use the «pins» module to configure a pin on a micro-controller. This
    is typically done with something similar to
    printer.lookup_object("pins").setup_pin("pwm", config.get("my_pin")). The returned object can then be commanded at
    run-time.
  • If the printer object defines a get_status() method then the
    module can export status information via
    macros and via the
    API Server. The get_status() method must return a
    Python dictionary with keys that are strings and values that are
    integers, floats, strings, lists, dictionaries, True, False, or
    None. Tuples (and named tuples) may also be used (these appear as
    lists when accessed via the API Server). Lists and dictionaries that
    are exported must be treated as «immutable» — if their contents
    change then a new object must be returned from get_status(),
    otherwise the API Server will not detect those changes.
  • If the module needs access to system timing or external file
    descriptors then use printer.get_reactor() to obtain access to the
    global «event reactor» class. This reactor class allows one to
    schedule timers, wait for input on file descriptors, and to «sleep»
    the host code.
  • Do not use global variables. All state should be stored in the
    printer object returned from the load_config() function. This is
    important as otherwise the RESTART command may not perform as
    expected. Also, for similar reasons, if any external files (or
    sockets) are opened then be sure to register a «klippy:disconnect»
    event handler and close them from that callback.
  • Avoid accessing the internal member variables (or calling methods
    that start with an underscore) of other printer objects. Observing
    this convention makes it easier to manage future changes.
  • It is recommended to assign a value to all member variables in the
    Python constructor of Python classes. (And therefore avoid utilizing
    Python’s ability to dynamically create new member variables.)
  • If a Python variable is to store a floating point value then it is
    recommended to always assign and manipulate that variable with
    floating point constants (and never use integer constants). For
    example, prefer self.speed = 1. over self.speed = 1, and prefer
    self.speed = 2. * x over self.speed = 2 * x. Consistent use of
    floating point values can avoid hard to debug quirks in Python type
    conversions.
  • If submitting the module for inclusion in the main Klipper code, be
    sure to place a copyright notice at the top of the module. See the
    existing modules for the preferred format.

Adding new kinematics

This section provides some tips on adding support to Klipper for
additional types of printer kinematics. This type of activity requires
excellent understanding of the math formulas for the target
kinematics. It also requires software development skills — though one
should only need to update the host software.

Useful steps:

  1. Start by studying the
    «code flow of a move» section and
    the Kinematics document.
  2. Review the existing kinematic classes in the klippy/kinematics/
    directory. The kinematic classes are tasked with converting a move
    in cartesian coordinates to the movement on each stepper. One
    should be able to copy one of these files as a starting point.
  3. Implement the C stepper kinematic position functions for each
    stepper if they are not already available (see kin_cart.c,
    kin_corexy.c, and kin_delta.c in klippy/chelper/). The function
    should call move_get_coord() to convert a given move time (in
    seconds) to a cartesian coordinate (in millimeters), and then
    calculate the desired stepper position (in millimeters) from that
    cartesian coordinate.
  4. Implement the calc_position() method in the new kinematics class.
    This method calculates the position of the toolhead in cartesian
    coordinates from the position of each stepper. It does not need to
    be efficient as it is typically only called during homing and
    probing operations.
  5. Other methods. Implement the check_move(), get_status(),
    get_steppers(), home(), and set_position() methods. These
    functions are typically used to provide kinematic specific checks.
    However, at the start of development one can use boiler-plate code
    here.
  6. Implement test cases. Create a g-code file with a series of moves
    that can test important cases for the given kinematics. Follow the
    debugging documentation to convert this g-code file
    to micro-controller commands. This is useful to exercise corner
    cases and to check for regressions.

Porting to a new micro-controller

This section provides some tips on porting Klipper’s micro-controller
code to a new architecture. This type of activity requires good
knowledge of embedded development and hands-on access to the target
micro-controller.

Useful steps:

  1. Start by identifying any 3rd party libraries that will be used
    during the port. Common examples include «CMSIS» wrappers and
    manufacturer «HAL» libraries. All 3rd party code needs to be GNU
    GPLv3 compatible. The 3rd party code should be committed to the
    Klipper lib/ directory. Update the lib/README file with information
    on where and when the library was obtained. It is preferable to
    copy the code into the Klipper repository unchanged, but if any
    changes are required then those changes should be listed explicitly
    in the lib/README file.
  2. Create a new architecture sub-directory in the src/ directory and
    add initial Kconfig and Makefile support. Use the existing
    architectures as a guide. The src/simulator provides a basic
    example of a minimum starting point.
  3. The first main coding task is to bring up communication support to
    the target board. This is the most difficult step in a new port.
    Once basic communication is working, the remaining steps tend to be
    much easier. It is typical to use a UART type serial device during
    initial development as these types of hardware devices are
    generally easier to enable and control. During this phase, make
    liberal use of helper code from the src/generic/ directory (check
    how src/simulator/Makefile includes the generic C code into the
    build). It is also necessary to define timer_read_time() (which
    returns the current system clock) in this phase, but it is not
    necessary to fully support timer irq handling.
  4. Get familiar with the the console.py tool (as described in the
    debugging document) and verify connectivity to the
    micro-controller with it. This tool translates the low-level
    micro-controller communication protocol to a human readable form.
  5. Add support for timer dispatch from hardware interrupts. See
    Klipper
    commit 970831ee
    as an example of steps 1-5 done for the LPC176x architecture.
  6. Bring up basic GPIO input and output support. See Klipper
    commit c78b9076
    as an example of this.
  7. Bring up additional peripherals — for example see Klipper commit
    65613aed,
    c812a40a,
    and
    c381d03a.
  8. Create a sample Klipper config file in the config/ directory. Test
    the micro-controller with the main klippy.py program.
  9. Consider adding build test cases in the test/ directory.

Additional coding tips:

  1. Avoid using «C bitfields» to access IO registers; prefer direct
    read and write operations of 32bit, 16bit, or 8bit integers. The C
    language specifications don’t clearly specify how the compiler must
    implement C bitfields (eg, endianness, and bit layout), and it’s
    difficult to determine what IO operations will occur on a C
    bitfield read or write.
  2. Prefer writing explicit values to IO registers instead of using
    read-modify-write operations. That is, if updating a field in an IO
    register where the other fields have known values, then it is
    preferable to explicitly write the full contents of the register.
    Explicit writes produce code that is smaller, faster, and easier to
    debug.

Coordinate Systems

Internally, Klipper primarily tracks the position of the toolhead in
cartesian coordinates that are relative to the coordinate system
specified in the config file. That is, most of the Klipper code will
never experience a change in coordinate systems. If the user makes a
request to change the origin (eg, a G92 command) then that effect is
obtained by translating future commands to the primary coordinate
system.

However, in some cases it is useful to obtain the toolhead position in
some other coordinate system and Klipper has several tools to
facilitate that. This can be seen by running the GET_POSITION
command. For example:

Send: GET_POSITION
Recv: // mcu: stepper_a:-2060 stepper_b:-1169 stepper_c:-1613
Recv: // stepper: stepper_a:457.254159 stepper_b:466.085669 stepper_c:465.382132
Recv: // kinematic: X:8.339144 Y:-3.131558 Z:233.347121
Recv: // toolhead: X:8.338078 Y:-3.123175 Z:233.347878 E:0.000000
Recv: // gcode: X:8.338078 Y:-3.123175 Z:233.347878 E:0.000000
Recv: // gcode base: X:0.000000 Y:0.000000 Z:0.000000 E:0.000000
Recv: // gcode homing: X:0.000000 Y:0.000000 Z:0.000000

The «mcu» position (stepper.get_mcu_position() in the code) is the
total number of steps the micro-controller has issued in a positive
direction minus the number of steps issued in a negative direction
since the micro-controller was last reset. If the robot is in motion
when the query is issued then the reported value includes moves
buffered on the micro-controller, but does not include moves on the
look-ahead queue.

The «stepper» position (stepper.get_commanded_position()) is the
position of the given stepper as tracked by the kinematics code. This
generally corresponds to the position (in mm) of the carriage along
its rail, relative to the position_endstop specified in the config
file. (Some kinematics track stepper positions in radians instead of
millimeters.) If the robot is in motion when the query is issued then
the reported value includes moves buffered on the micro-controller,
but does not include moves on the look-ahead queue. One may use the
toolhead.flush_step_generation() or toolhead.wait_moves() calls to
fully flush the look-ahead and step generation code.

The «kinematic» position (kin.calc_position()) is the cartesian
position of the toolhead as derived from «stepper» positions and is
relative to the coordinate system specified in the config file. This
may differ from the requested cartesian position due to the
granularity of the stepper motors. If the robot is in motion when the
«stepper» positions are taken then the reported value includes moves
buffered on the micro-controller, but does not include moves on the
look-ahead queue. One may use the toolhead.flush_step_generation()
or toolhead.wait_moves() calls to fully flush the look-ahead and
step generation code.

The «toolhead» position (toolhead.get_position()) is the last
requested position of the toolhead in cartesian coordinates relative
to the coordinate system specified in the config file. If the robot is
in motion when the query is issued then the reported value includes
all requested moves (even those in buffers waiting to be issued to the
stepper motor drivers).

The «gcode» position is the last requested position from a G1 (or
G0) command in cartesian coordinates relative to the coordinate
system specified in the config file. This may differ from the
«toolhead» position if a g-code transformation (eg, bed_mesh,
bed_tilt, skew_correction) is in effect. This may differ from the
actual coordinates specified in the last G1 command if the g-code
origin has been changed (eg, G92, SET_GCODE_OFFSET, M221). The
M114 command (gcode_move.get_status()['gcode_position']) will
report the last g-code position relative to the current g-code
coordinate system.

The «gcode base» is the location of the g-code origin in cartesian
coordinates relative to the coordinate system specified in the config
file. Commands such as G92, SET_GCODE_OFFSET, and M221 alter
this value.

The «gcode homing» is the location to use for the g-code origin (in
cartesian coordinates relative to the coordinate system specified in
the config file) after a G28 home command. The SET_GCODE_OFFSET
command can alter this value.

Time

Fundamental to the operation of Klipper is the handling of clocks,
times, and timestamps. Klipper executes actions on the printer by
scheduling events to occur in the near future. For example, to turn on
a fan, the code might schedule a change to a GPIO pin in a 100ms. It
is rare for the code to attempt to take an instantaneous action. Thus,
the handling of time within Klipper is critical to correct operation.

There are three types of times tracked internally in the Klipper host
software:

  • System time. The system time uses the system’s monotonic clock — it
    is a floating point number stored as seconds and it is (generally)
    relative to when the host computer was last started. System times
    have limited use in the software — they are primarily used when
    interacting with the operating system. Within the host code, system
    times are frequently stored in variables named eventtime or
    curtime.
  • Print time. The print time is synchronized to the main
    micro-controller clock (the micro-controller defined in the «[mcu]»
    config section). It is a floating point number stored as seconds and
    is relative to when the main mcu was last restarted. It is possible
    to convert from a «print time» to the main micro-controller’s
    hardware clock by multiplying the print time by the mcu’s statically
    configured frequency rate. The high-level host code uses print times
    to calculate almost all physical actions (eg, head movement, heater
    changes, etc.). Within the host code, print times are generally
    stored in variables named print_time or move_time.
  • MCU clock. This is the hardware clock counter on each
    micro-controller. It is stored as an integer and its update rate is
    relative to the frequency of the given micro-controller. The host
    software translates its internal times to clocks before transmission
    to the mcu. The mcu code only ever tracks time in clock
    ticks. Within the host code, clock values are tracked as 64bit
    integers, while the mcu code uses 32bit integers. Within the host
    code, clocks are generally stored in variables with names containing
    clock or ticks.

Conversion between the different time formats is primarily implemented
in the klippy/clocksync.py code.

Some things to be aware of when reviewing the code:

  • 32bit and 64bit clocks: To reduce bandwidth and to improve
    micro-controller efficiency, clocks on the micro-controller are
    tracked as 32bit integers. When comparing two clocks in the mcu
    code, the timer_is_before() function must always be used to ensure
    integer rollovers are handled properly. The host software converts
    32bit clocks to 64bit clocks by appending the high-order bits from
    the last mcu timestamp it has received — no message from the mcu is
    ever more than 2^31 clock ticks in the future or past so this
    conversion is never ambiguous. The host converts from 64bit clocks
    to 32bit clocks by simply truncating the high-order bits. To ensure
    there is no ambiguity in this conversion, the
    klippy/chelper/serialqueue.c code will buffer messages until
    they are within 2^31 clock ticks of their target time.
  • Multiple micro-controllers: The host software supports using
    multiple micro-controllers on a single printer. In this case, the
    «MCU clock» of each micro-controller is tracked separately. The
    clocksync.py code handles clock drift between micro-controllers by
    modifying the way it converts from «print time» to «MCU clock». On
    secondary mcus, the mcu frequency that is used in this conversion is
    regularly updated to account for measured drift.

Книжные памятники Свет

Обратная связь
Версия для слабовидящих

Войти

НЭБ

  • Коллекции и спецпроекты

  • Новости

  • Электронные читальные залы

  • Информация для библиотек

  • Программное обеспечение для библиотек

  • Вопросы и ответы

  • Обратная связь

  • Форум

Наши продукты

  • Книжные памятники

  • Свет

  • Мы в соцсетях

    Версия для слепых

    Clipper Руководство по программированию Версия 5.01 Пер. с англ.

    Clipper Руководство по программированию Версия 5.01 Пер. с англ.

    Спенс Р.

    Скачать
    rusmarc-запись

    Спенс Р.

    Скачать rusmarc -запись

    Электронная копия документа недоступна

    V,470 с.

    Количество страниц

    1994

    Год издания

    Минск

    Место издания

    О произведении

    Издательство

    Тивали

    Серия

    Серия «Мир науки»

    ISBN

    985-6034-02-7

    ББК

    З973.23-018.2

    Общее примечание

    Загл. и авт. ориг.: Clipper / Rick Spence

    Еще

    Библиотека

    Российская национальная библиотека (РНБ)

    Еще

    Ближайшая библиотека с бумажным экземпляром издания

    Пожалуйста, авторизуйтесь

    Вы можете добавить книгу в избранное после того, как
    авторизуетесь на портале. Если у вас еще нет учетной записи, то
    зарегистрируйтесь.

    32.973
    C 716

    СПЕНС, РИК.
        CLIPPER. РУКОВОДСТВО ПО ПРОГРАММИРОВАНИЮ. ВЕРСИЯ 5.01 / Р. СПЕНС; ПЕР. С АНГЛ. — МИНСК : ТИВАЛИ, 1994. — 480 с. — (МИР НАУКИ). — ISBN 5-915391-68-6 : 50.00 р.

    ББК 32.973.2-018

    Рубрики: CLIPPER—ЯЗЫКИ ПРОГРАММИРОВАНИЯ.

       Компьютеры—Программирование

    Экземпляры:
    Всего: 1, Абонемент — 1 экз.
    Свободны:
    Абонемент — 1 экз.: (Инв. Б 1399122)

    Похожие издания по классификации

    Понравилась статья? Поделить с друзьями:

    А вот и еще наши интересные статьи:

  • Дюспаталин цена в томске инструкция по применению
  • Руководств yaskawa a1000
  • Кордарон для инъекций инструкция по применению цена
  • Инструкция по применению лекарственного препарата мексидол
  • Музыкальная колонка jbl инструкция по применению на русском языке

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии