При работе с распределенными информационными базами (РИБ) программисты часто сталкиваются с необходимостью ограничить передачу данных на периферийные узлы. Если для документов и справочников настроить отборы по организации или складу относительно просто, то фильтрация записей независимых регистров сведений (например, АкцизныеМарки, ЦеныНоменклатуры, Штрихкоды) вызывает множество вопросов.
В этой статье мы подробно разберем, как правильно настроить отбор в обмене РИБ для независимого регистра сведений, используя конфигурацию «Конвертация данных 2.1» (КД), как обойти подводные камни при работе с наборами записей и правильно управлять авторегистрацией в плане обмена. Регулярное выполнение настроенных задач по расписанию обеспечивает программа для автоматического обмена данными между базами 1С.
---
Первая и самая частая ошибка начинающих разработчиков — попытка настроить правила в КД на основе неактуальных или некорректно загруженных метаданных. Если в вашей базе КД у регистра сведений не отображаются измерения, ресурсы или реквизиты, это означает, что метаданные конфигурации-источника были загружены с ошибками или перепутаны базы.
Выполним последовательную подготовку конфигурации:
АкцизныеМарки) включен в состав нужного плана обмена. Если его там нет, добавим его на вкладке «Состав» плана обмена.MD83Exp.epf для платформы 1С 8.3)..xml. При выгрузке обязательно проверим, чтобы флаг «Выгружать регистры сведений» был установлен.После успешной загрузки все измерения, ресурсы и реквизиты регистра станут доступны в КД для настройки правил регистрации объектов (ПРО).
---
Даже если написать идеальный код фильтрации в правилах регистрации, он не будет выполняться, если в самом плане обмена допущена классическая ошибка с настройкой авторегистрации.
Проанализируем, как платформа 1С обрабатывает изменения объектов:
Если для элемента состава плана обмена свойство «Авторегистрация» установлено в значение «Разрешить», то при любой записи объекта в базу платформа автоматически регистрирует изменения для всех узлов этого плана обмена. При этом механизмы Библиотеки стандартных подсистем (БСП) и ваши кастомные правила регистрации объектов (ПРО) просто игнорируются.
Чтобы отбор по правилам регистрации заработал, выполним следующие действия в конфигураторе:
АкцизныеМарки).Теперь регистрацией изменений будет полностью управлять программный код БСП на основе загруженных правил регистрации.
---
Перейдем к самой сложной технической части — написанию кода отбора. Главная «подводная ложь» независимых регистров сведений заключается в том, как платформа представляет их данные при записи.
Для справочников или документов параметр Объект в обработчиках ПРО представляет собой конкретную ссылку или объект (ДокументОбъект, СправочникОбъект). Но для независимого регистра сведений параметр Объект — это всегда РегистрСведенийНаборЗаписей (коллекция строк, объединенных общим отбором).
Попытка обратиться напрямую к реквизитам, например, Объект.Статус или Объект.Справка2, вызовет критическую ошибку: «Поле объекта не обнаружено». Нам необходимо обходить набор записей в цикле.
Рассмотрим пример реализации отбора в обработчике «ПередОбработкой» в КД. Нам нужно передавать на периферийный узел только те записи, у которых ресурс Статус равен значению ВНаличии (из перечисления СтатусыАкцизныхМарок) и при этом реквизит Справка2 не заполнен.
Разберем по шагам код обработчика:
// По умолчанию отменяем регистрацию всего набора записей
Отказ = Истина;
// Проверяем, есть ли вообще записи в наборе.
// Если наборе пустой (происходит очистка/удаление записей),
// то нам нужно разрешить регистрацию, чтобы эти данные удалились и на периферии.
Если Объект.Количество() = 0 Тогда
Отказ = Ложь;
Иначе
// Если записи есть, обходим их в цикле
Для Каждого Запись Из Объект Цикл
// Проверяем условия фильтрации для каждой строки
Если Запись.Статус = Перечисления.СтатусыАкцизныхМарок.ВНаличии
И НЕ ЗначениеЗаполнено(Запись.Справка2) Тогда
// Если хотя бы одна запись в записываемом наборе соответствует условиям,
// мы разрешаем регистрацию всего набора записей на узле.
Отказ = Ложь;
Прервать; // Дальнейший перебор строк не имеет смысла, прерываем цикл
КонецЕсли;
КонецЦикла;
КонецЕсли;
Важное примечание по поводу очистки: Обратите внимание на проверку Объект.Количество() = 0. Если пользователь или бизнес-логика программы очищает движения по регистру (записывает пустой набор), то количество записей будет равно нулю. Если мы безусловно вернем Отказ = Истина в этом случае, то на подчиненном узле РИБ старые записи никогда не удалятся, что приведет к рассинхронизации данных между базами.
---
В процессе создания отборов часто возникает вопрос: как правильно проверять реквизиты на пустоту? Пользователи часто путают понятия Неопределено и Пустая ссылка.
Проанализируем разницу:
ДокументСсылка.Справка2ЕГАИС.ПустаяСсылка()). У такой ссылки есть тип, но ее уникальный идентификатор (GUID) состоит из одних нулей.Для того чтобы не писать сложные конструкции с проверкой типов и вызовом метода Пустая() для каждого возможного справочника или документа, в платформе 1С существует универсальная функция ЗначениеЗаполнено(). Она корректно определяет пустоту для любых типов данных (включая ссылки, числа, строки, даты, Неопределено и Null).
Рекомендуется всегда использовать конструкцию НЕ ЗначениеЗаполнено(Запись.ИмяРеквизита) для проверки того, что поле осталось пустым.
---
Если настройка правил регистрации в ПРО кажется вам избыточной или ее сложно отлаживать в рабочей базе, существует альтернативный вариант фильтрации данных непосредственно в процессе выгрузки (на уровне правил конвертации).
Для реализации этого метода:
// В ПКО "ПередВыгрузкой" параметр "Объект" также может выступать как выборка или набор
// Если мы выгружаем конкретную запись (строку):
Если Источник.Статус <> Перечисления.СтатусыАкцизныхМарок.ВНаличии
ИЛИ ЗначениеЗаполнено(Источник.Справка2) Тогда
Отказ = Истина; // Отменяем выгрузку этой конкретной записи
КонецЕсли;
Сравнение подходов (ПРО против ПКО/ПВД):
ВыборкаИзменений) на узлах будет постоянно замусориваться записями, которые фактически не должны отправляться. При каждом сеансе обмена система будет тратить ресурсы процессора и диска на чтение этих записей, анализ условий и последующий отказ от выгрузки. При больших объемах данных в регистре АкцизныеМарки это может привести к критическому замедлению обменов.Поэтому для высоконагруженных систем и больших регистров сведений всегда рекомендуется использовать первый вариант — жесткую фильтрацию на этапе регистрации изменений через Правила регистрации объектов (ПРО).