Статья предназначена в первую очередь для консультантов и архитекторов, работающих с продуктами SAP, перед которыми стоит задача проектирования и реализации решения по подготовке отчетности в формате Excel. 

В настоящее время все большую популярность набирают облачные решения для визуализации данных, демонстрируя двузначный рост год-к-году по большинству показателей. Однако не все компании - клиенты поставщиков облачных решений могут позволить себе использовать “облака” по самым разным причинам: от требований безопасности данных до недостаточной функциональности или даже более высокой стоимости владения по сравнению с on-premise. 

Поэтому время от времени возникают задачи подготовки отчетности для визуализации в on-premise-инструментах. Автор долгое время работал и продолжает работать с решениями SAP, поэтому именно решения SAP (SAP BW/4, SAP S/4), как поставщики данных для отчетности, наиболее близки. Однако предлагаемый подход может быть скопирован и на другие системы-источники. Никаких препятствий к этому нет.

Задача формулируется так: реализовать on-premise решение по автоматической и регулярной подготовке отчетов по бизнес-данным SAP-систем (BW/4 или S/4).

Технические требования к отчетам:

  • минимальное время отклика при открытии отчета пользователем (2-4 сек)

  • возможность смотреть отчеты как на настольном, так и на мобильном устройстве (планшет, телефон)

  • комбинация табличных и графических представления данных на одной странице

  • несколько страниц (вкладок) с отчетами

  • корректное разбиение на страницы при печати на принтере/PDF.

  • отдельные табличные представления могут содержать большое число строк и/или столбцов (более 1 млн ячеек совокупно).

  • табличные представления 

    • реализуют кросс-табличный формат

    • содержат итоги, подитоги по строкам и столбцам.

    • содержат иерархические группировки

    • содержат данные нарастающим итогом по календарным аналитикам

    • поддерживают функции “автофильтр”, “фиксация прокрутки” и некоторые другие функции Excel (например, комментарии к ячейкам, merge cells)

    • добавление статических картинок

    • условное форматирование ячеек

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

Наиболее близкими стандартными инструментами SAP, подходящими для этой задачи, является a)SAP BW on HANA + Broadcaster или b)SAP BW/4 HANA + SAP BI Platform + SAP Crystal Report Enterprise + Publishing.

  • Вариант a) подходит для клиентов, остающихся пока на решении SAP BW on HANA. 

  • Вариант b) - для клиентов, перешедших на новое перспективное решение SAP BW/4 HANA и имеющих лицензии SAP BI Platform

Однако, оба этих варианта имеют те или иные ограничения, которые может быть крайне непросто или даже невозможно преодолеть, в т.ч. даже с добавлением “точечной” разработки (макросы VBA, ABAP-программы или кода на встроенном script-языке в Crystal Reports). Даже если в первоначальной постановке задачи нерешаемых требований нет, это не означает, что в будущем такие требования не появятся. Это означает, что лучше с самого начала выбрать подход, достаточно гибкий для решения как известных сейчас, так и неизвестных, но ожидаемых будущих требований. 

Очевидно, что реализация третьего варианта, варианта с) будет с высокой долей собственной разработки отдельных компонентов целевого решения. Какие же опции могут существовать для технологических решений SAP в этом случае?

Существуют классы из библиотеки ABAP2XLSX (Apache2 licence model). Написанные на ABAP, они содержат методы по генерации XLSX-файла без использования Excel: XLSX-файлы создаются напрямую из кода на ABAP. Создав программную “обертку” для этих классов внутри S/4 или BW, вы можете генерировать XLSX-файлы с требуемым форматированием. Запускать эту генерацию возможно как диалоговом, так и в пакетном (batch) режиме, что позволяет настроить автоматическую публикацию, рассылку и пр. по расписанию или событиям. 

Таким образом, все стадии процесса: извлечение данных, преобразования в формат отчета и генерация XLSX реализуются на одном языке (ABAP), и являются неотъемлемой частью хорошо знакомой в SAP-мире инфраструктуры жизненного цикла и среды выполнения ABAP-кода.

Но представляет интерес и альтернативный подход, который при определенном масштабе более эффективен и функционален. Речь идет о генерации XLSX-файла в коде на Python. Существует минимум две очень популярные python-библиотеки генерации Excel-кода: openpyxl и xlsxwriter. Это дает больше гибкости при выборе и развитии вашего решения, чем использование единственно возможной библиотеки на ABAP.  

Процессы целевого решения могут выглядеть, например, так:

  • Данные системы-источника выгружаются на регулярной основе в текстовые csv-файлы. Файлы выгружаются в каталоги сервера приложений SAP или на выделенный файловый сервер или даже в облачный каталог, если это позволяют политики безопасности.

  • csv-файлы считываются Python-программой, которая затем выполняет обработку данных (расчет подитогов, итогов, расчет нарастающих итогов, объединение нескольких наборов данных, подтягивание наименований к кодам аналитик и т.п и т.д.), генерацию и публикацию XLSX-файла

Архитектура целевого решения состоит из:

  • SAP-системы-источника данных, которая генерирует csv-файлы. Генератором файлов может быть: 

    • разработанные ABAP-программы, 

    • SAP BW OpenHub. 

В последнем случае легко настроить считывание данных из т.н. BW-запросов, в которых нередко реализуют сложную логику расчета бизнес-показателей пользовательских отчетов. Инструмент создания BW-моделей и -запросов (SAP HANA Studio BWMT) нельзя назвать инструментом “конечного пользователя”, но тем не менее он обладает мощным функционалом, позволяющим в создании даже сложных объектов во многих случаях обходиться без программирования. Однако, верно и то, что с помощью этого инструмента добиться желаемой производительности (см. требования выше) практически не представляется возможным. Поэтому результат работы BW-запроса - [кросс-]табличное представление данных - приходится визуализировать в Excel не стандартным инструментом SAP Analysis for Excel, а просто Excel. Но XLSX-файл нужно ещё подготовить и где-то разместить. А для этого применяются....

  • Python-программы, использующие библиотеки:

    • работы с данными - pandas;

    • генерации XLSX-файлов  - openpyxl или/и xlsxwriter;

    • любые другие библиотеки Python для дополнительных преобразований считанных из файлов данных;

  • Сервер для запуска Python-программ. При наличии лицензий, можно рассмотреть SAP Data Intelligence, но подойдут и другие решения. На самых начальных этапах, при небольшом количестве Python-программ - генераторов XLSX-файлов можно обойтись средствами планирования задач операционной системы

  • Полученный XLSX-файл конечный пользователь может просмотреть как в Excel, так и его opensource-аналогах (LibreOffice, OpenOffice). Последнее особенно важно для компаний, в которых не используются продукты Microsoft Office или планируется от них отказаться. Использование же стандартного on-premise SAP-инструмента для визуализации данных BW-отчетов - SAP Analysis for Excel невозможно без Excel, т.к. технически он является его addOn.

Несколько слов про центральную часть архитектуры -  Python-программы. Принимая во внимание, что генерировать XLSX-файл можно и с помощью ABAP-библиотеки, в Python это делать во многих аспектах удобнее:

  • существенно больше программистов на Python, чем на ABAP. Python изучают чуть ли не в школах, не говоря уже о ВУЗах. Нетрудно предположить, что и уровень зарплатных ожиданий для Python также ниже при прочих равных

  • Существенно больше готовых и бесплатных Python-библиотек, которые выполнят необходимые преобразования и расчеты.

  • возможно разрабатывать Python-код для генерации XLSX-файлов без доступа к SAP-системам, практически в offline-режиме. Так удобнее отдавать работу на outsource.

  • проще пользоваться всеми возможностями git-репозиториев. Да, в ABAP это тоже возможно, но это гораздо менее распространено.

  • Более лаконичный код, чем на ABAP. 

Например, при таких исходных данных для визуализации

src =  ['1;1;2020;1;10;30',
        '1;1;2020;2;11;31',
        '1;1;2021;1;12;32',
        '1;1;2021;2;13;33',
        '1;2;2020;1;14;34',
        '1;2;2020;2;15;35',
        '1;2;2021;1;16;36',
        '1;2;2021;2;17;37',
        '2;1;2020;1;18;38',
        '2;1;2020;2;19;39',
        '2;1;2021;1;20;40',
        '2;1;2021;2;21;41',
        '2;2;2020;1;22;42',
        '2;2;2020;2;23;43',
        '2;2;2021;1;24;44',
        '2;2;2021;2;25;45',
        ]

следующий компактный код

char_count  = 4 # первые 4 колонки (поля) в каждой строке данных соответствуют аналитикам. Остальные (2 в этом примере) - показатели.
column_count = src[0].count(";")+1 # общее число полей в строке с данными
src = list(map(lambda s: s.split(';'), src))
src = list(map(lambda row: list(map(lambda e, i: float(e) if i >= char_count else e, row, range(len(row)))), src))
df = pd.DataFrame.from_records(src, columns = list(map(lambda i: chr(65+i), range(column_count))))                
table = pd.pivot_table(df, values='E', index=['A', 'B'], columns=['C', 'D'], aggfunc=np.sum, margins = False)

выполняет преобразование строк в исходном массиве: разбивает строку на поля, разделенные ;. Последние 2 поля, которые по смыслу есть “показатели”, сохраняются как числа float. Первые 4 поля - это аналитики и хранятся как строки.

На выходе кода - кросс-таблица, в которой по строкам - развертка по полям A и B, а по столбцам - развертка по полям C и D. Поле E - один (из двух в исходных данных) показателей, используемый в кросс-таблице.

C    2020        2021
D       1     2     1     2
A B
1 1  10.0  11.0  12.0  13.0
  2  14.0  15.0  16.0  17.0
2 1  18.0  19.0  20.0  21.0
  2  22.0  23.0  24.0  25.0

Если добавить код для расчета подитогов и итогов по строкам и столбцам (еще 5 - 6 строк кода), получится

C                    2020                   2021                  all total
D                       1     2 total-2020     1     2 total-2021 all total
A         B
1         1          10.0  11.0       21.0  12.0  13.0       25.0      46.0
          2          14.0  15.0       29.0  16.0  17.0       33.0      62.0
          1 total    24.0  26.0       50.0  28.0  30.0       58.0     108.0
2         1          18.0  19.0       37.0  20.0  21.0       41.0      78.0
          2          22.0  23.0       45.0  24.0  25.0       49.0      94.0
          2 total    40.0  42.0       82.0  44.0  46.0       90.0     172.0
all total all total  64.0  68.0      132.0  72.0  76.0      148.0     280.0

Очевидно, что это уже почти готовая “матрица” для публикации в XLSX, после чего останется только применить форматирование [опять же, методами Python-библиотеки генерации XLSX] и файл готов. Файл можно публиковать средствами Python или операционной системы, и затем открывать в Excel, LibreOffice и т п.

Что касается производительности и потребления системных ресурсов при выполнении всех шагов процесса, начиная от выгрузки данных в csv из SAP и заканчивая генерацией XSLX-файла в Python-программе, то предложенная архитектура позволяет управлять распределением нагрузки, перенося ее с одних компонент на другие. 

Например, если Python-код потребляет слишком много памяти при выполнении подготовки данных (слишком сложные расчеты или/и миллионы строк в выгрузке), то можно, не меняя степени параллелизации выполнения Python, и не выполняя аппаратного масштабирования, рассмотреть перенос вычислений или/и большее уплотнение данных на стороне SAP-сервера. Возможно и обратное, когда уменьшать нагрузку следует уже на SAP-сервер.

Комментарии (10)


  1. la0
    11.01.2022 09:37
    +1

    Есть простое решение:
    1. Делаем в экселе нужную таблицу руками (с выравниваниями/заливками)
    2. Сохраняем эту табличку как html
    3. Используем html таблицу как шаблон для генерации отчёта на стороне основной системы(строки собирать не большие затраты)
    4. только сохраняем не с расширением .html , а с .xlsx

    Если таких отчётов немного(а CSV уже не хватает), то едва ли есть решение оптимальнее (по критерию затрат времени и эксплуатационных расходов в дальнейшем)


    1. Sergei2003 Автор
      11.01.2022 10:28

      Спасибо, интересный подход. Но не могли бы подробней рассказать про него?

      п.3 выполняется на ABAP-сервере? Вы написали "на стороне основной системы", но я хотел уточнить

      При сохранении xlsx в html создается подкаталог с несколькими файлами (css, htm, xml) и главный файл с тем же именем, что xslx, но с расширением htm. Если в xlsx вкладок было 2, то в подкаталоге создается 2 htm-файла, и править, использовать, как шаблоны, надо их. Глядя на htm-код в этих файлах, лично мне было бы много сложнее программно добавить колонки и строки в уже существующий шаблон htm-table, чем высокоуровневыми методами Python-библиотеки конструировать xslx-файл. Только для отчетов с фиксированным числом строк и столбцов это не нужно делать.

      Добавление комментария к ячейке в htm также выглядит непростым делом из-за сложности формата. А некоторые xlsx-опции (автофильтр, фиксация прокруток) вообще теряются при сохранении в html.

      Буду признателен за ваши комментарии. Сталкивались ли вы с такими задачами (программное добавление строк/столбцов в htm, новые комментарии, включение автофильтров и фиксация прокрутки) когда применяли ваш подход и как решали? По-моему, конструирование шаг-за-шагом данных в формате xslx с помощью высокоуровневой библиотеки (хоть на Python, хоть ABAPXSLX) в общем случае, все же приводит к более наглядному и компактному коду, чем вписывание в шаблон.


  1. escorial
    11.01.2022 19:15
    +1

    Спасибо, было интересно почитать про Ваш опыт!

    Думаю стоит обратить внимание на следующие моменты:

    • с учетом того, что SAP BW зачастую применяется в Enterprise среде с более высокими требованиями к безопасности по сравнению с СМБ, возможно потребуется размещение отдельной инфраструктуры под python окружение и аудит зависимостей open-source библиотек, которые будут применяться для генерации конечного XLSX, нужно будет решить вопросы их периодического обновления;

    • если мы говорим про получении отчетов из web-приложения при применении SAP EP / Fiori Launchpad и использовании отдельной среды для окружения питона и генерации XLSX, нужно будет проработать порядок передачи сгенерированного в отдельном окружении XLSX документа в текущую сессию в которой пользователь взаимодействует с SAP-окружением, с учетом его полномочий и исключения доступа к этому XLSX сторонних лиц;

    • csv-файлы как промежуточное представление выгруженной из SAP BW информации возможно не являются оптимальным способом коммуникации 2х экосистем;

    • по моему опыту в сложных отчетах зачастую пристуствует динамическая логика (группировка, форматирование, берем данные разных наборов при выполнении разных условий) - чтобы она успешно отработала на питоне нужно будет запихнуть все необходимое для принятие этих динамических решений в промежуточный csv.


    1. Sergei2003 Автор
      11.01.2022 19:52

      Да, спасибо, моменты правильно подмечены.

      По 1-му: как упоминал в посте, такой средой может быть SAP DI (OnPremise или Cloud). Для минимальных требований к отчету в XSLX, среди opensource python-библиотек понадобится одна из двух упомнянутых библиотек генерации xslx, pandas и numpy. Последние две де-факто - стандартные для Python. Может быть их известность и распространенность упростит требования безопасности к ним. Но это от внутренних политик зависит, конечно

      По 2-му: один из вариантов - ограничиться простой публикацией готовых xslx-файлов в папки на корпоративном файловом хранилище, MS Sharepoint, где уже используются все необходимые политики разграничения доступа. Зачем xslx "вытягивать" в SAP EP / Fiori, я не совсем понимаю. Удобства работы, на мой взгляд, это не добавит.

      По 3-ему. Согласен, не самый оптимальный способ. При наличии технической и, что немаловажно, лицензионной возможности, можно без большого труда забирать данные в Python-программу из БД.

      Но применительно к SAP-продуктам - источникам данных, обращение к БД напрямую требует отдельной лицензии (что не у всех клиентов есть). А при наличии лицензии внутренними политиками не всегда разрешено подключаться к продуктивным БД SAP-систем иначе, как из приложений SAP. И, наконец, не всегда готовые для xslx данные хранятся непосредственно в БД и их не вытащить без специальных настроек. Например, в случае получения данных из BW-отчета, у нас не так-то много пространства для выбора. А вот BW OpenHub в csv-файл прост, работает всегда и генерирует понятный контент.

      Файлы удобны еще и тем, что в случае их хранения вы всегда знаете, что и в какой момент было выгружено. Это очень легко проверять. В БД это сделать чуть сложнее, учитывая обычные требования "не раздувать" базу данных архивной информацией.

      По-4-му: такую логику преобразований можно убрать в исходную систему. А если это не рационально или не возможно, обратиться к той же Python.pandas, которая позволяет манипуливать dataFrames почти как таблицами в SQL.


      1. escorial
        12.01.2022 10:33

        п.2 - генерировать XLSX в текущей веб-сессии пользователя имелась ввиду работа пользователя например в SAP Fiori с карточкой какой-либо сущности (например проекта) и необходимость по нажатию кнопки в этой карточке выгрузить печатную форму паспорта этого проекта и т.д.

        п.3 - помимо csv еще можно посмотреть в сторону web-сервисов (REST, OData etc), предоставления данных посредством BICS/MDX, но посмотреть позднее что именно было выгружено из бэкенда конечно будет сложнее если такую возможность не закладывать в момент генерации конечного XLSX.


  1. Kryptonets
    11.01.2022 19:58
    +1

    Что-то сложно. А не пробовали использовать low-code решения? Коннектор в Power Query в Excel к SAP HANA или папке с csv файлами и генерить любые отчёты либо в нём либо в Power Pivot и выводить в сводную. Зачем писать программные коды, когда это может реализовать пользовательский интерфейс?


    1. Sergei2003 Автор
      11.01.2022 20:16

      Да, не просто. С PowerQuery знаком на начальном уровне. Архитектурное решение использовать PowerQuery требует ответов на многие вопросы:

      лицензии на PowerQuery (PQ)

      лицензии на доступ к SAP HANA (при обращении к ней напрямую), в т.ч. инсталляция библиотек доступа на каждую рабочую станцию с PQ

      требования отказаться от MS Excel в пользу LibreOffice (например)

      повторное использование логики, стилей и т п. в разных книгах с PQ. Не знаю, может это и можно там сделать. Не уверен

      контроль версий кода PQ. Не знаю, можно ли PQ прикрутить к git, не уверен.

      доступ через планшет/телефон. Открыть статический xslx-файл, даже немаленький, там легко и быстро. А вот как быть с PQ - не знаю.

      Мне кажется, PQ очень удобен для персонального использования, либо в очень небольших командах. Когда пользователь достаточно компетентен в модели данных, в инструменте, и сам отвечает только перед собой за то, что он там создал. Делать же отчет на PQ для пользования сотням пользователей можно, конечно, но поддерживать это все крайне сложно будет. Не претендую тут на истинность, потому что с PQ знаком, как уже писал, поверхностно.


    1. escorial
      12.01.2022 10:31

      Кажется что требования 2-4 сек. на отчет конечно убивает все попытки строить отчет онлайн на стороне клиента, получается все отчеты должны быть уже построены заранее.


  1. Kryptonets
    11.01.2022 20:42
    +1

    PQ бесплатный, к нему никакие лицензии не нужны, а начиная с 2016 Excel так вообще встроенный. Ну то, что лицензии платные к SAP - это специфика SAP. Под логикой и стилем в разных файлах не очень понял. Как построен процесс? Это один обновляемый файл, рассылаемый пользователям или множество файлов? PQ - это ETL инструмент, он выгрузит данные в точно такую же статическую таблицу в обычном xlsx файле, если это необходимо и точно также это можно будет смотреть на телефоне/планшете или выгрузить в Power Pivot, где дальше можно настроить интерактивность, если хочется большего. Любой запрос на PQ - это код на языке M, который можно зашить хоть в txt а потом из PQ ссылаться на этот txt и исполнять код, а txt можно редактировать. Ну а если вопрос о сотне пользователей, то наверное это уже не уровень Excel, а веб-интерфейсов. Хотя если это один файл, который лежит в облаке, то там хоть сто, хоть тысяча.Помню однажды реализовал безопасность на уровне строк на Power Pivot для разных групп пользователей, т. е. даже это реализуемо в Excel. В свою очередь я сам Python не знаю от слова совсем, поэтому использую сообразительность, зашёл в аналитику данных со стороны VBA, SQL, DAX, MDX, но вот до Python пока руки не дошли. Мне всегда казалось, что программирование на Python - это что то очень сложное))


    1. Sergei2003 Автор
      11.01.2022 21:39

      Python довольно простой, его даже в средней школе изучают. В отличие от M :)

      А процесс довольно обычный. Несколько упрощая, на сервере, по расписанию или по событию запускается процесс, который сначала делает csv, потом запускает python-код, делающий xlsx и публикующий его. Другой вариант - процесс запускает python-код, который подключается к БД, забирает данные, делает xlsx и публикует его.

      Если запуск PQ можно планировать (можно ли?) на сервере (на Windows, надо полагать. только :) ) и затем PQ не только в статическую xlsx-таблицу выгрузит, но и стили к ячейкам применит, комменты к ячейкам добавит, смерджит ячейки, сгруппирует строки и колонки, добавит автофильтр и бизнес-графику и зафиксирует области прокрутки, то будет, в общем-то, очень похоже, да :)

      Поправьте меня, но тогда это будет комбинация кода на M и VBA, который может вызываться вперемешку. Верно? И VBA для git придется "копи-пастить".