При настройке синхронизации данных между конфигурациями 1С часто возникает необходимость ограничить выгрузку определенных объектов. Для этого используются правила регистрации объектов (ПРО). Однако начинающие разработчики часто сталкиваются с непонятными ошибками при попытке программного описания условий в событиях правил. Разберем на конкретном примере, почему стандартный, казалось бы, код может приводить к сбоям в работе «1С:Управление торговлей 11.3» и как написать его правильно и эффективно.
Рассмотрим ситуацию, когда в событии ПередОбработкой прописана логика: если у документа установлено определенное дополнительное сведение, его не нужно регистрировать для обмена. Типичный код, который может привести к ошибке, выглядит так:
СвойствоВыб = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ДокументНеУчаствуетВОбмене");
ЗначСв = УправлениеСвойствами.ЗначениеСвойства(Объект.Ссылка, СвойствоВыб);
Если ЗначСв = Истина Тогда
Отказ = Истина;
КонецЕсли;
ВОЗВРАТ; // Источник проблемы
Проанализируем причину ошибки. В правилах регистрации объектов код, написанный в окне редактора (например, в конфигурации «Конвертация данных 2.1»), при сохранении и последующей загрузке в базу-источник компилируется динамически. Этот код встраивается внутрь процедур Модуля менеджера обмена. Оператор Возврат (Return) прерывает выполнение всей процедуры, в которую «вклеен» ваш фрагмент. Это критично, так как после вашего условия могут идти системные алгоритмы платформы или БСП, необходимые для корректного завершения регистрации объекта. В некоторых случаях использование Возврат в контексте, где ожидается простое выполнение блока инструкций, приводит к синтаксической ошибке при генерации программного модуля.
Решение: Для отмены регистрации объекта в правилах всегда используйте установку флага Отказ = Истина. Никогда не используйте Возврат в обработчиках событий ПРО.
Выясним, почему использование метода УправлениеСвойствами.ЗначениеСвойства и поиск по наименованию в правилах регистрации — это плохая практика. Правила регистрации срабатывают при каждом изменении объекта. Если в базе происходит массовое проведение документов или групповая обработка, ваш код будет вызываться тысячи раз.
НайтиПоНаименованию крайне медленный и нестабильный. Если пользователь изменит название свойства в режиме «1С:Предприятие» (например, добавит пробел), поиск вернет пустую ссылку, и условие перестанет работать без каких-либо предупреждений.Объект.Ссылка (если Объект — это ссылка) в правилах регистрации часто провоцирует лишние обращения к базе данных.Рассмотрим, как переписать этот код с использованием прямого запроса к регистру сведений ДополнительныеСведения. Это значительно ускорит работу системы при регистрации изменений.
// 1. Сначала определим ссылку на свойство.
// В идеале ее лучше кэшировать или использовать предопределенный элемент,
// но если ищем динамически, то хотя бы один раз.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДополнительныеСведения.Значение КАК Значение
|ИЗ
| РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
|ГДЕ
| ДополнительныеСведения.Объект = &Объект
| И ДополнительныеСведения.Свойство.Наименование = &ИмяСвойства";
Запрос.УстановитьПараметр("Объект", Объект); // Здесь Объект - это ссылка на документ
Запрос.УстановитьПараметр("ИмяСвойства", "ДокументНеУчаствуетВОбмене");
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Если Выборка.Значение = Истина Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
Посмотрим на ситуацию со стороны высокой нагрузки. Если мы проверяем одно и то же свойство для тысячи документов, запрос будет выполняться тысячу раз. Чтобы этого избежать, проанализируем возможность получения ссылки на свойство ДокументНеУчаствуетВОбмене заранее.
В событиях регистрации (например, ПередОбработкойПравил) можно один раз найти ссылку на свойство и поместить ее в структуру Параметры, которая доступна во всех последующих вызовах для конкретных объектов. Это избавит базу данных от необходимости искать свойство по строке «ДокументНеУчаствуетВОбмене» для каждого документа.
Подведем итог и составим эталонный шаблон кода для фильтрации объектов по дополнительному сведению в УТ 11.3:
// Проверяем, не является ли объект новым (у нового нет ссылок и сведений)
Если НЕ Объект.Пустая() Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ИСТИНА КАК НеУчаствует
|ИЗ
| РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
|ГДЕ
| ДополнительныеСведения.Объект = &Объект
| И ДополнительныеСведения.Свойство.Наименование = &ИмяСвойства
| И ДополнительныеСведения.Значение = ИСТИНА";
Запрос.УстановитьПараметр("Объект", Объект);
Запрос.УстановитьПараметр("ИмяСвойства", "ДокументНеУчаствуетВОбмене");
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
Важные моменты, которые мы разобрали:
УправлениеСвойствами.Соблюдение этих правил позволит избежать трудноуловимых ошибок в обмене данными и обеспечит стабильную работу бизнес-процессов в конфигурациях на базе 1С:Предприятие 8.3.