Меню

Углубляемся в ABAP. (BC402)

Чтобы писать надежные и производительные программы, азбуки мало: нужно знать, какие бывают данные, как они устроены, где они живут, и как осуществляется к ним доступ; какие бывают программы, как они устроены, как в них передаются данные. Понятное дело, производительность нужно замерять, и для этого нужны инструменты. Динамическое программирование в ряде случаев может оказаться полезным (ну и опасным, конечно, тоже).

Чтобы писать надежные и производительные программы, азбуки мало: нужно знать, какие бывают данные, как они устроены, где они живут, и как осуществляется к ним доступ; какие бывают программы, как они устроены, как в них передаются данные. Понятное дело, производительность нужно замерять, и для этого нужны инструменты. Динамическое программирование в ряде случаев может оказаться полезным (ну и опасным, конечно, тоже). Типы программ, типы данных, устройство памяти, вызов программ и передача данных, арифметические и символьные вычисления, устройство и производительность внутренних таблиц, динамическое программирование, Open SQL, трассировка исполнения и производительности – рассматриваются на семинаре «BC402. Углубленное ABAP программирование». Продолжительность - 5 дней. Семинар предназначен для ABAP-разработчиков и консультантов по разработке, может быть полезен специалистам по сопровождению и безопасности. Знание тем, затронутых в семинаре нужно всем, кому придется серьезно программировать на ABAP. Семинар проводится по версии 7.40.

Необходимой предпосылкой для семинара является владение материалом семинаров:

Желательны также 

ABAP-программы могут содержать процессинговые блоки (processing blocks) пяти категорий: блоки обработки событий (event blocks), подпрограммы (forms), методы (methods), модули (modules) и функциональные модули (function modules). Не следует путать модули и функциональные модули – они весьма различны. Подпрограммы, методы и функциональные модули могут быть явным образом вызваны из ABAP-программы, они могут иметь интерфейсные параметры и локализуют декларации. Модули (просто так модули, без словечка «функциональные») и блоки обработки событий не локализуют деклараций, не имеют интерфейсных параметров и не могут быть законным образом вызваны из ABAP-программы. Модули могут быть вызваны из логики обработки экранов (а это не ABAP, это другой язык). Блоки обработки событий нельзя вызвать ни из ABAP, ни из логики обработки экранов, исполнительная система сама их вызовет в тот момент, когда сочтет, что соответствующее событие наступило. ABAP-программы могут быть различных типов, в зависимости от их типа (и – иногда - способа запуска) за время их работы с ними будут происходить различные вещи, допустимость использования процессинговых блоков той или иной категории так же определяется типом ABAP-программы. 

Примечание. Например, функциональные модули могут встретиться в программах только типа «группа функций», модули не могут встретиться в пулах классов, а в программах типа «группа типов» недопустимы вообще никакие процессинговые блоки.

В языке ABAP (начиная версии 7.02) есть 12 встроенных элементарных (скалярных) типов данных 5 числовых (i, f, p, decfloat16, decfloat34), 5 символьных (d, t, c, n, string) и два байтовых (x, xstring). Элементраные данные могут быть только этих типов. Параметры получают тип (а также размер и точность) тех данных, которые в них фактически передаются. Можно ограничить тип передаваемых данных, указав тип данных, разрешенных для параметров. Кроме конкретной типизации параметров ABAP допускает родовую типизацию, например, для данных типов i, f, p, decfloat16, decfloat34 таким родовым описателем типа будет numeric. Родовая типизация допустима не во всех случаях.

Как и во всех языках императивного программирования, в ABAP очень существенно, как устроена память, что с ней происходит, как данные передаются из одной программы в другую и из одного процессингового блока в другой. При входе пользователя в SAP-системе возникает пользовательская сессия (user session) в рамках которой пользователь может открыть параллельно несколько окон, каждому окну соответствует подразделение памяти – внешняя сессия (external session). В каждой из внешних сессий могут последовательно выполнятся программы, запускаемые командами (statements)  SUBMIT, CALL TRANSACTION или LEAVE TO TRANSACTION.

Примечание. В русскоязычной документации термин «statement» переводится как «оператор». Поскольку тем же словом переводится термин «operator» возникает неоднозначность. Во избежание путаницы я буду использовать слова «команда» и «оператор» соответственно для терминов «statement» и «operator».

При подобных запусках организуется специальное подразделение памяти – внутренняя сессия (internal session), а старая внутренняя сессия либо сохраняется в контексте пользователя, либо удаляется в зависимости от того, как именно была запущена новая внутренняя сессия.

Примечание. Увидеть память, выделенную для внешних и внутренних сессий можно в транзакции ST02.

Для той программы, запуск которой вызвал создание внутренней сессии, создается подразделение памяти – главная программная группа (main program group). Как обмениваться данными с подпрограммами, методами и функциональными модулями понятно – через интерфейсные параметры, а вот как быть, если нужно обменяться данными между блоками обработки событий или модулями других программ, вообще не имеющими интерфейсных параметров (да и подпрограммы в ряде случаев принципиально, а в ряде случаев по традиции могут не иметь интерфейсных параметров)? А вот как: при первом обращении к подэкрану или подпрограмме другой программы, эта вызываемая таким образом программа целиком берется в ту же (в данном случае в главную) программную группу. А данные внутри программной группы можно обобществить между всеми программами этой программной группы специальными декларациями. Разумеется, это обобществление памяти, как и любое обобществление, вещь потенциально опасная, а потому злоупотреблять этим не следует. Чтобы было поменьше таких обобществлений, вызовы функциональных модулей и методов глобальных классов работают по-другому. При первом функционального модуля образуется дополнительная программная группа (additional program group), в которую берется функциональная группа целиком. При последующих вызовах функциональных модулей из этой функциональной группы перезагрузки группы не будет и эти функциональные модули будут работать с тем состоянием памяти группы, которое к этому моменту окажется. Разумеется, при исполнении функциональных модулей могут также возникнуть внешние вызовы подпрограмм или подэкранов. В таком случае соответствующие программы будут загружены уже в эту дополнительную программную группу.

Интерфейсом вызываемого отчета является набор его параметров и критериев, интерфейсом транзакции – BDC-таблица, содержащая сведения на каком экране какой программы в какое поле какая информация вводится. Но не всегда при вызове программы удается передать данные через ее интерфейсные параметры. В пределах каждой внешней сессии можно передавать данные из одной программы в другую через ABAP-память. Одна программа данные в нее экспортирует, а другая – импортирует. Каждая команда экспорта образует отдельный кластер данных в ABAP-памяти. В кластере памяти могут одновременно находится совершенно различные данные: скаляры, структуры, внутренние таблицы. Разумно давать этим кластерам различающиеся идентификаторы, иначе старое содержимое кластера будет полностью заменено новым содержимым. Состояние ABAP-памяти свое собственное для каждой внешней сессии. При диалоговой работе внешние сессии связаны с экранами. В ряде случаев бывает полезно организовать передачу данных между экранами различных внешних сессий. Для этого существует SAP-память. Она общая для всех внешних сессий одной пользовательской сессии. Поскольку она предназначена для передачи данных с экрана на экран, а на экранах нельзя ввести ничего, кроме текстов, то устроена SAP-память просто: это набор именованных текстовых «карманов» - set/get-параметров. Существуют команды, позволяющие обмениваться данными через SAP-память, set/get-параметры можно привязать к полям экранов.

Память под данные может выделяться статически один раз на все время исполнения программы или динамически по мере надобности. Статически выделяется память для элементарных данных фиксированной длины и для структур, все компоненты которых имеют фиксированную длину. Такие данные называются плоскими (flat). Символьные и байтовые строки, а также внутренние таблицы называются глубокими (deep), память под них выделяется динамически. Для доступа к глубоким данным в системе используются специальные заголовки, содержащие среди прочего ссылки на место, занимаемое данными в памяти. Если несколько различных глубоких объектов данных (переменных) имеют одинаковое значение, то сами данные существуют лишь в единственном экземпляре, а заголовки разных объектов данных содержат одну и ту же ссылку. Динамическое выделение памяти более экономно, но приводит к интересным эффектам. Если, например, создать две внутренние таблицы с одним и тем же содержимым, а потом удалить запись из одной из них, то место, занимаемое этими таблицами, увеличится.

Обычно память под переменные выделяется в той области, которая предоставляется рабочему процессу, и эта переменная будет доступна только этому процессу. В ряде случаев бывает нужно сделать данные доступными для всех рабочих процессов. Для этого можно создать такие классы, атрибуты объектов которых будут храниться в общей памяти сервера приложений. Такой объект называются shared, в русскоязычной документации стандартный перевод еще не устоялся, используются варианты: «общий», «совместно используемый». Существует специальная синтаксическая конструкция, позволяющая создавать классы таких объектов. Совместно используемые объекты могут понадобиться для разных целей, соответственно можно определить различные области памяти совместно используемых объектов. В той программе, которая создала совместно-используемый объект, есть ссылка на него, другим же программам эта ссылка изначально неизвестна. Для получения доступа к совместно используемым объектам для каждой области автоматически создается свой собственный класс (с тем же именем, что у области), методы которого управляют работой с совместно используемыми объектами.

ABAP первоначально создавался так, чтобы быть похожим на естественный английский. Поэтому в нем широко используется команды, синтаксис которых устроен как раз так, чтобы уподобить их естественному языку. Для языка программирования подобие естественному языку необязательно. Тем более что, многие языки программирования строятся на использовании выражений. Выражения - это комбинация имен объектов данных, функций, методов, операторов и литералов, возвращающая вычисленное значение. Запись алгоритма с помощью выражений оказывается компактнее, чем с помощью команд. Движение в сторону все большего использование выражений ярко обозначилось с версии 7.02, когда среди прочего появились символьные выражения и много новых полезных встроенных функций. С версии 7.40 появилась возможность инлайновой декларации объектов данных и операторы - конструкторы, создающие объекты данных во время исполнения выражений, что значительно увеличивает гибкость языка.

Вычисление арифметических выражений

Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland

У вас уже есть учетная запись?

Войти