Управляемый цикл |
Конструкция <управляемый цикл> используется в формах, управляемых из прикладной программы.
Цикл предназначен для организации вывода в отчет многократно повторяющихся однотипных строк, называемых телом цикла. Например, цикл используется для формирования строк таблицы.
Циклы управляются потоком сообщений, поступающим из прикладной программы.
<управляемый цикл> ::= .{ [<горизонтальный цикл>] [<цикл с отступом>] [<имя цикла>] [checkenter] [<фильтр>] <тело цикла> .}
Цикл открывается ключевой конструкцией .{ и закрывается ключевой конструкцией .}, стоящими в первой позиции строки.
<Горизонтальный цикл>: Вы имеете возможность сделать горизонтальным любой цикл (управляемый цикл, цикл WHILE, цикл по SQL-таблице), при этом значения выводятся в одной строке и разделяются пробелом.
Необходимо учитывать, что длина строки ограничена возможностями Вашего принтера.
В большинстве случаев горизонтальные циклы используются совместно с циклом с отступом.
Признак горизонтального цикла рекомендуется размещать непосредственно за открывающей скобкой цикла.
<горизонтальный цикл> ::= horizontal
Горизонтальный цикл в присоединенной форме может соответствовать обычному циклу формы-прототипа.
<Цикл с отступом>: система позволяет начинать все строки цикла с отступом. Величина отступа равна последней позиции строки, предшествующей этому циклу. Первая строка цикла начинается на предшествующей циклу строке и отделяется от нее двумя пробелами.
В большинстве случаев цикл с отступом используется совместно с горизонтальным циклом.
Признак цикла с отступом рекомендуется размещать непосредственно за признаком горизонтального цикла, если такой имеется, или за открывающей скобкой цикла.
<цикл с отступом> ::= margin
<Имя цикла>: цикл может иметь имя, расположенное после открывающей скобки цикла. Имя циклу присваивается при проектировании формы-прототипа и сохраняется в присоединенной форме.
Рекомендуется использовать поименованные циклы, так как это дает возможность посылать управляющие сообщения из прикладной программы в цикл по имени, что облегчает структурирование прикладной программы.
Если цикл имеет имя, то сообщения из прикладной программы передаются поименованному циклу, иначе сообщения адресуются текущему циклу формы.
Вложенные циклы всегда именуются.
<имя цикла> ::= <идентификатор>
Количество, взаимное расположение, имена и типы управляемых циклов в форме-прототипе и в присоединенных формах должны совпадать.
Возможны циклы двух типов:
цикл с параметром checkenter, или цикл с проверкой условия на вход. Прикладная программа управляет входом в очередную итерацию цикла с помощью стандартного сообщения feDoLoop. Проверка сообщения feDoLoop проводится в начале каждой итерации цикла. Вход в цикл произойдет, если прикладная программа к началу обработки цикла пришлет сообщение feDoLoop. Если сообщение feDoLoop не прислано, цикл будет пропущен. Выход из цикла осуществляется после того, как в очереди событий не будет найдено очередное сообщение feDoLoop;
цикл без параметра checkenter, или цикл с безусловным входом. Прикладная программа управляет выходом из цикла с помощью стандартного сообщения feBreak. Проверка сообщения feBreak проводится в конце каждой итерации цикла. Выход из цикла произойдет после поступления сообщения feBreak. Если сообщение feBreak поступит к началу обработки цикла, цикл будет иметь одну итерацию.
Стандартные сообщения, управляющие циклом, формируются модулем Forms.Pas ("Приложение 3") на основе сообщений, поступающих из прикладной программы.
<фильтр> ::= ;<логическое выражение>
Цикл может иметь фильтр. Фильтры применяются только в присоединенных формах.
Фильтры в циклах используются для усечения обрабатываемого циклом потока данных прикладной программы. Фильтр является дополнительным условием, выполнение которого открывает доступ к очередной итерации цикла. Условие формируется внутри формы.
Для создания фильтров используются те же средства, что и для формирования любых других арифметических выражений формы.
При работе с несколькими вложенными циклами, имеющими фильтры, вхождение во внутренний цикл определяется только собственным фильтром внутреннего цикла и не зависит от фильтрации очередной итерации внешнего цикла.
Фильтр начинается точкой с запятой и целиком располагается в ключевой строке цикла. Между точкой с запятой и логическим выражением не должно быть пробела.
Фильтр представляет собой логическое выражение, результатом вычисления которого является логическая переменная. Если выражение истинно, то очередная итерация цикла исполняется, если ложно, то итерация пропускается.
<тело цикла> ::= [<заголовок>] <тело> [<подножие>]
Тело цикла состоит из конструкции <тело> и необязательных заголовка и подножия.
Заголовок и подножие цикла, если они заданы, печатаются на каждой странице отчета в пределах действия цикла.
Правила оформления заголовков и подножий цикла соответствуют правилам оформления заголовков и подножий формы.
В теле цикла используется та же конструкция <тело>, что и в соответствующей форме.
Пример 1
.form акт .{ цикл_внешний checkenter внешний цикл: поле 1 - @@@; поле 2 - @@@ .{ цикл_внутренний checkenter внутренний цикл: поле 3 - @@@@@@ .} .} .endform
Форма-прототип "акт" имеет два вложенных цикла. Внешнему циклу присвоен идентификатор "цикл_внешний", внутреннему циклу - "цикл_внутренний". Оба цикла с параметром checkenter. Предположим, внешний цикл исполняется два, а внутренний - три раза. Поле 1 заполняется единицами, поле 2 - двойками, поле 3 - тройками. Отчет будет иметь следующий вид:
Внешний цикл: поле 1 - 111;поле 2 - 222 Внутренний цикл: поле 3 - 333333 Внутренний цикл: поле 3 - 333333 Внутренний цикл: поле 3 - 333333 Внешний цикл: поле 1 - 111;поле 2 - 222 Внутренний цикл: поле 3 - 333333 Внутренний цикл: поле 3 - 333333 Внутренний цикл: поле 3 - 333333
Пример 2
Форма-прототип:
.form s1 .fields a:integer a1:integer a:integer .endfields .{checkenter ext hellow ^ .{checkenter asa ^ внутренний цикл .} goodby ^ .} .endform
.linkform s2 prototype is s1 .fields a a1 a .endfields .{checkenter ext;(a=1) or (a=3) hellow ^ .{checkenter asa;(a=3) or (a=4) ^ внутренний цикл .} goodby ^ .} .endform
Входной поток:
Предположим, внешний цикл должен иметь 4, а внутренний - 2 итерации в каждой итерации внешнего цикла.
1 итерация: а=1; а1=5;
2 итерация: а=2; а1=6;
3 итерация: а=3; а1=7;
4 итерация: а=4; а1=8;
Исполнение формы-прототипа:
hellow1 5 внутренний цикл 5 внутренний цикл goodby1 hellow2 6 внутренний цикл 6 внутренний цикл goodby2 hellow3 7 внутренний цикл 7 внутренний цикл goodby3 hellow4 8 внутренний цикл 8 внутренний цикл goodby4
Исполнение присоединенной формы:
hellow1 goodby1 hellow3 7 внутренний цикл 7 внутренний цикл goodby3 8 внутренний цикл 8 внутренний цикл
Пример 3
Форма-прототип:
.form t .fields x .endfields .{ x=^ .} .endform
присоединенная форма t1:
.linkform t1 prototype is t .fields x .endfields пример горизонтального цикла ----------------------------- .{horizontal x=^ .} .endform
Исполнение присоединенной формы t1.
Предположим, что цикл имеет 10 итераций. При исполнении данной присоединенной формы мы получим следующий отчет:
пример горизонтального цикла -------------------------------- 1 2 3 4 5 6 7 8 9 10
Присоединенная форма t2.
.linkform t2 prototype is t .fields x .endfields пример обычного цикла с отступом --------------------- .{margin x=^ .} .endform
Исполнение присоединенной формы t2.
Предположим, что цикл имеет 10 итераций. При исполнении данной присоединенной формы мы получим следующий отчет:
Пример обычного цикла с отступом -------------------------------- 1 2 3 4 5 6 7 8 9 10
Присоединенная форма t3.
.linkform t3 prototype is t .fields x .endfields пример горизонтального цикла c отступом ------------------------------------- .{horizontal margin x=^ .} .endform
Исполнение присоединенной формы t3:
Предположим, что цикл имеет 10 итераций. При исполнении данной присоединенной формы мы получим следующий отчет:
Пример горизонтального цикла с отступом -------------------------------- 1 2 3 4 5 6 7 8 9 10