Как в РИБ 1С настроить регистрацию документа «Установка цен» только по выбранным типам цен?

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

При работе в распределенных информационных базах (РИБ) часто возникает задача разделения данных между узлами. Типичный пример — когда в центральном офисе создается один общий документ УстановкаЦенНоменклатуры, содержащий розничные цены для всех магазинов сети. Однако в каждый конкретный магазин (периферийный узел) должны попадать только те цены, которые относятся именно к нему. По умолчанию механизм РИБ регистрирует документ целиком: если в документе 100 строк с разными типами цен, все они уедут в подчиненный узел, что может быть нежелательным как с точки зрения безопасности данных, так и с точки зрения производительности.

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

Проблема регистрации ссылочных объектов

Прежде всего, важно понимать фундаментальное ограничение платформы: объект регистрируется целиком. Когда мы добавляем документ в состав плана обмена, система отслеживает изменение ссылки на этот документ. Мы не можем «зарегистрировать половину документа» в таблице регистрации изменений. Если документ изменен, в таблицу Registration попадает ссылка на него, и при обмене платформа попытается выгрузить все его реквизиты и все строки табличных частей.

Однако мы можем вмешаться в процесс выгрузки данных. Разберем, как это сделать правильно.

Решение 1: Использование обработчика ПриОтправкеДанныхПодчиненному

Это наиболее гибкий и рекомендуемый метод для решения задачи фильтрации состава документа в РИБ. Этот обработчик располагается в модуле Плана обмена. Он вызывается непосредственно перед тем, как объект будет сериализован в XML-файл сообщения обмена.

Рассмотрим по шагам алгоритм реализации этого метода:

  1. Определим критерий фильтрации. Лучше всего добавить в сам план обмена дополнительный реквизит (например, ТипЦенДляЭтогоУзла), чтобы не «зашивать» названия цен в программный код.
  2. В обработчике проверим тип отправляемого объекта.
  3. Если это ДокументОбъект.УстановкаЦенНоменклатуры, мы создадим его копию в памяти, удалим ненужные строки и передадим измененную копию в поток обмена.

Проанализируем пример кода, который необходимо разместить в модуле плана обмена:


Процедура ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента)

    // Проверяем, что отправляемый элемент — это наш документ
    Если ТипЗнч(ЭлементДанных) = Тип("ДокументОбъект.УстановкаЦенНоменклатуры") Тогда
        
        // Получаем настройку типа цен для текущего узла (куда отправляем данные)
        // Предположим, у нас в ПланеОбмена есть реквизит ТипЦенФильтр
        НужныйТипЦен = ЭтотОбъект.ТипЦенФильтр;
        
        Если ЗначениеЗаполнено(НужныйТипЦен) Тогда
            
            // Создаем копию объекта, чтобы не менять данные в основной базе
            КопияДокумента = ЭлементДанных.Скопировать();
            
            // Проходим по табличной части и удаляем строки с "чужими" типами цен
            КоличествоСтрок = КопияДокумента.ТЧ_Цены.Количество();
            Для Индекс = 1 По КоличествоСтрок Цикл
                ТекущаяСтрока = КопияДокумента.ТЧ_Цены[КоличествоСтрок - Индекс];
                
                Если ТекущаяСтрока.ТипЦен <> НужныйТипЦен Тогда
                    КопияДокумента.ТЧ_Цены.Удалить(ТекущаяСтрока);
                КонецЕсли;
            КонецЦикла;
            
            // Проверяем, остались ли вообще строки в документе
            Если КопияДокумента.ТЧ_Цены.Количество() = 0 Тогда
                // Если строк не осталось, документ вообще не нужно отправлять
                ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать;
            Иначе
                // Подменяем оригинальный объект на нашу "урезанную" копию
                ЭлементДанных = КопияДокумента;
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЕсли;

КонецПроцедуры

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

Решение 2: Фильтрация наборов записей регистра сведений

Документ «Установка цен» сам по себе является лишь регистратором. Основные данные хранятся в регистре сведений (например, ЦеныНоменклатуры). Если в плане обмена для регистра сведений установлено Авторегистрация: Запретить, или если вы хотите фильтровать именно движения документа, нужно учитывать особенности наборов записей.

В отличие от документов, наборы записей регистра сведений в РИБ могут выгружаться частично, если они не подчинены регистратору. Но в случае с ценами регистратор почти всегда есть. Рассмотрим ситуацию, когда мы хотим отфильтровать именно записи регистра.

Если мы используем тот же метод ПриОтправкеДанныхПодчиненному для набора записей, нам нужно проанализировать структуру РегистрСведенийНаборЗаписей. Мы можем программно перебрать записи в наборе и удалить те, которые не соответствуют ТипуЦен узла-получателя. Это гарантирует, что в подчиненной базе в регистре окажутся только разрешенные записи.

Решение 3: Правила регистрации данных (ПРД) в БСП

Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), вы можете использовать механизм «Правил регистрации данных». Это позволяет настраивать условия регистрации без внесения изменений в конфигуратор.

Разберем, как это работает:

  1. В пользовательском режиме открываются настройки синхронизации данных.
  2. Для конкретного объекта (Документ «Установка цен») настраивается фильтр (например, ТипЦен = &НужныйТип).
  3. Система при записи документа будет проверять это условие.

Однако здесь есть ловушка: ПРД работают на уровне регистрации ссылки. Если в документе есть хотя бы одна строка с «правильным» типом цен, документ зарегистрируется полностью. ПРД не умеют «обрезать» табличные части документа при регистрации. Поэтому для задачи «частичной» передачи содержимого одного документа метод ПриОтправкеДанныхПодчиненному остается единственным рабочим вариантом.

Рекомендации по архитектуре обмена

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

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

← На главную