22 | 11 | 2017

------------------------------------------------------------------
BEGIN SEQUENCE Определяет последовательность операторов для BREAK
------------------------------------------------------------------

BEGIN SEQUENCE
<комманды>...
[BREAK [<выраж.>]]
<комманды>...
[RECOVER [USING <переменная>]]
<комманды>..
END [SEQUENCE]

Аргументы

BREAK <выраж.> передает выполнение комманде, следующей за
коммандой RECOVER если она указана, или комманде, следующей за
коммандой END SEQUENCE. <выраж.> значение, возвращаемое в переменную
<переменная>, указанную в предложении USING комманды RECOVER .


RECOVER USING <переменная> определяет указатель записи в
SEQUENCE конструкции, куда передается управление зa коммандой BREAK.
Если USING <переменная> указана, <переменная> получает значение,
возвращенное коммандой BREAK. В основном это ошибка объекта.

END определяет указатель конца конструкции SEQUENCE. Если нет
комманды RECOVER, то после команды BREAK управление передается
комманде, следующей за END.

Применение

BEGIN SEQUENCE...END - управляющая структура, которая может быть
использована для исключения и управления ошибкой. Она определяет
блок комманд, включая вызываемые процедуры и пользовательские
функции.

Когда в блоке встречается комманда BREAK BEGIN SEQUENCE переходит на
соответствующую комманду RECOVER и управление передается комманде,
следующей за коммандой RECOVER. Если RECOVER не указана, управление
передается комманде, следующей за END. Комманда RECOVER получает па-
раметр, переданный коммандой BREAK. Часто это объекты, генерируемые
блоком управления ошибок ERRORBLOCK().

Внутри конструкции SEQUENCE существуют некоторые ограничения
допускающиеся между коммандами BEGIN SEQUENCE и RECOVER. Допускается
комманда RETURN, но не допускается LOOP или EXIT предложения
комманды цикла DO WHILE, находящихся вне конструкции SEQUENCE.
Внутри блока комманд, следующих за коммандой RECOVER можно
использовать LOOP, EXIT или BREAK, после того как сформирована
конструкция SEQUENCE. LOOP внутри комманды RECOVER используется для
повторного выполнения блока SEQUENCE.

108

Пример использования

Этот пример показывает конструкцию SEQUENCE в которой
встречается комманда BREAK :

BEGIN SEQUENCE
<комманды> ...
IF lBreakCond
BREAK
ENDIF
RECOVER
<комманды> ...
END

<комманды>...

Следующий пример показывает как ошибочный объект
возвращается в переменную, указанную в предложении USING комманды
RECOVER :

LOCAL objLocal, bLastHandler
//
// Сохранить текущий и установить новое управление ошибкой
bLastHandler := ERRORBLOCK({ |objErr| MyHandler(objErr, .T.) })
//
BEGIN SEQUENCE
.
. <комманды с ошибкой>
.
RECOVER USING objLocal
//
// Послать сообщение об ошибке
? "Error: "
IF objLocal:genCode != 0
?? objLocal:description
ENDIF
.
.
.
END
//
// Восстановить предыдущее управление ошибкой
ERRORBLOCK( bLastHandler )

FUNCTION MyHandler( objError, lLocalHandler )
//
// Задержать объект ошибки
IF lLocalHandler
BREAK objError
ENDIF
.
. <другие комманды для задержки ошибки>

109


.
RETURN NIL

Этот пример показывает как блок комманд в конструкции
SEQUENCE может быть выполнен заново с помощью LOOP из блока комманд,
следующих за RECOVER :

DO WHILE .T.
BEGIN SEQUENCE
.
. <комманды с ошибкой>
.
RECOVER
IF PrintRecover()
LOOP // Повторить блок комманд с SEQUENCE
ENDIF
END
EXIT // Выход из операции
ENDDO

-------------------------------------------------------------------
DECLARE* Создание и инициализация переменных памяти и массивов
------------------------------------------------------------------


DECLARE <идентификатор>[[:= <выраж.>], ... ]

Аргументы

<идентификатор> имя переменной памяти или массива, который будет
cоздаваться. Если <идентификатор> является массивом, то для
указания элементов используйте следующий синтаксис:

массив[<элемент1>, <элемент2>, ...]
массив[<элемент1>],[<элемент2>]...

Максимальное число элементов в массиве - 4096.

<выраж.> необязательное присвоение значения новой переменной
памяти. <выраж.> для переменной памяти содержит оператор присвоения
(|=) за которым следует выражение или буквенный массив. Если
<выраж.> не указано, переменной присваивается нулевое значение или
создается массив с нулевыми элементами. Идентификаторы массива не
могут передавать значение <выраж.>.

Применение

DECLARE - совместимая команда и является синонимом команды PRIVATE.
В основном ее использование не рекомендовано.

-------------------------------------------------------------------
DO* Вызов процедуры
------------------------------------------------------------------

110

DO <процедура> [WITH <список аргументов>]

Аргументы

<процедура> - имя процедуры, которая будет выполняться.

WITH: Задает <список аргументов> до 128 элементов. Каждый
аргумент может быть простой переменной, полем, массивом, элементом
массива, выражением или объектом.

Применение

Комманда DO вызывает процедуру с необязательной передачей параметров
в вызываемую подпрограмму. Он выполняет некоторое действие,
указанное в пользовательской функции или указанной процедуры.

В Клиппер число указанных аргументов для передачи не сравнивается с
числом параметров в вызванной процедуре. Если число аргументов
меньше числа параметров, то переменной параметру с необъявленным
аргументом передается нулевое значение. Если аргумент пропущен
внутри <списка аргументов> (оставлено пустое место) , то также
передается нулевое значение. Для обнаружения позиции последнего
передаваемого аргумента в списке аргументов используйте PCOUNT().
Для обнаружения пропущенного аргумента, сравните получаемые
параметры с нулем.

Команда DO включается в компиляцию, если файл компилируется без
опции компилятора /M. Когда компилятор Клиппер встречает оператор DO
и указанная процедура еще не использовалась, то он ищет в текущем
каталоге файл с этим именем и расширением .prg и компилирует если
его найдет. В противном случае вызываемая процедура предполагается
внешней. Заметим что, когда производится компановка, то от
компановщика требуется разрешение этой внешней ссылки.

В Клиппер 5.0 DO - совместимая комманда и поэтому не рекомендована.
Она заменяется вызовом процедуры или функции без DO. Этот вызов
передает также значения по умолчанию. Для передачи аргументов по
ссылке используйте оператор (@). Если используете для такой передачи
комманду DO, то необходимо указать комманду в директиве #command.

Пример использования

Пример выполнения процедуры без параметров:

DO AcctsRpt
AcctsRpt() // Предпочитаемый метод

Пример выполнения процедуры с передачей двух аргументов:

DO QtrRpt WITH "2nd", "Sales Division"
QtrRpt("2nd", "Sales Division") // Предпочитаемый метод


111


Пример выполнения процедуры с передачей первого аргумента
по значению, второго - по ссылке:

nNumber = 12
DO YearRpt WITH nNumber + 12, nNumber
YearRpt(nNumber + 12, @nNumber) // Предпочитаемый метод

bFE Здесь процедура вызывается с пропущенными аргументами:

DO DisplayWindow WITH ,,,,"My Window"
DisplayWindow(,,,,"My Window") // Предпочитаемый метод

-------------------------------------------------------------------
DO CASE Для выбора пути выполнения программы из множества условий
------------------------------------------------------------------


DO CASE
CASE <условие>
<команды>...
[CASE <условие>]
<команды>...
[OTHERWISE]
<команды>...
END[CASE]

Аргументы

CASE <условие> определяет блок команд для выполнения, если
<условие> истинно (.T.).

OTHERWISE определяет блок команд для выполнения, если ни одно из
указанных условий не приняло значения истинно (.T.).

Применение

Структура DO CASE при работе дает ветвление к командам следующим за
первым истинным оцениванием условия CASE. Эта ветвь выполняется до
встречи со следующим оператором CASE, OTHERWISE или ENDCASE. В этой
точке контроль передается первой командной строке, следующей за
ENDCASE.

Пределов вложенности нет: Любое количество команд, включая другие
структуры (DO WHILE, DO CASE, IF, FOR) может быть вложено в простую
структуру DO CASE. В дополнение, нет зафиксированного числа
операторов CASE, которые могут содержатся в простой структуре DO
CASE. DO CASE ...ENDCASE идентична команде IF...ELSEIF...ENDIF.

Пример использования

Следующий пример показывает вывод меню. Используя команду DO CASE
осуществляется выбор пункта меню :


112


@ 3, 25 PROMPT "Первый выбор"
@ 4, 25 PROMPT "Второй выбор"
MENU TO nChoice
//
DO CASE
CASE nChoice = 0
RETURN
CASE nChoice = 1
ChoiceOne()
CASE nChoice = 2
ChoiceTwo()
ENDCASE

-------------------------------------------------------------------
DO WHILE Выполняет цикл пока условие (.T.)
------------------------------------------------------------------


DO WHILE <условие>
<команды>...
[EXIT]
<команды>...
[LOOP]
<команды>...
ENDDO

Аргументы

<условие> - оцениваемое при выполнение оператора DO WHILE
управляющее условие.

EXIT: команда EXIT позволяет выполнить безусловное ветвление
управления из внутренней части структуру DO WHILE к оператору
непосредственно следующему за ENNDO.

LOOP: команда LOOP позволяет выполнить ветвление управления к
последней выполненной командной строке структуры DO WHILE.

Применение

Данная DO WHILE структура позволяет организовать циклическое
выполнение группы команд при условии, что управляющее логическое
выражение на каждом витке цикла истинно (.T.). Убедившись в
истинности условия, программа передает управление командам тела
цикла. Они выполняются до тех пор, пока не встретится команда EXIT,
LOOP или ENDDO. По ENDDO осуществляется переход на строку DO WHILE и
процесс повторяется.

Если при очередной проверке условия обнаруживается логическая ложь
(.T.), DO WHILE структура не выполняется, а управление передается
следующей за ENDDO команде.

Выход: Опция EXIT используется в том случае, если цикл должен быть

113


прерван исходя из каких-то промежуточных условий, а не тех, которые
заданы в строке DO WHILE.

Цикл: Опция LOOP обычно используется для предотвращения выполнения
оставшихся команд тела цикла на основе анализа каких-то
промежуточных условий. Встретив LOOP, программа осуществляет переход
на последнюю выполненную строку DO WHILE.

Пример использования

Следующий пример показывает управляющую структуру для
простейшего отчета:

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
? "Итог: ", nTotalAmount, "для", cOldSalesman
ENDDO
CLOSE Sales

Следующий фрагмент демонстрирует как LOOP может быть
использован для обеспечения промежуточных условий процесса:

DO WHILE <условие>
<инициализация процесса>...
IF <промежуточные условия>
LOOP
ENDIF
<продолжение процесса>...
ENDDO

Этот пример показывает использование команды DO WHILE для
того, чтобы эмулировать повтор до тех пор пока существует цикл:

LOCAL lMore = .T.
DO WHILE lMore
<команды>...
lMore = (<условие>)
ENDDO

Следующий пример показывает конструкцию цикла при
использовании файла базы данных:

DO WHILE .NOT. EOF()
<команды>...
SKIP

114


ENDDO

-------------------------------------------------------------------
EXTERNAL Сообщает имена компановщику
------------------------------------------------------------------


EXTERNAL <список процедур>

Аргументы

<Список процедур> определяет список имен процедур, функций
пользователя и файлов форматов, которые будут добавлены в список
подпрограмм и использованы при компановке файла в (.EXE) файл.

Применение

EXTERNAL является коммандой определения ссылок компановщику.
EXTERNAL должен быть определен в программном файле перед вызовом
процедуры или пользовательской функции. Во время компиляции
исходного текста, все явно заданные ссылки на процедуры и
пользовательские функции делаются для компановщика. В некоторых
случаях может не быть явно заданных ссылок. EXTERNAL насильно
назначает процедуры или пользовательские функции на компановку, если
не было явно заданных ссылок в исходном файле. Это важно в следующих
случаях:

FEПроцедуры, пользовательские функции или форматы содержались
макро выражениях или переменных.

FEПроцедуры и пользовательские функции использовались в
командах REPORT и LABEL и не имели ссылки в исходном тексте.

FEПользовательские функции использовались в индексных ключах и
не имели ссылок в исходном тексте.

Для группировки всех EXTERNAL поместите их в отдельный файл
заголовков и затем с помощью директивы #include включите его в
программный файл. Файл STD.CH содержит ссылки на все стандартные
подпрограммы.

Пример использования

Этот пример показывает файл заголовков, содержащий общие установки
EXTERNAL для REPORT FORM:

// Externals.ch
EXTERNAL HARDCR
EXTERNAL TONE
EXTERNAL MEMOTRAN
EXTERNAL STRTRAN

-------------------------------------------------------------------

115


FIELD Определяет имена полей базы данных
------------------------------------------------------------------


FIELD <список полей> [IN <алиас>]

Аргументы

<список полей> - список имен полей для объявления компилятору.

IN <алиас> указывает алиас для присвоения когда существуют не
алиасные ссылки на имена, указанные в списке. Если алиас не указан,
то не алиасные ссылки на переменные в списке переменных трактуются
как пердшествующий специальный алиас поля (FIELD().

Применение

FIELD определяет имена полей базы данных для компилятора и заменяет
алиас для каждого имени. Это позволяет компилятору разрешить ссылки
на переменные с неявным алиасом указанным в команде.

Команда FIELD не открывает базы данных и не проверяет существование
указанных полей. Она полезна для управления ссылками на поля базы
данных. Попытка доступа к полям базы данных, не указанных в команде
USE вызывает ошибку.

Пример использования

Пример пользовательской функции, которая содержит команды для
определения имен полей базы данных в текущей рабочей области и в
области Employee:

FUNCTION DisplayRecord
FIELD CustNo, OrderNo, Salesman
FIELD EmpName, EmpCode IN Employee
USE Employee NEW
USE Orders NEW
//
? CustNo // Ссылка на Orders->CustNo
? EmpName // Ссылка на Employee->EmpName
//
CLOSE Orders
CLOSE Employee
RETURN NIL

-------------------------------------------------------------------
FOR...NEXT Выполнение цикла со счетчиком
------------------------------------------------------------------


FOR <перМ> = <вырN1> TO <вырN2> [STEP <вырN3> ]
<команды>...
[EXIT]

116


<команды>...
NEXT

Аргументы

<переменная памяти> представляет собой управляющую переменную
цикла.

<вырN1> определяет первоначальное значение управляющей
переменной (нижняя граница цикла).

<вырN2> задает верхнюю границу цикла.

STEP: Опция STEP через выражение <выр.N3> задает значение
пошагового приращения управляющей переменной. По умолчанию
принимается приращение, равное 1.

EXIT: Опция EXIT позволяет независимо от управляющих условий
выходить из цикла. Управление передается первой команде, следующей
за строкой NEXT.

Применение

Данная команда позволяет организовать циклическое выполнение
команд,в процессе которого значение управляющей переменной получает
определенное пошаговое приращение. В результате эта переменная
изменяется от своего первоначального нижнего значения до
определенного верхнего. С каждым шагом цикла Клиппер осуществляет
перерасчет числовых выражений строки FOR, благодаря чему значения
верхней границы и приращения являются динамичными.

Пример использования

Пример обработки массива в порядке возрастания элементов:

nLenArray = LEN(массив)
FOR i = 1 TO nLenArray
<команды>...
NEXT

Обработка массива в обратном порядке:

nLenArray = LEN(массив)
FOR i = nLenArray TO 1 STEP -1
<команды>...
NEXT

-------------------------------------------------------------------
FUNCTION Объявление определяемой пользователем функции
------------------------------------------------------------------


[STATIC] FUNCTION <функция>[(<список параметров>)]

117


[LOCAL <имя> [[:= <выраж.>], ... ]]
[STATIC <имя> [[:= <выраж.>], ... ]]
[FIELD <список имен> [IN <алиас>]
[MEMVAR <список имен>]
.
. <выполняемые команды>
.
RETURN <выраж.>

Аргументы

<функция> задает имя создаваемой функции. Имена процедур и
функций пользователя могут включать до 10 символов.

<список параметров> определяет список переменных параметров.
Переменные, указанные в этом списке объявляются локальными.

STATIC FUNCTION определяет пользовательскую функцию, которая
может быть включена только процедурой или пользовательской функцией,
объявленной в некотором программном файле (.prg).

LOCAL определяет и инициализирует список переменных или
массивов, которые видимы и существуют только в текущей функции.

STATIC определяет и инициализирует список переменных или
массивов, которые видимы и существуют во время выполнения программы.

FIELD определяет список идентификаторов для использования имен
полей базы данных, когда они встречаются.

MEMVAR определяет список идентификаторов для использования как
скрытых переменных памяти, так и глобальных переменных или массивов.

RETURN <выраж.> посылает код возврата в вызов процедуры или
возвращает значение <выраж.> в пользовательскую функцию. Каждая
функция должна иметь одну комманду RETURN с возвращаемым значением.

Применение

Команда FUNCTION определяет пользовательскую функцию и список
локальных переменных для получения параметров. Пользовательская
функция является подпрограммой, включающей в себя установки и
операторы выполнения когда вы указываете имя функции, а затем
круглые скобки. Определение функции начинается с команды FUNCTION и
заканчивается следующей командой FUNCTION или командой PROCEDURE или
концом файла. Функции используются для скрытого описания
вычисляемого блока программы и затем создания выражений,
использующих возвращаемое значение.

Функции в Клиппер такие же как и процедуры, за исключением того, что
должны возвратить значение. Возвращаемое значение может быть любого
типа, включая массив, код блока или нулевое значение. Каждая функция
должна начинаться с команды FUNCTION и содержать одну комманду

118


RETURN с аргументом. Определения функций не могут быть вложенными.
Существуют два типа функций: функции, которые доступны где-либо в
программе, создаются как глобальные функции и определяются коммандой
FUNCTION; функции, которые доступны только в текущем программном
файле создаются как статические функции и определяются коммандой
STATIC FUNCTION. Статические функции используются по ряду причин. Во
первых, они ограничивают видимость имен функций. Таким образом
ограничивается доступ к функции. Во вторых, статические функции
устанавливают ссылки во время компиляции. Это позволяет выполнить
именно статическую функцию, если существует глобальная функция с
таким же именем.

Замечания

Вызов пользовательской функции: Пользовательская функция
вызывается стандартным образом:

<функция>([<список аргументов>])

Пользовательская функция может быть вызвана внутри выражения. Она
также может быть вызвана как алиасное выражение с некоторым алиасом
и заключена в круглые скобки:

<алиас>->(<функция>(<список аргументов>))

Когда функция вызвана с алиасом, выбирается соответствующая рабочая
область.

Параметры: Пользовательские функции, процедуры могут
получать параметры, посланные из вызванной процедуры, пользова-
тельской функции или командной строки DOS. В Клиппер 5.0 существует
два пути получения параметров: список имен ло- кальных переменных,
которые могут быть объявлены в команде FUNCTION или список
переменных памяти, которые могут быть указаны в комманде PERAMETERS.
Но определение формальных параметров не должно быть указано в
PARAMETERS. Параметры, указанные в пользовательской функции могут
быть получены по значению или по ссылке. Для передачи параметров по
ссылке используется оператор (@). Переменные полей не могут пере-
даваться по ссылке и всегда передаются по значению.

Пример использования

Пример пользовательскую функции преобразования формата
числа:

? Currency( 1000 ) // Результат: $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

119


cNumber := TRANSFORM(nNumber, "999,999,999,999.99")
cNumber := PADL("$" + LTRIM(cNumber), LEN(cNumber))
ENDIF
RETURN cNumber

Пример пользовательской функции, которая преобразовывает
символьную строку в общий список и возвращает массив с элементами
строки:

aList := ListAsArray("One,Two") // Результат: {"One", "Two"}

FUNCTION ListAsArray( cList )
LOCAL nPos
LOCAL aList := {} // Определяет пустой массив
//
DO WHILE (nPos := AT(",", cList)) != 0
AADD(aList, SUBSTR(cList, 1, nPos - 1)) // Добавляет новый
элемент
cList := SUBSTR(cList, nPos + 1)
ENDDO
AADD(aList, cList)
//
RETURN aList // Возвращает массив

Пример определения пропущенных аргументов путем сравнения с
нулевым значением:

FUNCTION MyFunc( param1, param2, param3 )
IF param2 != NIL
param2 := "значение по умолчанию"
ENDIF
.
. <комманды>
.
RETURN NIL

Пример показывает как пользовательская функция Currency()
может быть вызвана как алиасное выражение:

USE Invoices NEW
USE Customer NEW
? Invoices->(Currency(Amount))

-------------------------------------------------------------------
IF Выполняет последовательности команд в зависимости от условия
------------------------------------------------------------------


IF <условие1>
<команды>...
[ELSEIF <условие2>]
<команды>...
[ELSE]
<команды>...

120


END[IF]

Аргументы

<условие> - управляющее выражение. Если его значение истинно
(.T.), то все последующие команды выполняются до тех пор пока не
встретится ELSEIF, ELSE или ENDIF.

ELSEIF: Эта фраза определяет команды, которые будут выполнены
если <условие> будет истинно (.T.). Вы можете указать любое
количество предложений ELSEIF внутри структуры IF...ENDIF

ELSE: Предложение с ELSE определяет команды, которые будут
выполняются, если <условие> принимает значение ложь (.F.).

Применение

Управляющая структура IF передает управление командам для которых
<условие> во фразе IF или ELSEIF принимает истинное значение
(.T.). Далее, продолжают выполняться предложения до первой фразы
ELSEIF, ELSE или ENDIF. Если не одно <условие> не принимает значение
"истинно", то выполнение передается на предложения, следующие за
ELSE.

Структура IF...ENDIF может быть вложена внутрь другой структуры
IF...ENDIF, а также внутрь других команд предлагаемых структурным
программированием. Все используемые структуры должны быть правильно
вложены.

Форма IF...ENDIF идентична конструкции DO CASE...ENDCASE.

Пример использования

LOCAL nNumber := 0
//
IF nNumber < 50
? "Меньше чем 50"
ELSEIF nNumber = 50
? "Равен 50"
ELSE
? "Больше чем 50"
ENDIF

-------------------------------------------------------------------
LOCAL Определяет локальные переменные и массивы
------------------------------------------------------------------


LOCAL <имя> [[:= <выраж.>], ... ]

Аргументы

<имя> определяет имя переменной или массива для объявления

121


локальным. Если за именем следуют квадратные скобки ([ ]), то
создается массив. Для массива используйте следующий синтаксис:

массив[<элемент1>, <элемент2>, ...]
массив[<элемент1>],[<элемент2>]...

Максимальное число элементов в массиве - 4096. Максимальное число
массивов ограничивается возможностью памяти.

<выраж.> опция назначения значения новой локальной переменной.
Для массивов эта опция не используется. Если она не указана,
переменной назначается нулевое значение.

---------------------------------------------------------------------
Внимание

Макро оператор (&) не может быть использован в комманде LOCAL.
---------------------------------------------------------------------

Применение

LOCAL определяет одну или несколько переменных или массив
локальными в текущей процедуре или пользовательской функции и должна
располагаться перед коммандами PRIVATE и PARAMETERS. Локальные
переменные доступны только внутри текущей процедуры или
пользовательской функции, в отличие от переменных памяти и
недоступны внутри вызванных подпрограмм. Локальные переменные
создаются автоматически процедурой каждый раз, где они были
объявлены. Они продолжают существовать и сохраняют значения до тех
пор, пока объявленная порцедура или пользовательская функция не
возвращает значение в программу, которая ее вызвала. Если процедура
или пользовательская функция вызвана рекурсивно (сама себя), каждое
рекурсивное действие создает установку локальных переменных.
Максимальное значение локальных переменных ограничено только
возможностью памяти.

Замечания

Отслеживание локальных переменных в отладчике: Для доступа
к локальным переменным в отладчике, необходимо скомпилировать
программный файл с опцией /B.

FE^ Локальные параметры: Список локальных параметров может быть
объявлен в комманде FUNCTION или в PROCEDURE путем указания списка
параметров в круглых скобках:

FUNCTION <имя>(<список параметров>)

Объявление локальных параметров заменяет создание закрытых
параметров с коммандой PARAMETERS.

FE^ Макро выражения: Локальные переменные не могут быть
использованы в макро переменных или выражениях. Если локальная

122


переменная ссылается внутри макро выражения вместо нее посылается
глобальная переменная с этим же именем. Если такая переменная не
существует, генерируется ошибка.

FE^ Тип локальных переменных: После того как TYPE() использует
макро оператор (&) для оценки типа аргумента, он не может быть
использован для определения типа локальной или статической
переменной или выражения, содержащего ссылку локальной или
статической переменной. Используйте VALTYPE() для оценки аргументов
и возврата типа возвращаемых значений.

Пример использования

Определение двух локальных массивов и двух локальных
переменных:

LOCAL aArray1[20, 10], aArray2[20][10], var1, var2

Определение двух локальных переменных с назначением. Первой
присваивается дата, второй - массив:

LOCAL dWhen := DATE()
LOCAL aVegies := {"Апельсин", "Лимон", "Мандарин"}

-------------------------------------------------------------------
MEMVAR Определяет скрытые переменные и глобальные переменные памяти
------------------------------------------------------------------


MEMVAR <список переменных>

Аргументы

<список переменных> список имён переменных для определения
скрытыми и глобальными переменными памяти.

Применение

MEMVAR - команда определения, которая вызывает компилятор для
того, чтобы указать ссылки на переменные, определенные без явно
заданного алиаса путем присвоения алиаса переменной памяти
(MEMVAR->). MEMVAR не используется в макро выражениях или
переменных. MEMVAR не создает и не проверяет существование
переменных. Она используется для того, чтобы обеспечить управление
ссылками на переменные, существование которых известно. Во время
выполнения указанные переменные должны быть созданы операторами
PRIVATE, PARAMETERS или PUBLIC. Попытка доступа к переменным перед
их созданием вызовет ошибку.

Пример использования

Следующий пример показывает связь между скрытой перменной и
переменной поля базы данных с таким же именем. Скрытая переменная

123


объявлена коммандой MEMVAR:

FUNCTION Example
MEMVAR amount, address
PRIVATE amount := 100
USE Customer NEW
//
? amount // Ссылка на переменную
? Customer->Amount // Ссылка на поле
//
RETURN NIL

-------------------------------------------------------------------
PARAMETERS Определяет переменные через которые будут параметром функции
------------------------------------------------------------------


PARAMETERS <список переменных памяти>

Аргументы

<список переменных памяти> одна или более имен получаемых
переменных, разделенных запятой. Количество принимаемых переменных
может не соответствовать количеству передаваемых.

Применение

Команда PARAMETRS создает переменные памяти для получения
передаваемых значений. Полученные переменные передаются как
параметры. Параметры могут быть определены как локальные переменные,
если это указано в командах PROCEDURE или FUNCTION. В этом случае
они передаются как формальные параметры.

Обратите внимlt;у CASE словиеpание, Клиппер не делает проверки аргументов и поэтому
не требует соответствия количества формальных и фактических
параметров. Определить количество реально переданных параметров
можно функцией PCOUNT().

Пример использования

Пример пользовательской функции, которая получает значения
переданные параметрами с использованием команды PARAMETERS:

FUNCTION MyFunc
PARAMETERS cOne, cTwo, cThree
? cOne, cTwo, cThree
RETURN NIL

Получение значений, переданных в локальные переменные путем
определения параметров внутри FUNCTION:

FUNCTION MyFunc( cOne, cTwo, cThree )
? cOne, cTwo, cThree

124


RETURN NIL

-------------------------------------------------------------------
PRIVATE Локализация переменной памяти, объявленной глобальной
------------------------------------------------------------------


PRIVATE <имя> [[:= <выраж.>], ... ]

Аргументы

<имя> определяет имя переменной или массива для объявления
глобальными. Если за именем следуют квадратные скобки ([ ]), то
создается массив. Для массива используйте следующий синтаксис:

массив[<элемент1>, <элемент2>, ...]
массив[<элемент1>], [<элемент2>]...

Максимальное число элементов в массиве - 4096. Максимальное число
массивов ограничивается возможностью памяти.

<выраж.> опция назначения значения новой глобальной переменной.
Для массивов эта опция не используется. Если она не указана,
переменной назначается нулевое значение или создаётся массив с
нулевыми элементами.

Применение

Команда PRIVATE создаёт массивы и переменные видимые внутри
вызванной и текущей процедуры или пользовательской функции. Эти
переменные существуют во время выполнения активной процедуры до тех
пор, пока не будут выполнены комманды CLEAR ALL, CLEAR MEMORY или
RELEASE.

Доступ к глобальным переменным, имеющим такие же имена, как и
предыдущие локальные , статические переменные или переменные поля
базы данных приводит к ошибке.

Команда PRIVATE должна быть указана внутри процедуры или
пользовательской функции и следовать за такими командами как: FIELD,
LOCAL, MEMVAR и STATIC.

Максимальное число переменных памяти в простейшей программе - 2048.
Помните, конструкции PRIVATE ALL, LIKE, EXCEPT не поддерживаются.

Пример использования

Пример создания двух массивов и трёх переменных с помощью
комманды PRIVATE:

PRIVATE aArray1[10], aArray2[20], var1, var2, var3

125


-------------------------------------------------------------------
PROCEDURE Определяет имя процедуры и формальные параметры
------------------------------------------------------------------


[STATIC] PROCEDURE <процедура> [(<список параметров>)]
[FIELD <список полей> [IN <алиас>]
[LOCAL <имя> [[:= <выраж.>], ... ]]
[MEMVAR <список имен>]
[STATIC <имя> [[:= <выраж.>], ... ]]
.
. <выполняемые команды>
.
[RETURN]

Аргументы

<процедура> имя процедуры. Имя может быть не более 10 символов и
начинаться с буквы.

<список параметров> определяет один или несколько параметров
переменных. Переменные, указанные в этом списке объявляются
локальными.

STATIC PROCEDURE определяет процедуру, которая может быть
вызвана только процедурой или пользовательской функцией, указанной в
этом же программном файле (.prg).

LOCAL определяет и инициализирует список переменных или
массивов, которые видимы и существуют только в текущей процедуре.

STATIC определяет и инициализирует список переменных или
массивов, которые видимы и существуют в течении выполнения
программы.

FIELD определяет список имён полей базы данных. IN используется
для ссылки на алиас.

MEMVAR определяет список имён переменных или массивов для
использования их как переменных памяти .

RETURN передаёт код возврата в вызывающую процедуру или
пользовательскую функцию. Если комманда RETURN не указана, то после
окончания процедуры управление передаётся подпрограмме, откуда
процедура была вызвана.

Применение

Команда PROCEDURE определяет процедуру и список локальных
переменных для получения параметров посланных из вызывающей
подпрограммы. Процедура является подпрограммой, включающей в себя
установки и операторы выполнения когда вы указываете имя процедуры,
а затем круглые скобки или взываете процедуру с помощью комманды DO.

126


Определение процедуры начинается с команды PROCEDURE и заканчивается
следующей командой PROCEDURE или коммандой FUNCTION или концом
файла.

Процедуры в Клиппер такие же как и пользовательские функции, за
исключением того, что всегда возвращают нулевое значение. Каждая
процедура должна начинаться с команды PROCEDURE и содержать комманду
RETURN для возврата управления в вызываемую процедуру или пользова-
тельскую функцию. Иногда комманда RETURN не требуется. Определения
процедур не могут быть вложенными.

Существуют два типа процедур: процедуры, которые доступны где-либо в
программе, создаются как глобальные функции и определяются коммандой
PROCEDURE, и процедуры, которые доступны только в текущем
программном файле, создаются как статические процедуры и
определяются коммандой STATIC PROCEDURE.

Статические процедуры используются по ряду причин. Во первых, они
ограничивают видимость имен процедур. Таким образом ограничивается
доступ к процедуре. Во вторых, статические процедуры устанавливают
ссылки во время компиляции. Это позволяет выполнить именно
статическую процедуре, если существует глобальная процедура с таким
же именем.

Замечания

Вызов процедуры: Существует два способа вызова процедуры в
Clipper. Первый, наиболее предпочтительный способ, - это вызов
процедуры как функции :

<процедура>([<список аргументов>])

Второй способ - это вызов процедуры с использованием комманды DO...WITH.

Процедура также может быть вызвана с использованием алиасного
выражения :

<алиас>->(<процедура>(<список аргументов>))

Когда процедура вызвана с алиасом, выбирается соответствующая
рабочая область.

Параметры: Процедуры, как и пользовательские функции, могут
получать процедуры могут полу- чать параметры, посланные из
вызванной процедуры, пользовательской функции или командной строки
DOS. В Клиппер 5.0 существует два пути получения параметров: список
имен локальных переменных, которые могут быть объявлены в команде
PROCEDURE или список переменных памяти, которые могут быть указаны в
комманде PERAMETERS. Но определение формальных параметров не должно
быть указано в PARAMETERS.

В Клиппер число указанных аргументов для передачи не сравнивается с
числом параметров в вызванной процедуре. Если число аргументов

127


меньше числа параметров, то переменной параметру с необъявленным
аргументом передается нулевое значение. Если аргумент пропущен
внутри <списка аргументов> (оставлено пустое место), то также
передается нулевое значение. Для обнаружения позиции последнего
передаваемого аргумента в списке аргументов используйте PCOUNT().

Пример использования

Пример процедуры типичной для Клиппер 5.0:

PROCEDURE Skeleton( cName, cClassRoom, nBones, nJoints )
LOCAL nCrossBones, aOnHand := {"красный", "синий"}
STATIC nCounter := 0
.
. <выполняемые команды>
.
RETURN

Пример определения пропущенных аргументов путем сравнения
их с нулевым значением:

PROCEDURE MyProc( param1, param2, param3 )
IF param2 != NIL
param2 := "значение по умолчанию"
ENDIF
.
. <команды>
.
RETURN

Пример вызова процедуры UpdateAmount() с использованием
алиасного выражения:

USE Invoices NEW
USE Customer NEW
Invoices->(UpdateAmount(Amount + Amount * nInterest))

-------------------------------------------------------------------
PUBLIC Определение глобальных переменных памяти
------------------------------------------------------------------


PUBLIC <имя> [[:= <выраж.>], ... ]

Аргументы

<имя> имя переменной или массива. Если <имя> заключено в
квадратные скобки, то создается массив. Используйте следующий
синтаксис для определения элементов массива:

массив[<элемент1>, <элемент2>, ...]
массив[<элемент1>] ,[<элемент2>]...


128


Максимальное число элементов в массиве - 4096. Максимальное число
массивов ограничивается возможностью памяти.

<выраж.> опция назначения значения новой глобальной переменной.
Для массивов эта опция не используется. Если она не указана,
переменной назначается нулевое значение или создаётся массив с
нулевыми элементами.

Применение

Команда PUBLIC создает массивы и переменные видимые для всех
процедур и пользовательских функций в программе. Эти переменные
существуют во время выполнения программы до тех пор, пока не будут
выполнены комманды CLEAR ALL, CLEAR MEMORY или RELEASE.

Доступ к глобальным переменным, имеющим такие же имена, как и
предыдущие локальные, статические переменные или переменные поля
базы данных приводит к ошибке.

Команда PUBLIC должна быть указана внутри процедуры или
пользовательской функции и следовать за такими командами как: FIELD,
LOCAL, MEMVAR и STATIC.

Максимальное число переменных памяти в простейшей программе - 2048.

Пример использования

Пример создания двух массивов и переменной :

PUBLIC aArray1[10, 10], var2
PUBLIC aArray2[20][10]

Пример создания переменной с присвоением значений:

PUBLIC cString := SPACE(10), cColor := SETCOLOR()
PUBLIC aArray := {1, 2, 3}, aArray2 := ARRAY(12, 24)

-------------------------------------------------------------------
RETURN Закончить выполнение процедуры, функции или программы
------------------------------------------------------------------


RETURN [<выраж.>]

Аргументы

<выр> - задается возвращаемое значение из функции определенной
пользователем. Если пользовательская функция закончилась без
выполнения комманды RETURN, возвращается нулевое значение.

Применение

Когда команда RETURN встречается в процедуре верхнего уровня

129


управление передается операционной системе. В процедуре, Clipper
передает управление на вызывающую функцию или процедуру и уничтожает
все локальные переменные памяти.

В процедуре или в функции определенной пользователем может быть
более чем одна команда RETURN. Но любая процедура или функция
определенная пользователем не обязательно должна оканчиваться
командой RETURN. Но если используется комманда RETURN с аргументом,
то каждая функция должна иметь хоть один RETURN с аргументом.

---------------------------------------------------------------------
Внимание

Процедура или пользовательская функция заканчивается коммандой
PROCEDURE, коммандой FUNCTION, или концом файла, но не коммандой
RETURN.
----------------------------------------------------------------------

Замечания

Массивы: Массивы могут быть возвращены из функции,
определенной пользователем.

RETURN TO MASTER: Клиппер не поддерживает RETURN TO MASTER
или любую другую форму возврата с указанием уровня возврата. Вы
можете смоделировать эти операции с помощью комманд BEGIN
SEQUENCE...END.

Пример использования

Пример, иллюстрирующий основную форму комманды RETURN в
процедуре и пользовательской функции:

PROCEDURE <процедура>
//
<комманды>...
//
RETURN

FUNCTION <функция>
//
<комманды>...
//
RETURN <выражение>

Пример возвращения массива в вызываемую процедуру или функцию:

FUNCTION PassArrayBack
PRIVATE aArray[10][10]
aArray[1][1] = "строка"
RETURN aArray

130


------------------------------------------------------------------
STATIC Определяет статическую переменную или массив
------------------------------------------------------------------


STATIC <имя> [[:= <выраж.>], ... ]

Аргументы

<имя> определяет имя переменной или массива для объявления
статическими. Если за именем следуют квадратные скобки ([ ]), то
создается массив. Для массива используйте следующий синтаксис:

массив[<элемент1>, <элемент2>, ...]
массив[<элемент1>],[<элемент2>]...

Максимальное число элементов в массиве - 4096. Максимальное число
массивов ограничивается возможностью памяти.

<выраж.> опция назначения значения новой статической переменной.
<выраж.> для статической переменной содержит массив. Если <выраж.>
не указано, переменной назначается нулевое значение или создаётся
массив с нулевыми элементами.

--------------------------------------------------------------------
Внимание

Макро оператор (&) не может быть использован в комманде STATIC.
--------------------------------------------------------------------

Применение

STATIC определяет переменные или массивы, которые доступны
только внутри того объекта, где они были созданы. Статические
переменные доступны только внутри процедуры или функции, если
определены после комманд PROCEDURE или FUNCTION. Статические
переменные доступны всем процедурам или функциям в программном файле
(.prg), если они определены перед первой процедурой или функцией в
файле.

Все статические переменные в программе создаются при первом вызове
программы и перед началом ее выполнения происходит присвоение
значений, указанных в <выраж.>.

Определения статических переменных внутри процедуры или
пользовательской функции должны располагаться перед выполняемыми
коммандами, включая PRIVATE, PUBLIC и PARAMETERS. Если переменная с
этим же именем определена как FIELD, LOCAL или MEMVAR внутри
процедуры или пользовательской функции, то компилятор выдаёт ошибку
и объектный (.obj ) файл не генерируется.

Максимальное число статических переменных в программе ограничено
только возможностями памяти. Но число элементов в статическом

131


массиве ограничено - 4096.

Замечания

Отслеживание статических переменных в отладчике: Для
доступа к статическим переменным в отладчике, необходимо скомпи-
лировать программный файл с опцией /B.

FE^ Макро выражения: Как и локальные переменные, статические
переменные не могут быть использованы в макро переменных или
выражениях. Если статическая переменная ссылается внутри макро
выражения вместо неё посылается глобальная переменная с этим же
именем. Если такая переменная не существует, гене- рируется ошибка.

FE^ Файлы памяти: Статические переменные не могут быть сохранены
коммандой SAVE и освобождены из файла памяти (.mem) коммандой
RELEASE.

FE^ Тип локальных переменных: После того как TYPE() использует
макро оператор (&) для оценки типа аргумента, он не может быть
использован для определения типа локальной или статической
переменной или выражения, содержащего ссылку локальной или
статической переменной. Используйте VALTYPE() для оценки аргументов
и возврата типа возвращаемых значений.

Пример использования

Пример создания и присвоения значения статической
переменной:

STATIC aArray1[20, 10], aArray2[20][10]
STATIC cVar, cVar2
STATIC cString := "строка", var
STATIC aArray := {1, 2, 3}

Пример использования статической переменной внутри
пользовательской функции:

FUNCTION MyCounter( nNewValue )
STATIC nCounter := 0 // Определение начального значения
IF nNewValue != NIL
nCounter = nNewValue // Новое значение для nCounter
ELSE
nCounter++ // Увеличение (+1) nCounter
ENDIF
RETURN nCounter

Пример определения статического массива, который доступен
внутри всего фрагмента программы:

STATIC aArray := {1, 2, 3, 4}
FUNCTION One
? aArray[1] // Результат: 1

132


RETURN NIL

FUNCTION Two
? aArray[3] // Результат: 3
 RETURN NIL