При работе в крупных организациях часто возникает ситуация, когда одна база 1С:Зарплата и Управление Персоналом 3.1 (ЗУП) должна передавать данные сразу в несколько учетных систем — например, в 1С:Бухгалтерия предприятия 3.0 (БП) и в 1С:ERP Управление предприятием (ERP). Проблема заключается в том, что оба этих обмена обычно используют один и тот же план обмена — Синхронизация данных через универсальный формат (Enterprise Data).
Так как правила регистрации (ПР) загружаются в рамках плана обмена, они становятся общими для всех созданных настроек синхронизации. Если мы меняем правила, чтобы запретить регистрацию определенного документа для ERP, эти изменения автоматически применяются и для БП, что часто недопустимо. В этой статье мы разберем, как программно разделить логику регистрации объектов в зависимости от того, для какого узла (приемника) она выполняется.
Прежде чем переходить к коду, давайте разберем, как система понимает, куда отправлять данные. В плане обмена создаются Узлы. Каждый узел соответствует конкретной базе-приемнику. Когда в ЗУП записывается документ (например, Премия), механизм регистрации данных перебирает все активные узлы текущего плана обмена и проверяет правила регистрации для каждого из них.
Следовательно, наша задача — в момент регистрации определить, какой именно узел обрабатывается в данный момент, и, если это узел ERP, а документ нам там не нужен, отменить регистрацию.
Это самый «чистый» способ, так как он не требует внесения изменений в конфигурацию или создания расширений. Мы будем использовать возможность написания кода в обработчиках событий правил регистрации. Для этого нам понадобится конфигурация Конвертация данных 2.0 или 3.0, в которой редактируются ПР для универсального формата.
Разберем алгоритм действий по шагам:
ОтражениеЗарплатыВБухучете).В этом обработчике нам доступен объект Узел. Это и есть ключ к решению. Мы можем проанализировать его свойства (код, наименование или дополнительные реквизиты). Рассмотрим пример кода, который нужно разместить в обработчике:
// Проверяем, какой узел сейчас обрабатывается.
// Можно проверять по коду узла или по вхождению строки в наименование.
НаименованиеУзла = СокрЛП(Узел.Наименование);
Если Найти(НаименованиеУзла, "ERP") > 0 Тогда
// Если это узел ERP, проверяем тип объекта
ТипОбъекта = ТипЗнч(Объект);
Если ТипОбъекта = Тип("ДокументОбъект.Премия")
Или ТипОбъекта = Тип("ДокументОбъект.ДоговорАвторскогоЗаказа") Тогда
// Устанавливаем Отказ в Истина, чтобы объект не зарегистрировался для этого узла
Отказ = Истина;
КонецЕсли;
КонецЕсли;
После внесения изменений необходимо сохранить правила, выгрузить их в файл XML и загрузить обратно в ЗУП через форму настройки синхронизации данных. Теперь при записи документа Премия система будет проверять: если узел содержит в названии "ERP", регистрация будет проигнорирована, а для узла БП она пройдет штатно.
Если по каким-то причинам вы не хотите менять правила регистрации (например, их слишком часто обновляет фирма 1С, и вы не хотите каждый раз переносить туда свой код), можно воспользоваться механизмом расширений. В ЗУП за регистрацию отвечает общий модуль ОбменДаннымиСобытия.
Проанализируем процедуру ВыполнитьПравилаРегистрацииОбъектовДляПланаОбменаПопыткаИсключение. Именно здесь система применяет правила к объекту. Мы можем перехватить этот процесс.
Рассмотрим пример кода в расширении (метод После или Вместо):
&После("ВыполнитьПравилаРегистрацииОбъектовДляПланаОбменаПопыткаИсключение")
Процедура Ист_ВыполнитьПравилаРегистрацииОбъектовПосле(МассивУзловРезультат, Объект, ИмяПланаОбмена, ДополнительныеПараметры)
// Нас интересует только план обмена через универсальный формат
Если ИмяПланаОбмена <> "СинхронизацияДанныхЧерезУниверсальныйФормат" Тогда
Возврат;
КонецЕсли;
// Удаляем из массива узлов те, куда объект не должен попасть
Для Каждого ТекущийУзел Из МассивУзловРезультат Цикл
Если Найти(ТекущийУзел.Наименование, "ERP") > 0
И ТипЗнч(Объект) = Тип("ДокументОбъект.ОтражениеЗарплатыВБухучете") Тогда
// Удаляем узел из списка получателей для данного конкретного объекта
МассивУзловРезультат.Удалить(МассивУзловРезультат.Найти(ТекущийУзел));
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важный момент: использование расширения дает больше контроля, но требует внимательности при обновлениях конфигурации, так как структура общих модулей может меняться.
Завязываться на наименование или код узла — не всегда надежно (пользователь может переименовать узел). Более профессиональный подход — использовать дополнительные сведения или реквизиты для узла плана обмена.
Разберем этот вариант:
ТипИнформационнойСистемы с типом "Значение дополнительного реквизита" (варианты: БП, ERP).Теперь в правилах регистрации (см. Решение 1) мы будем обращаться не к имени, а к этому свойству:
// Функция получения доп. реквизита (упрощенно)
ЗначениеСвойства = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Узел, "ДополнительныйРеквизит_ТипИнформационнойСистемы");
Если ЗначениеСвойства = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("ERP") Тогда
// Логика отказа
Если ТипЗнч(Объект) = Тип("ДокументОбъект.КадровыйПеревод") Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
Необходимо понимать разницу между Правилами регистрации (ПР) и Правилами обработки данных (ПОД).
Если мы отсекаем объект в ПР, он вообще не попадает в таблицу регистрации (не стоит в «очереди» на выгрузку). Это экономит ресурсы сервера и объем базы данных.
Если же объект зарегистрирован, мы все еще можем отсечь его на этапе выгрузки в правилах конвертации (ПОД). Однако в этом случае объект будет виден в мониторе регистрации (в составе отправляемых данных), но при самой синхронизации файл выгрузки для него формироваться не будет. Для чистоты системы лучше использовать именно фильтрацию в правилах регистрации.
Мы выяснили, что разделение потоков данных в ЗУП 3.1 для БП и ERP реализуемо через анализ текущего узла обмена. Самым рекомендуемым способом является модификация обработчика «Перед обработкой» в правилах регистрации. Это позволяет сохранить типовую конфигурацию и обеспечить гибкую логику обмена в зависимости от системы-приемника.