Планы обмена в 1С – это мощный, но порой недооцененный инструмент для организации синхронизации данных. Для чего они предназначены? И в каких случаях возникает необходимость создавать собственный, уникальный механизм, а не использовать или адаптировать типовые решения? Эта статья адресована в первую очередь разработчикам, но будет полезна и всем, кто стремится глубже понять принципы обмена данными в экосистеме 1С.
Ключевая задача плана обмена — регистрировать изменения выбранных объектов конфигурации. Как только изменение зафиксировано, система позволяет получить список этих измененных объектов, чтобы затем выгрузить их в нужный формат или обработать специфическим образом. Важной особенностью является возможность пометить обработанные объекты как отправленные. Это не само снятие с регистрации, а скорее промежуточный статус, полезный для контроля доставки. Такой механизм незаменим, когда требуется гарантированное получение данных информационной системой-приемником. После того как система-приемник успешно обработает пакет, она может отправить подтверждение, на основании которого в нашем плане обмена можно будет окончательно снять с регистрации ранее отправленные объекты.
Для управления этим процессом и обеспечения его корректности, планы обмена предоставляют стандартные реквизиты, такие как «Номер принятого» и «Номер отправленного». Они помогают гарантировать, что каждая сторона получает только актуальную, ранее не обработанную информацию.
Несмотря на кажущуюся сложность, механизм планов обмена довольно логичен. В этой статье мы подробно, с практическими примерами, разберем процесс их создания и использования, чтобы вы могли уверенно применять этот инструмент в своих разработках.
Что такое План Обмена?
План обмена — это специальный объект конфигурации, который выполняет следующие основные функции:
Определение состава данных: Указывает, какие именно объекты метаданных (справочники, документы, регистры и т.д.) будут участвовать в процессе обмена.
Учет изменений: Регистрирует изменения этих данных для каждого участника обмена (узла).
Хранение информации об узлах: Содержит сведения об информационных базах, с которыми настроен обмен.
План обмена можно сравнить со справочником, элементами которого являются узлы информационных баз.
Шаг 1: Создание Плана Обмена в Конфигураторе
1. Откройте конфигуратор вашей информационной базы 1С.
2. В дереве объектов конфигурации найдите ветку “Общие”, а в ней — “Планы обмена”.
3. Правой кнопкой мыши кликните по ветке “Планы обмена” и выберите “Добавить”.
-
-
Имя: ОбменСРозничнымиМагазинами
-
Синоним: Обмен с розничными магазинами
-
5. Вкладка “Состав”: Настройка состава данных
-
Здесь вы выбираете объекты метаданных, которые будут включены в обмен.
-
Для каждого объекта можно настроить Авторегистрацию:
-
Разрешить: Изменения объектов будут регистрироваться автоматически при их записи или проведении. Это поведение по умолчанию.
-
Запретить: Автоматическая регистрация производиться не будет. Изменения потребуется регистрировать программно. Это дает больше контроля над тем, какие именно изменения отправлять.
-
Пример:
Допустим, нам нужно обмениваться информацией о товарах и продажах. Добавляем в состав справочник “Номенклатура” и документ “ЧекККМ”.
6. Вкладка “Прочее”: Настройка “ЭтотУзел”
-
-
СсылкаЭтотУзел: Это один из важнейших реквизитов плана обмена.[2] Он хранит ссылку на узел, соответствующий текущей информационной базе в данном плане обмена. Система использует эту ссылку для идентификации “своего” узла при обмене.
-
Для создания этого реквизита, нажмите кнопку “…” рядом с полем “СсылкаЭтотУзел” и система предложит создать новый реквизит (обычно с типом ПланОбменаСсылка.<ИмяВашегоПланаОбмена>). Часто имя для этого реквизита оставляют ЭтотУзел.
-
7. Вкладка “Прочее”: Другие важные настройки
-
-
Распределенная информационная база (РИБ): Если план обмена создается для стандартного механизма РИБ, этот флаг необходимо установить.
-
Код узла, Наименование узла: Здесь можно задать длину и тип для стандартных реквизитов узла плана обмена.
-
8. После внесения всех настроек сохраните конфигурацию (обычно клавиша F7) и затем обновите конфигурацию базы данных (обычно F5).
Шаг 2: Программная работа с планами обмена
После создания плана обмена в конфигураторе, основная работа по его использованию, включая создание узлов и регистрацию изменений, выполняется программно средствами встроенного языка 1С.
2.1. Создание и установка узла "ЭтотУзел"
Каждая информационная база, участвующая в обмене, должна иметь запись о себе в списке узлов плана обмена. Для текущей (“этой”) базы данных такая запись идентифицируется через специальный реквизит ЭтотУзел
// Укажем имя нашего плана обмена ИмяПланаОбмена = "ОбменСРозничнымиМагазинами"; // Пытаемся получить ссылку на текущий узел ТекущийУзел = ПланыОбмена[ИмяПланаОбмена].ЭтотУзел(); Если ТекущийУзел = Неопределено ИЛИ ТекущийУзел.Пустая() Тогда // Если узел для текущей ИБ еще не определен, создадим его НовыйУзелДляТекущейБазы = ПланыОбмена[ИмяПланаОбмена].СоздатьУзел(); НовыйУзелДляТекущейБазы.Код = "ЦБ01"; // Задаем уникальный код для этой базы в рамках данного обмена НовыйУзелДляТекущейБазы.Наименование = "Центральная база"; Попытка НовыйУзелДляТекущейБазы.Записать(); // Устанавливаем созданный узел как "ЭтотУзел" для текущей ИБ ПланыОбмена[ИмяПланаОбмена].УстановитьЭтотУзел(НовыйУзелДляТекущейБазы.Ссылка); Сообщить("Успешно создан и установлен 'ЭтотУзел' для плана обмена '" + ИмяПланаОбмена + "'."); ТекущийУзел = НовыйУзелДляТекущейБазы.Ссылка; Исключение Сообщить("Ошибка при создании 'ЭтотУзел': " + ОписаниеОшибки(), СтатусСообщения.Важное); КонецПопытки; Иначе Сообщить("Для плана обмена '" + ИмяПланаОбмена + "' 'ЭтотУзел' уже был определен: " + ТекущийУзел.Наименование); КонецЕсли;
Важно: Код узла должен быть уникальным среди всех баз, которые участвуют в обмене по этому плану.
2.2. Создание узлов для других информационных баз (корреспондентов)
Аналогичным образом создаются узлы для других баз данных, с которыми планируется обмен.
// Имя нашего плана обмена ИмяПланаОбмена = "ОбменСРозничнымиМагазинами"; КодУзлаМагазина = "МАГ007"; // Предполагаемый код узла для магазина // Попытка найти узел по коду УзелМагазина = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзлаМагазина); Если УзелМагазина = Неопределено ИЛИ УзелМагазина.Пустая() Тогда // Если узел не найден, создаем новый НовыйУзелМагазина = ПланыОбмена[ИмяПланаОбмена].СоздатьУзел(); НовыйУзелМагазина.Код = КодУзлаМагазина; НовыйУзелМагазина.Наименование = "Магазин №7 'Продукты'"; Попытка НовыйУзелМагазина.Записать(); УзелМагазина = НовыйУзелМагазина.Ссылка; Сообщить("Успешно создан узел для обмена: " + УзелМагазина.Наименование); Исключение Сообщить("Ошибка при создании узла '" + КодУзлаМагазина + "': " + ОписаниеОшибки(), СтатусСообщения.Важное); КонецПопытки; Иначе Сообщить("Узел '" + УзелМагазина.Наименование + "' для обмена уже существует в системе."); КонецЕсли;
2.3. Регистрация изменений объектов
Когда объект, включенный в состав плана обмена, изменяется (создается новый, изменяется существующий, удаляется), система должна зафиксировать (зарегистрировать) этот факт. Регистрация происходит для конкретных узлов-получателей.
Автоматическая регистрация:
Если для типа объекта в составе плана обмена свойство “Авторегистрация” установлено в “Разрешить”, то при записи измененного объекта или при проведении документа он будет автоматически зарегистрирован для всех узлов обмена, кроме ЭтотУзел.
Программная регистрация:
Используется, если авторегистрация отключена или требуется более тонкое управление процессом регистрации.
// Пример: регистрируем изменение для конкретного элемента справочника "Номенклатура" // В реальной ситуации ссылка будет указывать на реально измененный или новый объект СсылкаНаИзмененныйТовар = Справочники.Номенклатура.НайтиПоКоду("ТОВ00123"); // Условный поиск Если НЕ ЗначениеЗаполнено(СсылкаНаИзмененныйТовар) Тогда Сообщить("Товар с кодом ТОВ00123 не найден для примера регистрации!"); Возврат; КонецЕсли; // Получим узел, для которого необходимо зарегистрировать изменение ИмяПланаОбмена = "ОбменСРозничнымиМагазинами"; КодУзлаМагазина = "МАГ007"; УзелПолучатель = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзлаМагазина); Если УзелПолучатель = Неопределено ИЛИ УзелПолучатель.Пустая() Тогда Сообщить("Узел-получатель с кодом " + КодУзлаМагазина + " не найден!"); Возврат; КонецЕсли; // Способ 1: Регистрация через свойство "ОбменДанными" объекта (если объект уже получен) // Перед записью объекта можно указать, для каких узлов регистрировать изменения: // ОбъектНоменклатуры = СсылкаНаИзмененныйТовар.ПолучитьОбъект(); // ОбъектНоменклатуры.ОбменДанными.Получатели.Добавить(УзелПолучатель); // Добавляем узел в список получателей // ОбъектНоменклатуры.Записать(); // При записи изменения зарегистрируются для узлов из списка ОбменДанными.Получатели // Способ 2: Регистрация через менеджер планов обмена (если есть только ссылка на объект) ПланыОбмена.ЗарегистрироватьИзменения(УзелПолучатель, СсылкаНаИзмененныйТовар); Сообщить("Изменения для объекта '" + СсылкаНаИзмененныйТовар + "' успешно зарегистрированы для узла '" + УзелПолучатель.Наименование + "'."); // Для проверки можно использовать метод "Зарегистрирован" Если ПланыОбмена.Зарегистрирован(УзелПолучатель, СсылкаНаИзмененныйТовар) Тогда Сообщить("Проверка: Объект действительно зарегистрирован для данного узла."); Иначе Сообщить("Проверка: Объект НЕ зарегистрирован для данного узла."); КонецЕсли; // Для отмены ранее выполненной регистрации изменений: // ПланыОбмена.ОтменитьРегистрациюИзменений(УзелПолучатель, СсылкаНаИзмененныйТовар); // Сообщить("Регистрация изменений для объекта '" + СсылкаНаИзмененныйТовар + "' была отменена для узла '" + УзелПолучатель.Наименование + "'.");
Регистрация удаления объекта:
Удаление объектов, входящих в план обмена, также должно быть зарегистрировано.
// Предположим, СсылкаНаУдаляемыйОбъект - это ссылка на объект, который был помечен на удаление // или удален непосредственно (если это разрешено). // ... (код для получения УзелПолучатель и СсылкаНаУдаляемыйОбъект) ... Если ЗначениеЗаполнено(УзелПолучатель) И ЗначениеЗаполнено(СсылкаНаУдаляемыйОбъект) Тогда // Для регистрации удаления используется специальный метод ПланыОбмена.ЗарегистрироватьУдаление(УзелПолучатель, СсылкаНаУдаляемыйОбъект); Сообщить("Удаление объекта '" + СсылкаНаУдаляемыйОбъект + "' зарегистрировано для узла '" + УзелПолучатель.Наименование + "'."); КонецЕсли;
Часто программную регистрацию удаления размещают в обработчике события ПередУдалением соответствующего объекта метаданных, если он включен в план обмена и авторегистрация удаления не используется или требуется дополнительный контроль.
Шаг 3: Выполнение обмена (Обзорно)
После того как изменения зафиксированы (зарегистрированы), можно приступать непосредственно к процессу обмена данными. Он обычно включает следующие этапы:
Выборка зарегистрированных изменений для определенного узла.
Формирование сообщения обмена (часто это XML-файл, но могут быть и другие форматы).
Передача сообщения получателю (способы: файловый обмен, веб-сервисы, FTP, очереди сообщений и др.).
Прием сообщения на стороне узла-получателя.
Загрузка данных из полученного сообщения в информационную базу получателя.
Пример кода для выгрузки (выборки) зарегистрированных изменений (без формирования XML):
// ... (код для получения УзелПолучатель, например, УзелМагазина из предыдущих примеров) ... ИмяПланаОбмена = "ОбменСРозничнымиМагазинами"; УзелПолучатель = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду("МАГ007"); Если УзелПолучатель = Неопределено ИЛИ УзелПолучатель.Пустая() Тогда Сообщить("Узел-получатель МАГ007 не найден для выгрузки изменений!"); Возврат; КонецЕсли; // Номер сообщения для этого узла. При первой выгрузке для нового узла обычно 1. // Далее этот номер увеличивается после каждой успешной отправки и подтверждения приема. НомерОчередногоСообщения = УзелПолучатель.НомерОтправленного + 1; // Выбираем зарегистрированные изменения для указанного узла и номера сообщения ВыборкаЗарегистрированныхИзменений = ПланыОбмена.ВыбратьИзменения(УзелПолучатель, НомерОчередногоСообщения); Сообщить("Начинается выгрузка изменений для узла: " + УзелПолучатель.Наименование + ", номер сообщения: " + ВыборкаЗарегистрированныхИзменений.НомерСообщения); Пока ВыборкаЗарегистрированныхИзменений.Следующий() Цикл // Получаем сам объект, который был изменен ОбъектДанных = ВыборкаЗарегистрированныхИзменений.Получить(); МетаданныеОбъекта = ОбъектДанных.Метаданные(); // На этом этапе должна происходить сериализация объекта в нужный формат (например, XML) Сообщить("К выгрузке готовится: " + МетаданныеОбъекта.ПолноеИмя() + " - " + ОбъектДанных); // В реальной системе здесь будет код для формирования XML-элемента или другой структуры данных КонецЦикла; Сообщить("Процесс выборки изменений для выгрузки завершен."); // Важно: После того как сообщение успешно сформировано, передано, и от узла-получателя пришло подтверждение // о его успешном приеме и загрузке, необходимо "сдвинуть" номер отправленного сообщения для этого узла. // Это делается, чтобы эти же данные не были выбраны при следующей выгрузке. // Например: ПланыОбмена.УстановитьНомерОтправленного(УзелПолучатель, НомерОчередногоСообщения); // Обычно это делается после получения квитанции от приемника.
Для реализации полноценных обменов часто применяются:
Правила обмена, создаваемые в конфигурации “Конвертация данных”: Они позволяют описывать сложные алгоритмы трансформации данных при передаче между базами с различными структурами.
Стандартные форматы обмена, такие как EnterpriseData.
Библиотека стандартных подсистем (БСП): В ней содержатся готовые инструменты и механизмы, значительно упрощающие разработку и настройку обменов.
Ключевые моменты и рекомендации:
Уникальность кодов узлов: Каждый узел в рамках одного плана обмена должен иметь уникальный код.
Нумерация сообщений: Система отслеживает номера отправленных и принятых сообщений для каждого узла. Это критически важно для поддержания последовательности и полноты обмена, а также для предотвращения повторной загрузки данных.
Фильтры на уровне плана обмена: На вкладке “Прочее” в свойствах плана обмена можно задать фильтры, которые позволяют ограничивать состав выгружаемых данных (например, по организации, складу, если у объектов есть соответствующие реквизиты).
Вопросы производительности: При очень большом объеме изменяемых данных автоматическая регистрация может создавать дополнительную нагрузку на систему. В таких сценариях может быть целесообразно перейти на программную регистрацию и оптимизировать моменты её вызова.
Использование транзакций: Операции, изменяющие данные (например, запись объекта), и операции регистрации этих изменений для обмена желательно выполнять в рамках одной транзакции. Это обеспечивает целостность данных: либо и объект записывается, и изменение регистрируется, либо (в случае ошибки) не происходит ни того, ни другого.
Понимание принципов создания и регистрации планов обмена является фундаментальным для разработки распределенных информационных систем на платформе “1С:Предприятие”, позволяя эффективно и гибко управлять потоками данных.