Процессор вывода результата компоновки данных в JSON. И не только…

У каждого разработчика возникают задачи интеграции решений. Основная масса решений призвана вывести данные из «1С:Предприятие 8» в обусловленном формате. Разработчики используют огромную часть своих драгоценных ресурсов на реализацию определенной структуры вывода и необходимого формата. А что если…

Лирическое отступление

Вспомните свои проекты интеграции, почти все они имеют вывод в виде таблицы или дерева. Примерно год назад мне пришла голову идея, а что если использовать за основу обменов систему компоновки данных — она ведь все это умеет. Почти целый год эта идея обкатывалась на различных конфигурациях, платформах и серверах; при различных требованиях к интеграции; успешно выводила сотни миллионов объектов за один подход (BI системы). Пришло время двигать технология в массы.

Как заставить это работать?

Версия 0.5.0.0
  • Необходима платформа «1С:Предприятие 8», версия и режим совместимости 8.3.6 и выше;
  • К статье прикреплена конфигурация, в ней 3 общих модуля — это часть кодовой базы из проекта «Библиотека интеграционного счастья», а так же обработка, которая умеет выводить JSON используя схему компоновки данных. Вывод максимально аналогичен выводу в ТабличныйДокумент;
    • Общие модули это основа, которая работает с вашими настройками;
    • Дополнительная обработка это готовый пример реализации вывода в JSON. Что примечательно, вы можете реализовать такую же обработку для другого формата по аналогии и она будет работать;
    • Ничего не мешает выполнять вывод даже в очень специфичные форматы.
  • Достаточно «Сравнить и объединить» с основной конфигурацией и система готова к работе;
  • Создать схему компоновки данных, инициализировать StreamObject (Дополнительная обработка) и передать, как параметры, в основной общий модуль и на выходе получить результат;
  • Ну как же без примера:
    • Быстрый вывод. Вывод с использованием дополнительных объектов, повышенное использование памяти: 

      НастройкиМакета = IHLDataComposition.NewDataCompositionTemplateParameters();
      НастройкиМакета.Schema   = СхемаКомпоновкиДанных;
      НастройкиМакета.Template = НастройкиКомпоновкиДанных;

      НастройкиВывода = IHLDataComposition.NewOutputParameters();
      НастройкиВывода.DCTParameters = НастройкиМакета;
      НастройкиВывода.CanUseExternalFunctions = Истина;

      StreamObject = Обработки.DataProcessorJSON.Create();
      StreamObject.Initialize();
      StreamObject.WriteStartObject();

      // Последний параметр указывает на быстрый вывод
      IHLDataComposition.Output(Неопределено, StreamObject, НастройкиВывода, Ложь);

      StreamObject.WriteEndObject();
      Результат = StreamObject.Close();

    • Последовательный вывод. Медленнее, чем быстрый вывод на 22.53%, но позволяет выводить результаты ограниченные только размером оперативной памяти сервера «1С:Предприятие 8»:

      НастройкиМакета = IHLDataComposition.NewDataCompositionTemplateParameters();
      НастройкиМакета.Schema   = СхемаКомпоновкиДанных;
      НастройкиМакета.Template = НастройкиКомпоновкиДанных;

      НастройкиВывода = IHLDataComposition.NewOutputParameters();
      НастройкиВывода.DCTParameters = НастройкиМакета;
      НастройкиВывода.CanUseExternalFunctions = Истина;

      StreamObject = Обработки.DataProcessorJSON.Create();
      StreamObject.Initialize();
      StreamObject.WriteStartObject();

      // Последний параметр указывает на последовательный вывод
      IHLDataComposition.Output(Неопределено, StreamObject, НастройкиВывода, Истина);

      StreamObject.WriteEndObject();
      Результат = StreamObject.Close();

  • Поверьте, в моей практике, пока не удалось встретить обмен, который не укладывался в возможности системы компоновки данных;
  • Вся конфигурация написана на английском языке, так как необходимо гарантировать работу в иностранных конфигурациях.

Видео, как это работает:

Версия 0.6.0.0
Требования:
  • Необходима платформа «1С:Предприятие 8», версия и режим совместимости 8.3.6 и выше;
  • К статье прикреплена конфигурация, в ней локализированная часть подсистемы — из проекта «Библиотека интеграционного счастья»;
  • Достаточно «Сравнить и объединить» с основной конфигурацией и система готова к работе;
  • После установки необходимо выполнить такие шаги:
    • добавить необходимые методы в справочник IHL_Methods (конфигурация пока поставляеться без встроенных методов)

    • после этого можно создавать элементы справочника IHL_ExchangeSettings (XML и CSV форматы пока не локализированы)

    • после выбора необходимого формата станет возможно добавлять методы из справочника IHL_Methods 

    • на этом этапе можно редактировать схему компоновки данных (Edit schema), а так же в конструкторе можно загрузить схему из файла

    • после создания СКД, появляеться возможность изменять настройки СКД через компоновщик настроек (страницы Structure, Parameters, Fields, Filter, Order). Внимание, после изменения СКД в компоновщик настроек будут загружены настройки по умолчанию.

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

  • Элементы справочника можно использовать для хранения и тестирования настроек ваших обменов; Вызывать необходимые настройки при определенных событиях и организовывать обмены (пока это на плечах ваших программистов, в версии 0.7.0.0 будет проще);
  • Так же осталась возможность из предыдущей версии: создать схему компоновки данных, инициализировать StreamObject (Дополнительная обработка) и передать, как параметры, в основной общий модуль и на выходе получить результат;
  • Небольшие изменения в примере из версии 0.5.0.0:
    • Быстрый вывод. Вывод с использованием дополнительных объектов, повышенное использование памяти: 

      DataCompositionTemplate = IHL_DataComposition.NewDataCompositionTemplateParameters();
      DataCompositionTemplate.Schema   = DataCompositionSchema;
      DataCompositionTemplate.Template = DataCompositionSettings;

      OutputParameters = IHL_DataComposition.NewOutputParameters();
      OutputParameters.DCTParameters = DataCompositionTemplate;
      OutputParameters.CanUseExternalFunctions = True;

      StreamObject = DataProcessors.DataProcessorJSON.Create();
      StreamObject.Initialize();
      StreamObject.WriteStartObject();

      // Последний параметр указывает на быстрый вывод
      IHL_DataComposition.Output(Undefined, StreamObject, OutputParameters, False);

      StreamObject.WriteEndObject();
      Result = StreamObject.Close();

    • Последовательный вывод. Медленнее, чем быстрый вывод на 22.53%, но позволяет выводить результаты ограниченные только размером оперативной памяти сервера «1С:Предприятие 8»:

      DataCompositionTemplate = IHL_DataComposition.NewDataCompositionTemplateParameters();
      DataCompositionTemplate.Schema   = DataCompositionSchema;
      DataCompositionTemplate.Template = DataCompositionSettings;

      OutputParameters = IHL_DataComposition.NewOutputParameters();
      OutputParameters.DCTParameters = DataCompositionTemplate;
      OutputParameters.CanUseExternalFunctions = True;

      StreamObject = DataProcessors.DataProcessorJSON.Create();
      StreamObject.Initialize();
      StreamObject.WriteStartObject();

      // Последний параметр указывает на последовательный вывод
      IHL_DataComposition.Output(Undefined, StreamObject, OutputParameters, True);

      StreamObject.WriteEndObject();
      Result = StreamObject.Close();

Планы для версии 0.7.0.0:

  • Локализировать интерфейс програмного получения настроек обмена;
  • Локализировать возможность обрабатывать API необходимого формата (Describe API, описать API есть возможность, но нигде не используеться);
  • Локализировать базовый авторизационный модуль (Базовая авторизация) + прикрепить видео трех-шаговой OAuth авторизации;
  • Локализировать подписки на события для вызова методов обмена из справочника IHL_ExchangeSettings.

На этом, пожалуй, закончу статью. Это еще не конец, проект живой и вы можете высказать свои предложения, а так же планирую дополнять статью.

27 Comments

  1. Snitkovski

    Спасибо!

    Очень интересная разработка — ознакомимся.

    И показательно, что авторы сразу говорят о «необходимости работы в иностранных конфигурациях» — отдельное спасибо!

    Reply
  2. Трактор

    Хотел изобразить что-то подобное. Но руки не доходили. Плюс посовещавшись с веб программистами решили остаться на soap.

    Reply
  3. pbazeliuk

    (2) Идея давно летала в воздухе, но как всегда не доходят руки ни 🙂 Вчера с коллегой приняли решения, добавить больше функциональности, справочник обменов, что бы можно было СКД редактировать прямо в «1С:Предприятии 8» и, возможно, логическое продолжение точку входа (HTTPСервис).

    Reply
  4. KonstB

    (0) Вопрос не по теме

    Вся конфигурация написана на английском языке, так как необходимо гарантировать работу в иностранных конфигурациях

    Почему тогда не

    StreamObject = DataProcessors.DataProcessorJSON.Create();

    или не

    TemplateParameters = IHLDataComposition.NewDataCompositionTemplateParameters();

    Почему часть на русском часть на «иностранном»?

    Reply
  5. pbazeliuk

    (4) В английской версии оно так и есть, но для обывателей этого ресурса, думаю, лучше видеть знакомые слова.

    Reply
  6. KonstB

    (5) Ясно.

    П.С, Режет глаз (часть на русском часть на «иностранном») и как результат менее понятно — ну это чисто мое мнение 🙂 Пару раз видел на боевых конфигурациях «рушлиш» — мрак … )

    Reply
  7. jaroslav.h

    Несколько раз прочитал и не могу понять применения, в чем фишка, дайте ответ? Авось и ко мне дойдет где у себя это могу прикрутить…

    Reply
  8. pbazeliuk

    (7) Представте кому-то нужны данные из «1С:Предприятие 8», ваша задача набросать СистемуКомпоновкиДанных и создать структуру отчета которая бы соответствовала вашему обмену. После прогонки данным модулем на выходе будет необходимый результат.

    Reply
  9. virtex3

    А в чем отличие перевода табличного документа в JSON вот таким образом?

    Функция СформироватьJSONизРезультата(данные)
    
    массивСтруктур = Новый Массив;
    колонки = данные.Колонки;
    
    Для каждого цСтрока Из данные Цикл
    структ = Новый Структура;
    Для каждого цКолонка Из колонки Цикл
    значение = цСтрока[цКолонка.Имя];
    типЗначения = ТипЗнч( значение );
    Если типЗначения = Тип(«Булево»)
    ИЛИ типЗначения = Тип(«Строка»)
    ИЛИ типЗначения = Тип(«Дата»)
    ИЛИ типЗначения = Тип(«Число») Тогда
    структ.Вставить( цКолонка.Имя, значение );
    Иначе
    структ.Вставить( цКолонка.Имя, Строка( значение ) );
    КонецЕсли;
    КонецЦикла;
    массивСтруктур.Добавить( структ );
    КонецЦикла;
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON( ЗаписьJSON, массивСтруктур );
    Возврат ЗаписьJSON.Закрыть();
    КонецФункции
    
    

    Показать

    Reply
  10. pbazeliuk

    (9)

    1. На каждом уровне иерархии могут быть полностью различные колонки;

    2. на вложенных уровнях (например, детальные записи) не должно быть колонок, если они есть полем группировки в родительских группах;

    3. колонки полученные из поля группировки косвенным образом должны быть вынесены на уровень группировки из детальных записей;

    4. суть не в обработке ТабличногоДокумента, ТаблицыЗначений или ДереваЗначений — по ним очень проблемно построить правильный вывод (в некоторых объектах на каждом уровне есть все колонки, что не есть правильно). Построение идет из процессора вывода.

    P. S. Именно ваш код не оптимальный, очень много лишних вычислений, так же огромный перерасход памяти. Уверен на 1 млн. структур упадет весь процесс.

    Так же в вашем коде есть ошибка, исходя из чего могу предположить, что код нигде не использовался.

    Вообще основная суть подсистемы это делать интеграции быстро, но пока остальные части не добавлены сюда. Они пока в процессе перевода.

    Reply
  11. virtex3
    Reply
  12. virtex3

    (10) если хотите разобраться, то вот структура СКД

    http://pastebin.com/Kc2V1E1K

    http://pastebin.com/Ls4MhyJ0

    http://pastebin.com/YcqwiudP

    Reply
  13. virtex3

    (10)

    Мне кажется будет логичней передавать МакетКомпоновкиДанных , а не просто СхемаКомпоновкиДанных и НастройкиПоУмолчанию

    Также как это делается в ПКД

    МакетКомпоновкиДанных = ПроцессорКомпоновкиДанных.Инициализировать(<Макет>, <ВнешниеНаборыДанных>, <ДанныеРасшифровки>, <ВозможностьИспользованияВнешнихФункций>)

    Тогда будет более универсально, как мне кажется.

    Reply
  14. pbazeliuk

    (13) Макет создается внутри общего модуля, вместо настроек по умолчанию можно использовать ваши настройки. По поводу ошибки смотрю.

    Reply
  15. pbazeliuk

    (12) Прикрепите внешний отчет, так как на тестовых конфигурациях ваш xml не собирается.

    Reply
  16. virtex3

    (15) а это не внешний отчет, он в конфигурации.

    вам отдельно отчет выгрузить из конфы или всю конфигурацию?

    Reply
  17. pbazeliuk

    (16) Только отчет и если можно сообщите версию конфигурации.

    Reply
  18. virtex3

    (17) Бухгалтерия для Казахстана, редакция 3.0, версия 3.0.11.12

    Выше скидывал настройку и СКД для АнализСубконтоТиповой

    Reply
  19. jaroslav.h

    А как отписаться от темы? Галка не снимается в доп параметрах ответа

    Reply
  20. pbazeliuk

    (18) В этого отчета нет структуры отчета. В этом основная причина. Стяну пока с партнерского портала конфигурацию посмотрю детальнее.

    Reply
  21. virtex3

    (20) и? есть идеи?

    Reply
  22. pbazeliuk

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

    В версии 0.6.0.0 есть возможность самому набросатьскопировать систему компоновки данных в Catalogs.IHL_ExchangeSettings, а так же необходимые настройки и настроить структуру отчета и тут же протестировать. Если и здесь будут ошибки их будет проще проанализировать.

    Файл конфигурации в прикреплении, чтобы не тратить вам SM.

    Reply
  23. caponid

    Если использовать итоги, то выдает ошибку

    {DataProcessor.DataProcessorJSON.ObjectModule(296)}: Поле объекта не обнаружено (Макет3)

    ColumnNames = TemplateColumns[Item.Template];

    вот собственно пример

    Reply
  24. pbazeliuk

    (23) Это известная ошибка, пока не определился в каком виде и где выводить ИТОГИ.

    Планирую к концу месяца выкатить обновление, что позволит так же описывать более декларативное и детальное описание формата вывода.

    Reply
  25. caponid

    Даже в том состоянии, в котором есть — мне очень понравилось ))

    Идея замечательная, да и код «красивый».

    Из идей развития — могу предложить сделать описание ссылки/перечисления — когда сама ссылка в выгрузке расшифровывается до ключевых полей поиска в приемнике и управляется этот механизм каким нить справочником с правилами трансформации/расшифровки ссылки.

    PS: Оказывается я совсем не понимаю код на английском… читать пришлось со словарём по ctrl+F1 🙁 — очень сложно переключаться между «текущим контекстом» и публикацией.

    PSS: Красивые иконки — поделитесь источником?

    Reply
  26. pbazeliuk

    (25) Сервис с иконками — https://icons8.com/

    По поводу идеи здесь нужно подумать, так как основная задача это обмены между различными системами, а не системами на базе 1С:Предприятие.

    Reply
  27. caponid

    За иконки спасибо. Добавил себе в закладки.

    а расшифровка ссылки — у меня в механизмах обмена (на объектах XDTO) получилось вот так

    Заданы правила формирования по объектам и выгрузка выглядит вот так:

    // это таблица ссылок для всего пакета
    <TRef T=»Справочник.Контрагенты» ID=»00000000-0000-0000-0000-123456789123″>
    <R N=»G» T=»bol» V=0/>
    <R N=»EDR» T=»str» V=»11111111″/>
    <R N=»ExtID» T=»str» V=»XX-1111111″/>
    </TRef>
    
    //а это фрагмент документа
    
    <R N=»Проведен» T=»bol» V=1/>
    // это просто ссылка
    <R N=»Автор» T=»Справочник.Пользователи» V=»00000000-0000-0000-0000-123456789000″/>
    // а это ссылка с с полями поиска
    <R N=»Контрагент» TRef=»00000000-0000-0000-0000-123456789123″/>
    

    Показать

    Основная идея — не нужно думать, для каких систем какие поля в выборке/скд для ссылки выбирать — задал один раз правила, и они будут выполнятся.

    Там же у меня и трансформация значений. — если надо что то допустим к коду добавить

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *