Как организовать кодовый обмен через JSON в 1С:Шина, переходя от КД 2.1?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Переход от обмена данными, реализованного на базе «Конвертации Данных 2.1» (КД 2.1), к полностью кодовому обмену с использованием формата JSON через 1С:Шина — это масштабная и комплексная задача. Она требует не только технических знаний, но и глубокого понимания бизнес-процессов, а также тщательного планирования архитектуры решения. Мы рассмотрим, как подойти к этой задаче, учитывая опыт и рекомендации коллег.

1. Определяем истинные цели перехода и анализируем текущие правила

Прежде чем приступать к технической реализации, критически важно выяснить истинные цели, которые заказчик хочет достичь, отказываясь от КД. Просто «уйти от КД» — это не цель, а способ ее достижения. Возможно, заказчик стремится к:

  1. Повышению производительности обмена: КД может быть неэффективной при больших объемах данных.
  2. Улучшению поддерживаемости и читаемости кода: Некоторым разработчикам нативный код кажется более понятным, чем правила КД, особенно при наличии специфичных доработок.
  3. Большей гибкости: Кодовый обмен предоставляет полный контроль над структурой JSON и логикой преобразований.
  4. Лучшей интеграции с 1С:Шина: Возможно, текущая реализация на КД плохо интегрируется с архитектурой шины.

Без четкого понимания целей, мы рискуем получить «обратный эффект», потратив ресурсы на создание решения, которое не принесет желаемых выгод. Возможно, КД 3.1 или даже доработанная КД 2.1 могли бы быть жизнеспособными альтернативами, если бы истинные цели были другими.

Далее, мы должны провести глубокий анализ текущих правил обмена КД 2.1. Они могут быть крайне сложными, содержать множество обработчиков, алгоритмов и специфической логики, которая формировалась годами. Этот этап требует значительных временных и бюджетных затрат. Мы должны:

  1. Выявить все выгружаемые и загружаемые объекты: Документы, справочники, регистры, перечисления и т.д.
  2. Понять логику трансформации данных: Как поля одного объекта преобразуются в поля другого, какие используются фильтры, условия, предопределенные значения.
  3. Определить механизмы сопоставления объектов: Как КД находит существующие объекты в базе-приемнике.
  4. Идентифицировать все «слабые места» КД: Например, сложности с отладкой, проблемы с выгрузкой в регистры в тестовом режиме, медленная работа определенных участков.

2. Проектируем архитектуру кодового обмена через JSON в 1С:Шина

Когда цели определены и текущие правила проанализированы, мы приступаем к проектированию новой архитектуры. Начнем с простого, как с «Привет мир!», чтобы понять основные механизмы взаимодействия с 1С:Шина и JSON.

2.1. Основные принципы архитектуры

  1. Использование 1С:Шина как транспорта: Если Шина выступает транспортом, то она будет отвечать за доставку сообщений. Наша задача – сформировать и отправить JSON-сообщение в Шину и принять/разобрать JSON-сообщение из Шины.
  2. Четкое определение формата JSON-документов: Согласовываем структуру JSON со всеми участниками обмена. Это может быть единая схема или несколько схем для разных типов объектов.
  3. Разделение логики выгрузки и загрузки: Для каждого направления обмена (выгрузка в Шину, загрузка из Шины) создаем отдельные обработчики или общие модули. Это повышает модульность и упрощает поддержку.
  4. Централизация настроек обмена: Все параметры обмена – такие как узлы планов обмена, правила маршрутизации, логины/пароли для доступа (если используются HTTP-сервисы), настройки соответствий – храним в регистрах сведений или константах. Это позволяет гибко настраивать обмен без изменения кода.
  5. Использование расширений конфигурации: Размещаем весь код обмена (общие модули, команды, регистры сведений) в расширениях. Это позволит нам оперативно вносить изменения и исправлять ошибки, не снимая конфигурацию с поддержки и без необходимости монопольного доступа к базе. Это критически важно для поддержания системы в актуальном состоянии и минимизации простоев.

2.2. Работа с JSON в 1С

Платформа 1С, начиная с версии 8.3.6, предоставляет мощные встроенные средства для работы с JSON. Мы можем использовать:

  1. Высокоуровневые функции ПрочитатьJSON() и ЗаписатьJSON(): Эти функции позволяют легко сериализовать и десериализовать примитивные типы, коллекции (Массивы, Структуры, Соответствия) и прикладные типы 1С (ссылки, объекты, наборы записей) через XDTO-сериализацию. Это удобно для простых JSON-документов.
  2. Низкоуровневые объекты ЧтениеJSON и ЗаписьJSON: Они предназначены для потоковой работы с JSON, что оптимально для больших объемов данных, так как не требует формирования всего документа в памяти.

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


// Пример формирования JSON для выгрузки объекта "Контрагент"
Функция СформироватьJSONКонтрагента(КонтрагентСсылка) Экспорт
    
    СтруктураДанных = Новый Соответствие();
    СтруктураДанных.Вставить("Идентификатор", Строка(КонтрагентСсылка.УникальныйИдентификатор()));
    СтруктураДанных.Вставить("Код", КонтрагентСсылка.Код);
    СтруктураДанных.Вставить("Наименование", КонтрагентСсылка.Наименование);
    СтруктураДанных.Вставить("ИНН", КонтрагентСсылка.ИНН);
    СтруктураДанных.Вставить("КПП", КонтрагентСсылка.КПП);
    СтруктураДанных.Вставить("ПолноеНаименование", КонтрагентСсылка.ПолноеНаименование);
    
    МассивАдресов = Новый Массив();
    Для Каждого КонтактнаяИнформация Из КонтрагентСсылка.КонтактнаяИнформация Цикл
        Если КонтактнаяИнформация.Вид.Наименование = "Юридический адрес" Тогда
            Адрес = Новый Соответствие();
            Адрес.Вставить("ТипАдреса", "Юридический");
            Адрес.Вставить("Представление", КонтактнаяИнформация.Представление);
            МассивАдресов.Добавить(Адрес);
        КонецЕсли;
    КонецЦикла;
    СтруктураДанных.Вставить("Адреса", МассивАдресов);

    СтрокаJSON = ЗаписатьJSON(СтруктураДанных, , Истина); // Истина для форматирования
    Возврат СтрокаJSON;
    
КонецФункции

// Пример использования ЗаписьJSON для потоковой записи (для больших объемов)
Функция СформироватьJSONДокументаПотоково(ДокументСсылка) Экспорт
    
    Запись = Новый ЗаписьJSON();
    Запись.УстановитьСтроку();
    Запись.НачатьЗаписьОбъекта(); // {
    
    Запись.ЗаписатьИмяСвойства("Идентификатор");
    Запись.ЗаписатьЗначение(Строка(ДокументСсылка.УникальныйИдентификатор()));
    
    Запись.ЗаписатьИмяСвойства("Номер");
    Запись.ЗаписатьЗначение(ДокументСсылка.Номер);
    
    Запись.ЗаписатьИмяСвойства("Дата");
    Запись.ЗаписатьЗначение(Формат(ДокументСсылка.Дата, "ДФ=yyyy-MM-ddTHH:mm:ss")); // ISO 8601
    
    Запись.ЗаписатьИмяСвойства("Контрагент");
    Запись.НачатьЗаписьОбъекта(); // {
    Запись.ЗаписатьИмяСвойства("Идентификатор");
    Запись.ЗаписатьЗначение(Строка(ДокументСсылка.Контрагент.УникальныйИдентификатор()));
    Запись.ЗаписатьИмяСвойства("Наименование");
    Запись.ЗаписатьЗначение(ДокументСсылка.Контрагент.Наименование);
    Запись.ЗакончитьЗаписьОбъекта(); // }
    
    Запись.ЗаписатьИмяСвойства("СуммаДокумента");
    Запись.ЗаписатьЗначение(ДокументСсылка.СуммаДокумента);
    
    Запись.ЗаписатьИмяСвойства("ТабличнаяЧасть");
    Запись.НачатьЗаписьМассива(); // [
    Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
        Запись.НачатьЗаписьОбъекта(); // {
        Запись.ЗаписатьИмяСвойства("Номенклатура");
        Запись.НачатьЗаписьОбъекта(); // {
        Запись.ЗаписатьИмяСвойства("Идентификатор");
        Запись.ЗаписатьЗначение(Строка(СтрокаТЧ.Номенклатура.УникальныйИдентификатор()));
        Запись.ЗаписатьИмяСвойства("Артикул");
        Запись.ЗаписатьЗначение(СтрокаТЧ.Номенклатура.Артикул);
        Запись.ЗакончитьЗаписьОбъекта(); // }
        Запись.ЗаписатьИмяСвойства("Количество");
        Запись.ЗаписатьЗначение(СтрокаТЧ.Количество);
        Запись.ЗаписатьИмяСвойства("Цена");
        Запись.ЗаписатьЗначение(СтрокаТЧ.Цена);
        Запись.ЗаписатьИмяСвойства("Сумма");
        Запись.ЗаписатьЗначение(СтрокаТЧ.Сумма);
        Запись.ЗакончитьЗаписьОбъекта(); // }
    КонецЦикла;
    Запись.ЗакончитьЗаписьМассива(); // ]
    
    Запись.ЗакончитьЗаписьОбъекта(); // }
    
    Возврат Запись.Закрыть();
КонецФункции

// Пример чтения JSON-строки
Функция ПрочитатьJSONКонтрагента(СтрокаJSON) Экспорт
    ДанныеJSON = ПрочитатьJSON(СтрокаJSON); // ДанныеJSON будет Соответствие
    
    // Получаем значение по ключу, например, Наименование
    Если ДанныеJSON.Свойство("Наименование") Тогда
        Возврат ДанныеJSON.Наименование;
    Иначе
        Возврат Неопределено;
    КонецЕсли;
КонецФункции

Для загрузки данных из JSON-строки, полученной из 1С:Шина, мы будем использовать схожий подход, но в обратном порядке. Сначала преобразуем JSON в структуру данных 1С, а затем будем сопоставлять и создавать/обновлять объекты.

3. Реализуем механизмы сопоставления данных

Один из самых сложных и критичных аспектов при отказе от КД — это реализация механизмов сопоставления объектов. КД делает это "из коробки", а в коде нам придется продумать каждый сценарий.

3.1. Подходы к сопоставлению

  1. Сопоставление по уникальным идентификаторам (GUID): Это наиболее надежный способ. Если объекты в обеих базах могут иметь одинаковые GUID (например, если они изначально создавались в одной системе, а в другую попадают только через обмен), используем УникальныйИдентификатор.
  2. Сопоставление по ключевым реквизитам: Для большинства справочников это может быть комбинация реквизитов, которая однозначно идентифицирует объект. Например:
    • Для справочника Номенклатура: Артикул, Наименование.
    • Для справочника Контрагенты: ИНН, КПП, Наименование.
    • Для пользователей: ИмяПользователя, E-mail.

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

  3. Использование регистра сведений для хранения соответствий: Это универсальный и мощный подход. Создаем специальный регистр сведений (например, СоответствияОбъектовИнформационныхБаз), в котором храним соответствие уникальных идентификаторов объектов разных баз.
    
    // Пример структуры регистра сведений "СоответствияОбъектовИнформационныхБаз"
    // Измерение: ИдентификаторИсточника (Строка 36, GUID)
    // Измерение: ТипОбъектаИсточника (Строка, например, "Справочник.Контрагенты")
    // Ресурс: ИдентификаторПриемника (Строка 36, GUID)
    // Ресурс: ТипОбъектаПриемника (Строка, например, "Справочник.Контрагенты")
    

    Логика работы:

    1. При загрузке объекта из JSON, сначала пытаемся найти его соответствие в регистре по ИдентификаторИсточника.
    2. Если соответствие найдено, получаем ИдентификаторПриемника и по нему находим объект в текущей базе.
    3. Если объект найден, обновляем его данные.
    4. Если соответствие не найдено в регистре, пытаемся найти объект в текущей базе по ключевым реквизитам (ИНН, Наименование и т.д.).
    5. Если объект найден по ключевым реквизитам, записываем его УникальныйИдентификатор и ИдентификаторИсточника в регистр соответствий. Обновляем данные объекта.
    6. Если объект не найден ни по GUID, ни по ключевым реквизитам, создаем новый объект и записываем его УникальныйИдентификатор и ИдентификаторИсточника в регистр соответствий.
  4. Ручное сопоставление: В особо сложных или исключительных случаях, когда автоматическое сопоставление невозможно (например, при расхождении в данных или наличии дублей), может потребоваться механизм ручного сопоставления через форму обработки.

4. Обработка ссылочных данных и коллекций

Работа с ссылочными данными (например, когда в документе указан Контрагент или Номенклатура) требует особого внимания. При сериализации прикладных типов 1С в JSON, ссылки могут быть преобразованы в их УникальныеИдентификаторы.

При загрузке JSON мы должны выполнить "разрешение" этих ссылок:

  1. Извлечь УникальныйИдентификатор ссылочного объекта из JSON.
  2. Использовать один из описанных выше механизмов сопоставления, чтобы найти соответствующий объект в текущей базе.
  3. Подставить найденную ссылку в создаваемый или обновляемый объект.

Для автоматизации этого процесса можно разработать универсальные функции, которые будут принимать УникальныйИдентификатор из JSON и возвращать соответствующую ссылку на объект 1С, используя регистр соответствий или прямой поиск.

Работа с коллекциями данных (табличные части документов, наборы записей регистров) аналогична. В JSON они обычно представляются массивами объектов. При загрузке мы должны перебрать элементы массива, сопоставить или создать их, а затем заполнить соответствующие табличные части или наборы записей.

5. Инструменты и автоматизация

Хотя идея использования OpenCode или LLM для прямой конвертации правил КД в код 1С для JSON-обмена звучит заманчиво, на практике готовых, широко используемых решений для полной автоматизации такого процесса пока нет. Однако мы можем использовать эти подходы для:

  1. Генерации черновиков кода: LLM могут помочь создать базовые структуры для формирования JSON или разбора входящих данных на основе описания формата или примера XML из КД.
  2. Автоматизации рутинных задач: Например, генерация кода для заполнения простейших реквизитов, маппинга перечислений.

Встроенные средства 1С для JSON, такие как ЧтениеJSON и ЗаписьJSON, являются нашими основными инструментами. Мы уже рассмотрели их функциональность. Подчеркнем, что для сложных или объемных JSON-структур потоковая запись/чтение через ЗаписьJSON/ЧтениеJSON значительно эффективнее, чем полная загрузка/выгрузка в память через ПрочитатьJSON()/ЗаписатьJSON().

6. Отладка и управление версиями

Переход на кодовый обмен упрощает отладку. Вся логика обмена находится непосредственно в конфигурации или расширении, что позволяет использовать стандартные средства отладчика 1С. Мы можем ставить точки останова, пошагово проходить код, инспектировать значения переменных – всё это гораздо удобнее, чем отладка обработчиков в КД, которая часто требовала выгрузки кода в файл и его специфичного выполнения.

Управление версиями правил обмена становится частью общего процесса управления версиями исходного кода. Мы будем использовать стандартные системы контроля версий (например, Git с плагинами для 1С) для отслеживания изменений в общих модулях, формах и регистрах, связанных с обменом. Это обеспечивает прозрачность изменений, возможность отката к предыдущим версиям и удобную командную разработку.

7. Альтернативные подходы и их особенности

Помимо полного переписывания на кодовый JSON-обмен, стоит рассмотреть и другие варианты, которые могут быть более подходящими в зависимости от конкретных условий и бюджета:

  1. Конвертация Данных 3.1: Если цель - уйти от проблем КД 2.1, но сохранить визуальный механизм настройки, КД 3.1 может быть хорошим вариантом. Она значительно отличается от 2.1, предоставляет больше возможностей по генерации кода и гибкости.
  2. Использование обмена ED с обработчиками в модулях менеджера: Для понимания структуры и логики обмена в коде, мы можем взять за образец типовые механизмы обмена, реализованные 1С в библиотеках стандартных подсистем (БСП) – например, обмен в формате EnterpriseData (ED). Там часто используются обработчики в модулях менеджера объектов, что является хорошим примером для нашего кодового обмена.
  3. Оценка бюджета и амбиций: Важно соотнести амбиции по полному переходу с имеющимся бюджетом и ресурсами. Полная переработка обмена – это большой проект. Если обмен разовый, то можно обойтись более простыми решениями, возможно, даже с ручным сопоставлением. Если же обмен постоянный и высоконагруженный, то инвестиции в качественный кодовый обмен оправданы.

Заключение

Переход от КД 2.1 к кодовому JSON-обмену через 1С:Шина предоставляет значительную гибкость, полный контроль над процессом и потенциальное улучшение производительности. Однако он требует тщательного проектирования, глубокой проработки каждого аспекта (от сопоставления данных до обработки ошибок) и готовности к инвестициям в разработку и поддержку. Использование расширений, встроенных средств 1С для работы с JSON, продуманные механизмы сопоставления и системный подход к отладке и управлению версиями — это ключевые факторы успеха в этом непростом, но перспективном проекте.

← На главную