Почему возникает ошибка при использовании оператора "Возврат" в правилах регистрации и как правильно фильтровать объекты при обмене?

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

При настройке синхронизации данных между конфигурациями 1С часто возникает необходимость ограничить выгрузку определенных объектов. Для этого используются правила регистрации объектов (ПРО). Однако начинающие разработчики часто сталкиваются с непонятными ошибками при попытке программного описания условий в событиях правил. Разберем на конкретном примере, почему стандартный, казалось бы, код может приводить к сбоям в работе «1С:Управление торговлей 11.3» и как написать его правильно и эффективно.

Проблема: использование оператора Возврат в обработчиках

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


СвойствоВыб = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ДокументНеУчаствуетВОбмене");
ЗначСв = УправлениеСвойствами.ЗначениеСвойства(Объект.Ссылка, СвойствоВыб);
Если ЗначСв = Истина Тогда
    Отказ = Истина;
КонецЕсли;
ВОЗВРАТ; // Источник проблемы

Проанализируем причину ошибки. В правилах регистрации объектов код, написанный в окне редактора (например, в конфигурации «Конвертация данных 2.1»), при сохранении и последующей загрузке в базу-источник компилируется динамически. Этот код встраивается внутрь процедур Модуля менеджера обмена. Оператор Возврат (Return) прерывает выполнение всей процедуры, в которую «вклеен» ваш фрагмент. Это критично, так как после вашего условия могут идти системные алгоритмы платформы или БСП, необходимые для корректного завершения регистрации объекта. В некоторых случаях использование Возврат в контексте, где ожидается простое выполнение блока инструкций, приводит к синтаксической ошибке при генерации программного модуля.

Решение: Для отмены регистрации объекта в правилах всегда используйте установку флага Отказ = Истина. Никогда не используйте Возврат в обработчиках событий ПРО.

Оптимизация производительности: Запросы против функций БСП

Выясним, почему использование метода УправлениеСвойствами.ЗначениеСвойства и поиск по наименованию в правилах регистрации — это плохая практика. Правила регистрации срабатывают при каждом изменении объекта. Если в базе происходит массовое проведение документов или групповая обработка, ваш код будет вызываться тысячи раз.

  1. Поиск по наименованию: Метод НайтиПоНаименованию крайне медленный и нестабильный. Если пользователь изменит название свойства в режиме «1С:Предприятие» (например, добавит пробел), поиск вернет пустую ссылку, и условие перестанет работать без каких-либо предупреждений.
  2. Обращение через точку: Конструкция Объект.Ссылка (если Объект — это ссылка) в правилах регистрации часто провоцирует лишние обращения к базе данных.
  3. Функции общего модуля: Универсальные функции БСП выполняют множество проверок (права доступа, кэширование и т.д.), которые избыточны для простой проверки флага регистрации.

Рассмотрим, как переписать этот код с использованием прямого запроса к регистру сведений ДополнительныеСведения. Это значительно ускорит работу системы при регистрации изменений.


// 1. Сначала определим ссылку на свойство. 
// В идеале ее лучше кэшировать или использовать предопределенный элемент, 
// но если ищем динамически, то хотя бы один раз.

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДополнительныеСведения.Значение КАК Значение
    |ИЗ
    |	РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
    |ГДЕ
    |	ДополнительныеСведения.Объект = &Объект
    |	И ДополнительныеСведения.Свойство.Наименование = &ИмяСвойства";

Запрос.УстановитьПараметр("Объект", Объект); // Здесь Объект - это ссылка на документ
Запрос.УстановитьПараметр("ИмяСвойства", "ДокументНеУчаствуетВОбмене");

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда
    Если Выборка.Значение = Истина Тогда
        Отказ = Истина;
    КонецЕсли;
КонецЕсли;

Как сделать еще лучше: использование параметров сеанса или кэширования

Посмотрим на ситуацию со стороны высокой нагрузки. Если мы проверяем одно и то же свойство для тысячи документов, запрос будет выполняться тысячу раз. Чтобы этого избежать, проанализируем возможность получения ссылки на свойство ДокументНеУчаствуетВОбмене заранее.

В событиях регистрации (например, ПередОбработкойПравил) можно один раз найти ссылку на свойство и поместить ее в структуру Параметры, которая доступна во всех последующих вызовах для конкретных объектов. Это избавит базу данных от необходимости искать свойство по строке «ДокументНеУчаствуетВОбмене» для каждого документа.

Правильная структура кода в событии ПередОбработкой

Подведем итог и составим эталонный шаблон кода для фильтрации объектов по дополнительному сведению в УТ 11.3:


// Проверяем, не является ли объект новым (у нового нет ссылок и сведений)
Если НЕ Объект.Пустая() Тогда
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	ИСТИНА КАК НеУчаствует
    |ИЗ
    |	РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
    |ГДЕ
    |	ДополнительныеСведения.Объект = &Объект
    |	И ДополнительныеСведения.Свойство.Наименование = &ИмяСвойства
    |	И ДополнительныеСведения.Значение = ИСТИНА";
    
    Запрос.УстановитьПараметр("Объект", Объект);
    Запрос.УстановитьПараметр("ИмяСвойства", "ДокументНеУчаствуетВОбмене");
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Если НЕ РезультатЗапроса.Пустой() Тогда
        Отказ = Истина;
    КонецЕсли;
    
КонецЕсли;

Важные моменты, которые мы разобрали:

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

← На главную