Р. Кречмер, В. Вейс - Разработка приложений SAP R3 на языке АВАР4. Р. Кречмер, В. Вейс - Разработка приложений SAP R3 на языке АВАР. Разработкаприложений sap r3Рюдигер Кречмерна языкеВольфганг Вейс
Скачать 28.36 Mb.
|
Глава 10 Подпрограммы и функции • Локальные подпрограммы • Глобальные функции системы • Интерфейсы • Исключения 110 Глава 10 AВАР/4 предлагает разработчикам различные средства, которые облегчают создание больших про- грамм, позволяя многократно использовать готовые компоненты программного обеспечения. В этой главе рассматриваются наиболее важные элементы техники модульного программирования: * Формы {или подпрограммы) — программные модули, локализованные в конкретной программе • Функции — глобальные программные компоненты, которые могут вызываться из разных программ Модули обоих типов поддерживают инкапсуляцию локальных переменных и различные способы передачи данных через интерфейсные параметры (например, по значению или по ссылке). У функций— общий интерфейс, который поддерживается средствами его описания. Поскольку формы по своей сути являются внутренними модулями, они имеют доступ к глобальным данным вызывающей программы. Функции вызываются из различных программ, поэтому к ним применяются более жесткие интерфейс- ные правила, позволяющие изменять только их параметры и локальные данные. Если тип интерфейсного параметра задан, его проверка для форм и функций осуществляется во время выполнения средствами синтаксического контроля (Syntax Check). В противном случае произво- дится его преобразование к типу фактических параметров формы, если соответствующие формальные параметры имеют общий тип или тип вообще не указан. Параметры функции идентифицируются по именам, а параметры формы — по своему положению в списке параметров. Функции обеспечивают удобную обработку исключений. Кроме того, при возникновении необходи- мости добавления новых условий или параметров это можно сделать, не изменяя всех вызывающих функцию программ, что особенно важно при разработке крупных распределенных систем. Другие принципы модульного программирования (в том числе вызовы отчетов и транзакции) будут рассмотрены в главах 18 и 21. Модульное программирование с использованием форм Форма, или подпрограмма, определяется парой операторов (своеобразных скобок) form/endform и вызывается из основной программы с помощью оператора perform: data value ' G' . write write flag. flag = . write flag. endform. При выполнении команды perform обрабатываются все операторы, находящиеся между оператором form и первым встретившимся после него оператором endform. Глобальную переменную, опре- деленную в этой же программе (поле flag), можно использовать и изменять внутри подпрограммы. В ре- зультате выполнения приведенной выше подпрограммы будет напечатано G L L. Формы языка АВАР/4 не возвращают значений. Возвращаемая из формы информация передается с помощью параметров интерфейса (см. далее раздел "Интерфейсы форм"). Определение формы разме- щается в конце исходных текстов программы, как показано в приведенном выше примере, и этот факт отражает главный смысл формы — событие в системе. Следовательно, любой исходный текст програм- мы, расположенный после определения формы, выполняется при работе программы, если он только содержит новую форму или событие (например, событие at line-selection). Локальные данные В предыдущем примере глобальный флаг изменялся в форме При необходимости объеди- нить и локализовать данные, принадлежащие только этой подпрограмме, следует определить эту ло- кальную переменную внутри формы обычным образом, с помощью ключевого слова data: data value ' С . write flag. Подпрограммы и функции 111 write flag. form data l_f lag ' write Здесь локальная переменная создается в форме и после выполнения приведенной подпрограммы будет напечатано G G. Использование локального имени поля flag вместо l_flag приведет к тому же результату, поскольку Глобальная переменная flag "невидима" внутри формы, а изменение локального поля, имеющего одина- ковое имя с глобальным, никак не повлияет на глобальное. Применение локальных переменных улучшает читабельность исходных текстов. Напротив, работа с данными в подпрограммах может привести к ошибкам и весьма затрудняет анализ исходного текста программы. Именно поэтому мы настоятельно рекомендуем использовать преимущественно локальные данные. Иногда бывает необходимо сохранить содержимое локального объекта данных от одного вызова под- программы до другого (т.е. внутри нее). В этом случае следует применять статические переменные. Например, можно сосчитать все вызовы формы: form count. s t a t i c s c a l l s c a l l s = c a l l s + 1. write c a l l s . При первом вызове формы count значение статической переменной calls увеличивается на 1, при втором — еще на 1, поэтому в результате будет напечатано 1 и 2. Синтаксис оператора statics такой же, как и у оператора data. Использование статических переменных в формах или функциях особенно важно при работе с локальными внутренними таблицами, так как дает возможность сохранять их, а не строить заново при каждом вызове подпрограммы. Следует быть очень внимательным при работе со статическими переменными, поскольку они сохраняют свои предыдущие значения при вызове формы, создавая немало проблем при отладке программы. Интерфейсы форм Приведенные выше примеры форм не имеют параметров интерфейса, которые становятся необхо- димыми при увеличении количества программных текстов. Обычно алгоритм выполнения подпрограм- мы записывается в общем виде и может применяться в различных случаях. Чтобы при каждом вызове получить правильный результат, нужно присвоить параметрам необходимые (и, может быть, разные) фактические значения. Например, следует локализовать вычисления налога с оборота внутри подпро- граммы, а затем всякий раз вызывать ее, задавая разные параметры на входе. В этом случае одни пара- метры будут служить входными, а другие — выходными. В АВАР/4 поддерживаются различные способы передачи параметров. Для экономии времени начнем с параметров, вызываемых по ссылке; их можно считывать и изменять внутри подпрограммы. В разделе "Классификация параметров" будут рассмотрены и другие методы. Ниже приведен пример подпрограммы, которая изменяет и выводит на экран два различных поля имени: types: (25) . data: type value , type value 'B' . set__name changing form changing type write f f name = ' Smith' . 112 Глава 10 write f_name. endform. Выполнение этой программы происходит следующим образом: • При первом обращении к форме с фактическим параметром name_l формальный параметр f_name получает значение name_l. • В рамках выполнения формы формальный параметр f-name выводится на экран вначале со своим первоначальным содержимым — А, затем ему присваивается значение Smith, и на экран выводится его новое содержимое. • При втором вызове формы формальный параметр f_name получает значение name_2. • При выполнении формы формальный параметр f_name выводится со своим содержимым В, затем ему присваивается значение Smith, и на экран выводится его новое содержимое. Типы фактических и формальных параметров всегда сравниваются, и при их несоответствии может возникнуть ошибка. Проверка соответствия типов подробно изложена в разделе "Контроль соответствия типов". В самом общем случае могут использоваться несколько параметров. Примером служит приведенный ниже текст: perform f changing a2 аЗ. form f changing 1 like al f2 like a2 f3 like a3. = f 1 + При выполнении программы формальные параметры получают соответствующие фактические зна- чения: 1. получает значение 2. f2 получает значение а2 3. получает значение аЗ Число параметров в определении формы (после слова form) и в ее вызове (после слова perform) должно совпадать. Синтаксическая проверка (Syntax Check) выполняется в режиме редактирования Editor до запуска программы. Следует также соблюдать порядок параметров, так как его изменение может не только привести к неверному результату, но и к возникновению ошибки при выполнении программы. Очень удобно давать "прозрачные" имена формальным параметрам, чтобы впоследствии было ясно, какому фактическому параметру соответствует каждое из них. В то же время имя параметра должно отражать его функциональное назначение при выполнении формы. Например, можно задать для них префикс f или или другие условные обозначения. Классификация параметров Параметры интерфейса бывают двух типов: • ТОЛЬКО ДЛЯ чтения (read only): параметры передаются в подпрограмму, но не изменяются в ней • Изменяемые (changing): параметры передаются в подпрограмму и изменяются внутри нее По отводимому им пространству в памяти и способам передачи (реализации) их можно классифи- цировать как • Передаваемые по значению (by value): в параметр копируется его реальное значение, и подпро- грамма всегда работает с этой копией • Передаваемые по ссылке (by reference): в подпрограмму передается только ссылка на его реаль- ное значение (адрес в памяти), а подпрограмма считывает или изменяет его Все возможные комбинации упомянутых выше типов параметров приведены в следующей таблице, которая содержит синтаксические определения параметра р, принятые в АВАР/4. Подпрограммы и функции 113 Чтение/Изменение По значению По ссылке Только для чтения using value (p) using p Изменяемые changing value (p) changing p Синтаксис определения формы точно указывает на способ передачи параметра, поэтому в вызываю- щей программе можно не предусматривать различий способа передачи (по ссылке или по значению). Кроме того, возможно сочетание способов передачи. Например, форма может иметь два входных пара- метра - и один из которых (fl) передается по значению, а другой — по ссылке. Выходной параметр f3 (см. пример) передается по значению: perform calc using a2 changing a3 . form calc using value like al like a2 changing value При выполнении формы создаются временные локальные копии фактических параметров al и аЗ (например, и сЗ), которые замещают формальные параметры и Фактическое значение а2 на- прямую замещает После этого тело формы выполняется с помощью этих фактических значений параметров. В нашем примере выполняемое вычисление сЗ = + (а2 * сЗ) использует локальные копии и сЗ и фактическое значение а2. В конце, после выполнения оператора endform, значение временной локальной копии сЗ присваивается фактическому параметру аЗ. Самый простой способ изменить параметр — передать его по ссылке. Конечно, в этом случае разрушение или потеря данных в подпрограмме неизбежно повлияет на исходную информацию. Передача по значению неизменно создает локальную копию фактического параметра, что не всегда возможно при гигантских емах данных (например, при создании внутренней таблицы с очень большим числом строк). Важно понимать различия в использовании параметров, определенных как using и как changing {передаваемых по ссылке — правый столбец в приведенном выше списке). Параметры, описанные как using, не могут изменяться внутри формы. Синтаксис служит только для описания параметра, однако при выполнении программы различий между этими определениями (using и changing) нет. Чтобы легчить чтение программы, рекомендуем по-разному обозначать входные (using) и выходные (changing) параметры, передаваемые по ссылке. Функции АВАР/4 никогда не изменяют параметры "только для чтения" (см. раздел "Интерфейсные параметры"). Допускается также передача в подпрограмму внутренних таблиц со строкой заголовка (дополнение header lines определения tables). Параметры таблицы всегда передаются по ссылке. Этот способ передачи возвращает нас к ранним реализациям когда для интерфейсных параметров не предусматривался тип. Поэтому для совместимости с более ранними версиями поддерживается передача параметров таблицы по ссылке. В качестве замены присвоению типа в интерфейсе можно задать структуру таблицы. Например, приведенная ниже форма заполняет внутреннюю таблицу данными всех клиентов: data like customers occurs 50 with header line. perform tables form tables structure select customers into table end Контроль совместимости типов В приведенном ниже примере формальные параметры имеют ссылки на типы или поля с помощью оператора type или и тем самым им приписывается тип. Если тип был определен, то технический тип фактического параметра должен совпадать с техническим типом соответствующего формального параметра. Технический тип состоит из элементарного типа АВАР/4 (с, i, p, n, f, d, t), длины и числа десятичных разрядов после запятой. Если технические типы не совпадают, система посылает сообщение при выполнении синтаксического контроля или самой программы. data: , (2) . changing set_name changing set__name changing f name l i k e name f_name = ' . 114 Глава 10 Фактический параметр name_l по типу и длине соответствует формальному параметру f_name, но f_name не соответствует name_3 по длине. Таким образом, программа написана неверно и при синтак- сическом контроле будет выведено сообщение об ошибке. Контроль совместимости типов распространяется только на технические типы полей. Если два поля имеют различные типы, но одинаковые технические типы, то проверка не выявит ошибок. Рассмотрим следующую программу: types: , t_nama_2 (25) . type type perform changing changing changing l i k e ' , В этой программе ошибок нет, поскольку технические типы фактических и формальных параметров совпадают. Результат будет таким же, если используется неэлементарное определение типа: form set_name changing f_name type t name_2. Если параметр имеет тип структуры (запись или внутренняя таблица), то соответствующие компо- ненты формального и фактического параметров будут сравниваться на уровне элементарных типов. Однако не всегда контроль совместимости типов полезен. Например, когда фактические параметры имеют другую длину или даже элементарные типы (такие, как строка символов или цифр), контроль типов можно отменить (как при синтаксической проверке, так и при выполнении программы), не ука- зав описание типа в интерфейсе подпрограммы. value 'АВ' , value form changing deleting leading write at Аналогично первому примеру в определении интерфейса разрешается использовать базисные ментарные типы: form changing type с. В этом случае контроль типов сводится к сопоставлению элементарных типов формального и фак- тического параметров, однако размер и число десятичных разрядов не проверяются. Например, в при- ниже подпрограмме первый вызов корректен, а второй записан неверно, так как тип поля не равен с: data <3). data type perform changing: Поддерживаются также базисные табличные типы. Можно указать, что параметры являются внут- ренней таблицей без ссылки на тип строки таблицы: form changing type sort search ' . Эта подпрограмма может работать с любой внутренней таблицей. В частности, внутри нее возможны такие специальные операции, как сортировка (sort) (см. главу 12, где рассматриваются операции, исполь- зуемые во внутренних таблицах). Если базисный табличный тип не указан, то при выполнении опера- тора возникает синтаксическая ошибка. Таким образом, контроль типов в интерфейсах подпрограмм обеспечивает следующие преимущества: Подпрограммы и функции 115 • Безопасность: успешное завершение проверки совместимости типов гарантирует (с высокой степенью надежности), что параметры не перепуганы и в их записи нет опечаток. • Читабельность исходных текстов: формальные параметры выполняют роль описания интерфей- са подпрограммы. • Повышение производительности программы: многие операции выполняются гораздо быстрее, если тип параметра в программе известен при генерации (создании выполняемого текста) программы. Создание функций увеличения возможности многократного использования текстов В отличие от подпрограмм функции обычно применяются во множестве различных программ и по- тому содержат лишь строго инкапсулированные данные, т.е. данные в функции могут изменяться только через ее интерфейс. Аргументы функции определяются с помощью имен, а не по их расположению в списке параметров, как в подпрограмме. При необходимости добавления в функцию новых условий или параметров это можно сделать, не изменяя все вызывающие программы этой функции. Кроме того, они обеспечивают удобную обработку исключений. Функции определяются парой операторов — function и endfunction и вызываются с помощью опе- ратора call function. Имя функции записывается прописным» буквами. c a l l f u n c t i o n ' MY_FIRST_FUNCTION' . f u n c t i o n ' MY_FIRST_FUNCTION' . w r i t e 'My f i r s t f u n c t i o n ! ' . e n d f u n c t i o n . При использовании средства описания интерфейса функций редактор АВАР/4 Editor не редактирует операторы function/endfunction или параметры интерфейса, а описывает функцию и ее параметры (см. раздел "Интерфейсные параметры"). Для изменения (редактирования) оператора вызова функции необ- ходимо указать в меню Editor: Edit (редактировать), а затем Insert Statement (вставить оператор). Сис- тема вставит асе параметры и исключения интерфейса. Функциональные группы и функции ДЛЯ создания функции с помощью средств Development Workbench в первом окне Object Browser, в части экрана Single Object (один объект), выберите из переключателя опций Function Group Objects (объекты функциональных групп) (рис.10.1). Рис. 10.1 Задание объекта функциональной группы |