Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VisualFoxPro.doc
Скачиваний:
15
Добавлен:
01.07.2025
Размер:
11 Мб
Скачать
☆

5.6.2. Оценка выражения

Команда

= Expression1 [, Expression2 ...]

оценивает (инициирует вычисление) выражения Expression1 [, Expression2 ...].

Употребляется, когда нужно выполнить одну или несколько функций, не используя их результата.

Если команда содержит одно выражение, то знак = может быть опущен.

Пример:

= SomeFunc(2), SomeProc(3) && Напечатает: 2 3

SomeFunc(4) && Напечатает: 4

function SomeFunc(pVar)

? pVar

return 2 * pVar

endFunc

procedure SomeProc(pVar)

?? pVar

endProc

Замечание. Также знак = используется в VFP и как логическая операция сравнения, и как оператор присваивания.

Функция

EVALUATE(cExpression)

оценивает выражение cExpression, заключенное в кавычки, и возвращает его результат.

Тип результата выражения может быть Character, Numeric, Currency, Date, DateTime, Logical или Memo. Длина выражения не должна превышать 255 символов.

Функция EVALUATE( ) аналогична TYPE( ), но возвращает не тип выражения, а его результат.

Выражения, содержащие EVALUATE( ), являются рашмор-неоптимизируемыми. Включение EVALUATE( ) в SQL-опцию WHERE может быть причиной неверных результатов

Примеры:

stringExpr = " 'b' $ 'abc' "

? Evaluate(stringExpr) && Напечатает: .T.

stringExpr = 'Sqrt(25)'

? Evaluate(stringExpr) && Напечатает: 5.00

5.7. Управляющие конструкции

Реализуют ветвления IF … ENDIF, выбор DO CASE … ENDCASE и циклы DO WHILE … ENDDO, FOR EACH … ENDFOR и FOR … ENDFOR. Состоят из команд IF, ENDIF, DO CASE и т. д.

Конструкции могут быть вложенными. Каждая конструкция может содержать любую другую конструкцию.

Конструкция

IF lExpression [THEN] Commands ENDIF

выполняет команды Commands, если логическое выражение lExpression вычисляется со значением .T.

Конструкция

IF lExpression [THEN] Commands1 ELSE Commands2 ENDIF

выполняет команды Commands1, если логическое выражение lExpression вычисляется со значением .T., или выполняет команды Commands2 – в противном случае.

Пример. Выводятся все положительные элементы одномерного массива someArray, а также их общее количество. При отсутствии положительных элементов печатается соответствующее сообщение.

declare someArray[10]

&& Все элементы массива будут равны –2

store –2 to someArray

&& Теперь массив будет иметь 2 положительных элемента

someArray[2] = 1

someArray[5] = 3

numberOfPositiveElements = 0

for each element in someArray

&& Проверяем знак элемента массива

if element > 0 then

&& Элемент положителен. Увеличиваем numberOfPositiveElements

&& и печатаем значение элемента

numberOfPositiveElements = numberOfPositiveElements + 1

? element

endif

next

if numberOfPositiveElements > 0 then

? "Число положительных элементов в массиве someArray: ", ;

numberOfPositiveElements

else

? "В массиве someArray нет положительных элементов!"

endif

Функция

IIF(lExpression, eExpression1, eExpression2)

возвращает результат выражения eExpression1, если логическое выражение lExpression вычисляется со значением .T., или результат выражения eExpression2 – в противном случае. Также функция вернет результат выражения eExpression2, если lExpression вычисляется со значением . NULL.

Функцию следует использовать, если это возможно, взамен конструкции IF ... ENDIF. Особенно она полезна при работе с отчетами и этикетками.

Функции IIF( ) выполняется быстрее, чем эквивалентная конструкция IF ... ENDIF.

Пример 1. Заменяются отрицательные элементы массива на число –1, а положительные – на число 1.

declare someArray[10]

store –2 to someArray

someArray[2] = 1

someArray[5] = 3

someArray[9] = 0

for k = 1 to Alen(someArray)

if someArray[k] != 0 then

someArray[k] = Iif(someArray[k] > 0, 1, –1)

endif

next

&&

&& Контрольный вывод

for each element in someArray

?? element && Напечатает: –1 1 –1 –1 1 –1 –1 –1 0 –1

next

Пример 2 (приводится в справке VFP):

close databases

open database (Home(2) + 'Data\TestData')

use Employee

scan

&& Печатаем либо сообщение 'Описания нет!', либо содержимое поля Notes

? Iif(Empty(Notes), 'Описания нет!', Notes)

endScan

Конструкция

DO CASE CASE lExpression1 [Commands1] [CASE lExpression2 [Commands2]] ... [CASE lExpressionN [CommandsN]] [OTHERWISE [Commands]] ENDCASE

выполняет первый набор команд, для которого логическое выражение lExpression вычисляется со значением .T.

Так, первоначально оценивается выражение lExpression1 и если оно возвращает .T., то выполнятся команды Commands1 и управление будет передано оператору, следующему за командой ENDCASE. В противном случае, если lExpression1 – это .F., оценивается выражение lExpression2 и т. д.

Если все логические выражения lExpression вернут .F. и если имеется команда OTHERWISE, то будут выполнены команды Commands, следующие за этой командой.

Пример. Функция DoOperation( ) возвращает сумму, разность, произведение или частное двух своих первых параметров в зависимости от значения третьего параметра. Функция вернет .F., если третий параметр, задающий вид операции, имеет недопустимое значение.

op = '+' && или '–', или '*', или '/', , или '^', или ':'

a = 5

b = 2

x = DoOperation(a, b, op)

function DoOperation(a, b, op)

do case

case op == '+' or op == '–' or op == '*' or op == '/' or op == '^'

x = a &op b && Используем макроподстановку

case op == ':'

x = a / b

otherwise

x = .F.

endcase

return x

endFunc

Функция

ICASE(lCondition1, eResult1 [, lCondition2, eResult2] ... [, eOtherwiseResult])

оценивает логические выражения и возвращает один из возможных результатов. Число пар передаваемых функции параметров не должно быть более 100.

Параметры:

lCondition – оцениваемое логическое выражение. Если оно вычисляется со значением .F., то оценивается следующее выражение, если – со значением .T., то функции вернет результат соответствующего выражения eResult.

eOtherwiseResult – результат, возвращаемый, если все выражения lCondition оцениваются со значением .F. Если параметр опущен и все lCondition имеют значение .F., то функция вернет NULL.

Если функция ICASE( ) использована в выражении фильтра, например в опции FOR или WHERE, то необходимо проследить, чтобы функция SYS(3055) задавала необходимый уровень допустимой сложности выражений.

Пример. В выше приведенной функции DoOperation( ) вместо конструкции DO CASE … ENDCASE употребляется функция ICASE( ).

function DoOperation(a, b, op)

return Icase(op == '+', a + b, op == '–', a – b, op == '*', a * b, ;

op == '/' or op == ':', a / b, op == '^', a^b, .F.)

endFunc

Конструкция

DO WHILE lExpression Commands [LOOP] [EXIT] ENDDO

обеспечивает выполнение команд Commands до тех пор, пока истинно логическое выражение lExpression.

Конструкция DO WHILE … ENDDO может включать команды LOOP и EXIT.

LOOP – передает управление на начало конструкции, то есть команде DO WHILE.

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

Пример (приводится в справке VFP). Вычисляется общая стоимость имеющихся в наличии товаров, цена которых не менее 20 у. е.

close databases

open database (Home(2) + 'Data\TestData')

use Products

set talk off

gnStockTot = 0

&& Просматриваем все записи таблицы Products

do while .T.

if eof( )

exit

endif

if unit_price < 20

skip && Переходим на следующую запись

loop

endif

gnStockTot = gnStockTot + in_stock

skip && Переходим на следующую запись

enddo

clear

? gnStockTot && Выводим результат

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

do while .T. and not eof( )

if unit_price >= 20 then

gnStockTot = gnStockTot + in_stock

endif

skip && Переходим на следующую запись

enddo

С функцией IIF( ) цикл будет еще короче:

do while .T. and not eof( )

gnStockTot = gnStockTot + Iif(unit_price < 20, 0, in_stock)

skip && Переходим на следующую запись

enddo

Конструкция

FOR EACH Var [AS Type [OF Class Library]] IN Group [FOXOBJECT] Commands [EXIT] [LOOP] ENDFOR | NEXT [Var]

обеспечивает выполнение команд Commands для каждого элемента Var массива или коллекции Group.

Опция и параметры:

Type – базовый класс, имя класса или библиотеки типа (только для Intellisense).

Class Library – библиотека классов, содержащая базовый класс, имя класса или библиотеки типа (только для Intellisense).

FOXOBJECT – указывает, что элемент Var будет ссылаться только на VFP-объекты (не COM).

Команды LOOP и EXIT имеют такое же действие, как и в конструкции DO WHILE … ENDDO: LOOP передает управление на начало цикла, EXIT – обеспечивает выход из цикла (прерывание цикла).

Пример 1. См. в описании конструкции IF … ENDIF.

Пример 2 (приводится в справке VFP). Создается экземпляр Microsoft Excel и добавляется новая рабочая книга. Печатаются имена элементов коллекции, которой рабочая книга является.

oExcel = CreateObject("Excel.Application")

oExcel.Workbooks.Add

for each Sheet in oExcel.Sheets

?? Sheet.Name, " " && Напечатает: Лист1 Лист2 Лист3

next Sheet

Пример 3. Выводятся имена файлов всех форм, входящих в активный проект.

&& Проект должен быть открыт

&& Одним из свойств объекта Project является коллекция Files

for each file in _VFP.ActiveProject.Files

&& Проверяем, является ли файл формой

if file.Type = 'K' then

? file.Name && Печатаем имя файла

endif

endfor

Конструкция

FOR Var = nInitialValue TO nFinalValue [STEP nIncrement] Commands [EXIT] [LOOP] ENDFOR | NEXT

обеспечивает выполнение команд Commands заданное число раз.

Если nIncrement > 0, то цикл выполняется до тех пор, пока Var ≤ nFinalValue.

Если nIncrement < 0, то цикл выполняется до тех пор, пока Var ≥ nFinalValue.

Значение 0 для параметра nIncrement недопустимо.

На первой итерации Var = nInitialValue.

Каждое новое значение параметра Var, вычисляемое при передаче управления на начало цикла, равно Var = Var + nIncrement. (Управление на начало цикла передают команды ENDFOR | NEXT и LOOP.)

Если параметр nIncrement опущен, то он принимается равным 1.

Команды LOOP и EXIT имеют такое же действие, как и в конструкции DO WHILE … ENDDO.

Замечание. Параметры nInitialValue, nFinalValue и nIncrement являются числовыми выражениями, вычисляемыми при входе в цикл, поэтому изменение значений nInitialValue, nFinalValue и nIncrement, если они являются переменными, внутри цикла не окажет влияния на число выполняемых итераций. Однако изменение параметра Var внутри цикла влияет на число его выполнений.

Пример 1. См. в описании функции IIF( ).

Пример 2. Выводится номер первой строки двумерного массива, имеющей отрицательный элемент.

declare someArray(4, 5)

someArray = 2

someArray(3, 2) = –1

someArray(4, 3) = –1

&& Массив someArray:

&&

2

2

2

2

2

&&

2

2

2

2

2

&&

2

–1

2

2

2

&&

2

2

–1

2

2

numberOfCols = Alen(someArray, 2) && Число столбцов в массиве

flag = .F.

for iRow = 1 to Alen(someArray, 1)

for iCol = 1 to numberOfCols

if someArray(iRow, iCol) < 0 then

? "Номер первой строки с отрицательным элементом ", iRow

flag = .T.

exit && Выход из внутреннего цикла

endif

endfor

if flag then && Строка найдена

exit && Выход из вешнего цикла

endif

endfor

if not flag

? "В массиве нет отрицательных элементов!"

endif

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

numberOfCols = Alen(someArray, 2) && Число столбцов в массиве

flag = .F.

iRow = 0

do while iRow < Alen(someArray, 1) and not flag

iRow = iRow + 1

iCol = 0

do while iCol < numberOfCols and not flag

iCol = iCol + 1

if someArray(iRow, iCol) < 0 then

? "Номер первой строки с отрицательным элементом ", iRow

flag = .T.

endif

enddo

enddo

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]