Краткое пособие по языку INFORMIX-4GL

# присвоить значение элементу массива можно так: LET massiw[1,i+2].kolwo = zap.a + LENGTH(massiw[1,i+2].tip) Для сокращения перечисления элементов в списках можно пользоваться нотацией (*). Например, strkt.* означает все элементы записи strkt. А так же нотацией THRU: (элементы записи от и до) SELECT kadry.* INTO strkt.* FROM kadry WHERE kadry.tabnom=i+j SELECT * INTO strukt.b THRU strkt.e FROM kadry Глобальные переменные должны иметь одинаковые объявления GLOBALS во всех модулях программы (в которых используются). Проще всего это организуется так: заводится отдельный модуль, в котором ничего, кроме объявлений GLOBALS нет. А во всех остальных модулях программы ссылаются на этот файл. Ниже приводится пример объявления глобальных переменных в файле progrglob.4gl: DATABASE zawod GLOBALS DEFINE zap RECORD LIKE kadry.* DEFINE ext_count INT . . . END GLOBALS Тогда в остальные модули программы, где используются эти глобальные переменные, надо включить строчку GLOBALS "progrglob" . . . Подпрограммные Блоки (Функции). В языке 4GL при программировании функций (подпрограмм) используются операторы function. Все аргументы функции должны быть объявлены. Аргументы передаются по значению. Если функция возвращает какие-либо значения, то при вызове ее нужно воспользоваться в операторе CALL предложением RETURNING с перечислением переменных, в которые возвращается значение. Ниже приводится соответствующий фрагмент программы. FUNCTION stroka(rec) DEFINE rec RECORD i int, st char(256) END RECORD RETURN st clipped,"автопробега" END FUNCTION . . . MAIN . . . CALL stroka(rec1.*) RETURNING simw . . . LET simw=stroka(7,"Привет участникам ") # Если функция возвращает одно значение, то ее имя мож- # но использовать в выражениях. MESSAGE simw . . . END MAIN На экране пользователь увидит: ѓЃѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹‚ ѓЉ Привет участникам автопробега ѓЉ ѓЉ ѓЉ ѓЉ ѓЉ ѓЉ ѓЉ ѓѓѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹„ Примеры Использования Программных Операторов. Оператор безусловного перехода действует в пределах модуля. GOTO metka . . . LABEL metka: . . . Оператор выбора. CASE WHEN iscreen=1 current window is w1 WHEN iscreen=2 current window is w2 let iscreen=1 OTHERWISE current window is SCREEN END CASE CASE (a+b) # Другой формат оператора CASE WHEN 1 message "a=",a WHEN 2 message "b=",b END CASE Условный оператор. IF str = "завершить" OR y<0 THEN exit program # Не забывайте в конце каждого условного # оператора ставить END IF. END IF Оператор цикла. FOR I= i1 TO 23 let a[i]=0 if b[i]=100 then EXIT FOR END IF END FOR

Цикл "пока".

WHILE ff > 3 or nn="проба"
PROMPT "Введите число " for n
let i=n+1
message "А у меня ",i,", больше. Вы проиграли."
SLEEP 5
RUN "rm *" WITHOUT WAITING
END WHILE
Динамическое Изготовление Операторов SQL. Курсоры.
Операторы PREPARE и EXECUTE предназначены для динамического (во время выполнения программы) изготовления и выполнения операторов языка SQL (не 4GL !!!). В приведенном ниже фрагменте в ответ на запрос пользователь сможет ввести с клавиатуры строку с оператором языка SQL (Пусть, например, он введет строку: DROP DATABASE buhgalteriq). Программа изготовит из этой строки настоящий оператор и выполнит его с помощью оператора EXECUTE. Если при выполнении зарегистрирована ошибка, о чем сообщит установленный в отрицательное значение код завершения status, пользователя снова попросят ввести оператор.
DEFINE stroka char(200)
MAIN
. . .
LABEL METK2:PROMPT "введите оператор языка SQL: " FOR stroka
WHENEVER ERROR CONTINUE # Включить режим "В случае
# ошибки продолжить выполнение
# программы"
PREPARE st1 FROM stroka # Изготовить оператор из
# символьной строки
EXECUTE st1 # Выполнить изготовленный оператор
IF status<0 THEN ERROR "ошибка номер ", status, " в вашем операторе" GOTO metk2 END IF WHENEVER ERROR STOP # Восстановить режим # "В случае ошибки прервать # выполнение программы" . . . END MAIN
В системную переменную status помещается код выполнения каждого оператора 4GL (status=0 если все нормально, status<0 если произошла ошибка). Переменная status может проверяться после любого оператора программы и в зависимости от ее значения могут предприниматься какие-либо действия.
Курсоры
Если запрос к таблице возвращает несколько (больше одной) строк, то для их обработки используется так называемый курсор - указатель во множестве строк, выбранных оператором SELECT. Оператором DECLARE объявляется курсор для запроса, оператором OPEN этот запрос фактически выполняется и выбранные строки выделяются. Курсор устанавливается на первую из выбранных строк. С помощью оператора FETCH вы можете брать очередную строку, на которую указывает курсор, и помещать ее в свои программные переменные. Курсор после этого смещается на следующую строку. С помощью конструкции циклической FOREACH имя_курсора ... END FOREACH можно перебрать все строки, выбранные оператором SELECT. Оператор OPEN в этом случае не нужен.
DATABASE zawod
DEFINE zap RECORD LIKE kadry.*
DECLARE curs1 CURSOR FOR
select * from kadry where datarovd>"9/25/1973"
# в цикле FOREACH выводим на экран все строки таблицы kadry,
# в которых столбец datarovd содержит дату после 25 сентября
# 1973 года.
FOREACH curs1 INTO zap.* # Берем очередную строку и по-
# мещаем ее в запись zap
MESSAGE zap.* # Выводим запись zap на экран
PROMPT "Еще ?" FOR CHAR c
END FOREACH # Конец цикла FOREACH

В следующем примере строки выбираемые из таблицы kadry через курсор curs2 помещаются в массив z1 (но не более 100 строк).

DATABASE zawod
DEFINE z1 ARRAY[100] OF RECORD LIKE kadry.*, counter int
DECLARE curs2 CURSOR FOR SELECT * FROM kadry
WHERE datarovd<"9/26/1973" OPEN curs2 FOR counter="1" TO 100 FETCH curs2 INTO z1[counter].* # взять очередную строку и поместить ее в следующий элемент # массива z1 IF status="NOTFOUND" THEN # если выбранные сроки кончились, закончить цикл EXIT FOR END IF END FOR LET counter="counter-1" MESSAGE "В массив z1 прочитано ",counter, " записей"
Этот пример демонстрирует еще одно использование переменной status. Если оператор FETCH пытается взять сроку из курсора когда тот уже пуст, то значение переменной status устанавливается равным символической константе NOTFOUND, имеющей значение 100. Поэтому можно проверять значение status после оператора FETCH и если оно равно 100, то прекратить чтение строк из опустевшего курсора. В данном примере пользователь сам должен ввести условия, по которым будут найдены строки в таблице ceh. Он, например, может ввести: "nomerceh>15 and nomerceh<23". Программа прицепит это условие к строке, в которой записан SELECT оператор, получит строчку "SELECT * FROM ceh WHERE nomerceh>15 and nomerceh<23", изготовит из нее оператор, и для этого изготовленного оператора SELECT объявит курсор. Дальше действия аналогичны предыдущему примеру.
DEFINE z2 ARRAY[100] OF RECORD LIKE ceh.*,
counter int, simw char(200)
PROMPT "допишите оператор SELECT * FROM ceh WHERE " FOR simw
IF LENGTH(simw)=0 THEN
LET simw="TRUE"
END IF
LET simw="SELECT * FROM ceh WHERE ", simw CLIPPED
PREPARE st2 FROM simw
DECLARE cs2 FOR st2
let counter=1
FOREACH cs2 INTO z2[counter].*
LET counter=counter+1
IF counter>100 THEN
EXIT FOREACH
END IF
END FOREACH
LET counter=counter-1
MESSAGE "В массив z2 прочитано ",counter, " записей"
Программирование Экранного Обмена.
В любой момент времени на экране терминала существует ТЕКУЩЕЕ окно, через которое и выполняется ввод/вывод вашей программы. С окном связаны используемые при вводе и выводе атрибуты (например, green, revers, underline и т.п.) и номера строк окна, используемых операторами MESSAGE, PROMPT и ERROR для вывода. При открытии нового окна оно становится текущим и и весь ввод/вывод будет направляться уже в него. В окно можно вывести экранную форму, которая, представляет собой набор экранных полей, имеющих имена, и в эти поля (из этих полей), обращаясь к ним по имени, можно выводить (вводить) данные с помощью оператора DISPLAY (INPUT). Экранные поля можно объединять в экранные записи. Описание экранных полей и самой формы располагается отдельно от программы в файле описания экранной формы. Ниже приведен пример программы, иллюстрирующий работу с окнами.
OPEN WINDOW wind1 AT 2,30 WITH 10 ROWS, 40 COLUMNS
ATTRIBUTE(BORDER, REVERSE, MESSAGE LINE FIRST)
# текущим окном является wind1
. . .
OPEN WINDOW wind2 AT 5,15 WITH FORM "schoolp"
ATTRIBUTE(GREEN,PROMPT LINE LAST,
MESSAGE LINE LAST, FORM LINE FIRST)
# текущим окном является wind2
CLEAR WINDOW wind1
. . .
CURRENT WINDOW IS wind1
# текущим окном является wind1
OPEN FORM form1 from "schoolp" # Инициализировать форму form1
# Взяв ее описание из файла
# schoolp.frm
DISPLAY FORM form1 # Вывести форму form1 в текущее окно
# т.е. в wind1

В результате работы этих операторов на экране терминала появится приблизительно такая картинка:

ѓ'ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ'
ѓљ ѓ'ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ' окно ѓљ
ѓљ ѓљ значение равно 8 ѓљ ...ѓwind1 ѓљ
ѓљ ѓ'ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ'
ѓљ ѓљ цех [ 2] [литейный ] ѓљ ѓљѓщѓ‹ѓ„ ѓљ
ѓљ ѓљ таб.номер [26 ] ѓљ ѓљ окно ѓљ
ѓљ ѓљ фамилия [Петров У.Е. ] ѓљ ѓљ ...ѓ wind2 ѓљ
ѓљ ѓљ должность [бригадир ] ѓљ ѓљ ѓЉ ѓљ
ѓљ ѓљ зарплата [$340 ] ѓљѓщѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ‹ѓ„ѓљ
ѓљ ѓљ дата рождения [31.12.1952] ѓљ ѓљ ѓљ
ѓљ ѓљ ѓљ ѓљ ѓљ
ѓљ ѓ"ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ"
ѓљ ѓљ 789 ѓљ ѓљ
ѓљ ѓ"ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ"
ѓљ ѓљ
ѓљ нет таких ѓљ
ѓ"ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ›ѓ"
Операторы MENU. MESSAGE. PROMPT.
В результате работы фрагмента программы
let sta_return=podtwervdenie(" В самом деле решили закончить? ")
...
function podtwervdenie(stroka)
define stroka char(38) , kod_wozwr int
open window podtwervdenie AT 11,10 WITH 4 rows, 39 columns ATTRIBUTE(border)
display stroka at 4, 2 attribute (reverse)
menu " "
command key("Y") " Yes " "Действительно Да."
let kod_wozwr=1
exit menu
command key("N",ESC) " No " "Нет, вернуться обратно."
let kod_wozwr=0
exit menu
command key("A") " Abort " "Отменить. И кончить."
let kod_wozwr=-1
exit menu
end menu
close window podtwervdenie
return kod_wozwr
end function

на экране в текущем окне появится такое меню

+---------------------------------------+
| : Yes No Abort |
|Действительно Да. |
| |
| В самом деле решили закончить? |
+---------------------------------------+
Оператор OPTIONS
Оператор OPTIONS может установить новые режимы для ввода вывода, если вас не устраивают заданные по умолчанию.
OPTIONS MESSAGE LINE 23,
HELP FILE "h4gl.txt", HELP KEY CONTROL-T,
DISPLAY ATTRIBUTE(REVERSE, UNDERLINE)
Операторы MESSAGE, ERROR
Оператор MESSAGE выводит строку значений на экран на message line. Аргументами MESSAGE могут быть переменные и константы, но не выражения.
let ttmm=CURRENT
message "Московское время ", ttmm
error "Данных больше нет, прочитанно ", n, " строк"

Оператор ERROR делает тоже, что и MESSAGE, только со звонком и с атрибутом REVERSE. Сообщение выводится на 24-ю строку экрана.
Оператор PROMPT
Оператор PROMPT выводит на экран display-list - список значений переменных и констант, и вводит после этого с клавиатуры значение в указанную вслед за ключевым словом FOR переменную.
PROMPT "Да или нет ?" FOR answer
ON KEY (CONTROL-U)
LET answer=wozderv()
EXIT PROMPT
END PROMPT

Можно включить в PROMPT контрольные блоки, выполняющиеся при нажатии заданных клавиш. Если в данном примере во время ввода пользователь нажмет клавишу CTRL-U то выполнятся операторы из ON KEY предложения: будет вызвана функция wozderv() а затем
прерван оператор PROMPT, не завершив ввода.
Операторы обмена с экранной формой
DISPLAY и INPUT
Оператор DISPLAY выводит данные в поля экранной формы.
DISPLAY a,b,zap[i].nomerceh TO pole1,fscr.* ATTRIBUTE(BOLD)

Если имена выводимых переменных совпадают с именами экранных полей в текущей экранной форме, то можно применить ключевое слово BY NAME.

DISPLAY BY NAME fio, dolvnostx

Оператор INPUT используется для ввода значений через поля экранной формы. Можно предусмотреть дополнительные действия при вводе. Для этого в оператор можно включить контрольные блоки AFTER, BEFORE, ON KEY.

INPUT kadr.* FROM fio, dolvnostx, nomerceh
BEFORE FIELD nomerceh
message "Сегодня обслуживаются цеха 5 и 6"
sleep 2
message ""
AFTER FIELD nomerceh
IF kadr.nomerceh > 6 then
MESSAGE "Нет такого цеха, повторите"
NEXT FIELD NOMERCEH
ENF IF
END INPUT
Фрагмент, реализующий окошко подсказки.
Ниже приведен пример программирования подсказки (в процессе интерактивного диалога) с использованием экранного массива. Таблица ceh содержит два столбца: номер цеха и его название. В приведенном фрагменте вызывается функция wyborceh, которая выводит содержимое таблицы ceh в экранный массив. Пользователь передвигает курсор на название нужного ему цеха и нажимает клавишу CR. Подпрограмма определяет номер цеха и возвращает его вызывающей программе.

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...