Зачем нужна конструкция "Если ОбменДанными.Загрузка Тогда Возврат;" в модуле объекта 1С?

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

При изучении типовых конфигураций «1С:Предприятие» разработчики часто сталкиваются со следующей конструкцией в самом начале предопределенных процедур модулей объектов (справочников, документов, процессов):


Если ОбменДанными.Загрузка Тогда
    Возврат;
КонецЕсли;

Для начинающих специалистов и тех, кто только знакомится с механизмами интеграции, назначение этой строки кода может быть неочевидным. Возникает множество вопросов: зачем принудительно прерывать выполнение модуля? Какую роль играет свойство ОбменДанными.Загрузка? Каковы стандарты его применения и где именно в коде должна располагаться эта проверка? В этой статье мы подробно разберем все нюансы использования данного механизма, проанализируем поведение платформы «1С» и рассмотрим практические примеры.

Что такое режим загрузки данных и как ведет себя платформа

Свойство ОбменДанными.Загрузка принадлежит объектам конфигурации, которые могут быть записаны в базу данных (справочники, документы, регистры и т.д.). Оно имеет тип Булево. По умолчанию при интерактивной работе пользователя или при стандартном программном создании объектов это свойство всегда равно Ложь.

Однако при переносе данных из других информационных систем (например, через планы обмена, правила конвертации данных КД 2.0 / КД 3.0 или веб-сервисы) специализированные механизмы платформы устанавливают это свойство в значение Истина перед записью объекта в базу данных. Это сигнализирует системе о том, что происходит не создание нового элемента пользователем, а импорт уже существующего, проверенного и корректного объекта из другой базы-источника.

Когда свойство ОбменДанными.Загрузка установлено в Истина, сама платформа «1С:Предприятие» переходит в режим «минимальных проверок»:

  1. Отключение контроля ссылочной целостности: Платформа позволяет записать объект, даже если в его реквизитах содержатся ссылки на элементы, которых еще нет в текущей базе данных (так называемые «битые» ссылки). Это необходимо для того, чтобы решить проблему цикческих ссылок при обмене, когда подчиненный объект должен быть загружен раньше родительского.
  2. Игнорирование уникальности кодов и номеров: Платформа «сквозь пальцы» смотрит на дублирование кодов справочников или номеров документов, предполагая, что раз в базе-источнике эти данные были сопоставлены и уникальны в рамках своей бизнес-логики, то и в базе-приемнике их нужно сохранить «как есть».
  3. Автоматический сброс флага: Важно понимать, что это свойство устанавливается временно. Как только транзакция записи конкретного объекта завершается успешно, платформа автоматически возвращает значение свойства ОбменДанными.Загрузка в состояние Ложь.

Зачем отключать код прикладных модулей при обмене?

Если сама платформа уже делает поблажки при записи объектов с установленным флагом Загрузка = Истина, зачем нам вручную писать код прерывания процедур в модулях объектов? Выясним причину.

Дело в том, что в модулях объектов (особенно в предопределенных процедурах ПередЗаписью и ПриЗаписи) разработчики прописывают сложнейшую прикладную бизнес-логику:

Представим, что мы выполняем первоначальный обмен данными и загружаем в базу-приемник 100 000 контрагентов или документов. Если при записи каждого из них начнет выполняться вся эта интерактивная логика, мы столкнемся со следующими критическими проблемами:

  1. Катастрофическое падение производительности: Вместо простой и быстрой записи транзакции СУБД сервер «1С» начнет производить миллионы лишних вычислений, запросов к базе данных и проверок. Процесс обмена, который мог завершиться за 10 минут, растянется на десятки часов или вызовет переполнение технологического журнала и зависание сервера.
  2. Искажение переносимых данных: Если в базе-приемнике сработает алгоритм автоматического пересчета (например, округление копеек или пересчет валюты по другому курсу), то данные в приемнике станут отличаться от данных в источнике. Это нарушит главный принцип обмена — идентичность информации в обеих системах.
  3. Ошибки блокировок и транзакций: Попытки создать связанные объекты «на лету» во время обмена часто приводят к взаимным блокировкам (Deadlocks) в СУБД, так как параллельно может записываться объект, который мы пытаемся заблокировать из кода обработчика.
  4. Лишние внешние действия: Рассылка писем клиентам или списание бонусов сработает повторно при обычном импорте старых заказов прошлых лет, что приведет к панике среди пользователей и финансовым потерям.

Именно для предотвращения этих проблем и используется конструкция Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;. Она мгновенно прекращает выполнение тяжелой прикладной логики, позволяя платформе просто сохранить пришедшие «чистые» данные в СУБД.

Где и как правильно размещать проверку загрузки

Рассмотрим важный архитектурный вопрос: где именно должна располагаться эта проверка? Среди разработчиков велись споры о возможности размещения этой конструкции непосредственно в теле модуля объекта (вне каких-либо процедур).

Внимание: размещать этот код вне процедур — грубейшая ошибка! Код в теле модуля объекта (вне процедур и функций) выполняется ровно один раз — в момент инициализации объекта в оперативной памяти компьютера (например, при вызове методов СоздатьДокумент(), СоздатьЭлемент() или при получении объекта из ссылки через ПолучитьОбъект()). В этот момент объект только создается в памяти, транзакция записи еще не началась, и свойство ОбменДанными.Загрузка гарантированно равно Ложь. Написание такой конструкции в теле модуля просто не сработает при записи и может привести к непредсказуемому поведению платформы.

Проверка должна находиться строго внутри предопределенных процедур-обработчиков событий модуля объекта. Чаще всего это:

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

  1. Действия, которые должны выполняться ВСЕГДА (даже при обмене): Сюда относится заполнение служебных реквизитов БСП (Библиотеки Стандартных Подсистем), которые необходимы для правильной регистрации изменений для последующих обменов (например, версия данных, узлы-получатели и т.д.).
  2. Действия, которые должны выполняться только при интерактивной работе: Это вся бизнес-логика, расчеты и проверки. Перед этой частью обязательно ставится условие проверки флага загрузки.

Разберем по шагам правильную структуру обработчика ПередЗаписью в модуле объекта справочника:


Процедура ПередЗаписью(Отказ)
    
    // ЧАСТЬ 1: Действия, выполняемые ВСЕГДА
    // Например, заполнение служебных реквизитов БСП для регистрации изменений
    ЭтотОбъект.ДополнительныеСвойства.Вставить("ВыполненаРегистрация", Истина);
    
    // Блок отсечения при обмене данными
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // ЧАСТЬ 2: Бизнес-логика (выполняется только при интерактивной работе или обычном программном создании)
    // Выясним причину незаполнения важных реквизитов
    Если Не ЗначениеЗаполнено(ЭтотОбъект.НаименованиеПолное) Тогда
        ЭтотОбъект.НаименованиеПолное = ЭтотОбъект.Наименование;
    КонецЕсли;
    
    // Проверим корректность заполнения ИНН для юрлиц
    Если ЭтотОбъект.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮридическоеЛицо Тогда
        ПроверитьЗаполнениеИНН(Отказ);
    КонецЕсли;

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

Использование конструкции в подписках на события

Отдельное внимание уделим Подпискам на события (Event Subscriptions). Это мощный инструмент платформы «1С», позволяющий вынести общий код обработчиков событий для множества разных объектов в один общий модуль. Например, подписка на событие ПередЗаписью для всех документов конфигурации, которая автоматически проверяет запрет редактирования прошлых периодов.

Если вы создаете собственную подписку на события записи или удаления объектов, вы обязаны в самом начале ее обработчика сделать проверку свойства Загрузка у источника события. Иначе при первом же обмене данными ваша подписка начнет срабатывать для каждого загружаемого объекта, что приведет к критическим ошибкам или полной блокировке загрузки.

Рассмотрим шаблон правильного написания обработчика подписки на событие:


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

Особенности работы с документами и проведением

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

Когда документ переносится через механизмы обмена данными в проведенном состоянии, платформа «1С» ведет себя следующим образом:

Платформа не инициирует проведение заново, так как движения уже сформированы в источнике и переданы «как есть». Пытаться же программно провести документ, у которого в этот момент свойство ОбменДанными.Загрузка установлено в значение Истина, запрещено на уровне ядра платформы — система выдаст ошибку времени выполнения. Поэтому в процедуре ОбработкаПроведения проверку флага загрузки делать не нужно.

Использование флага вне механизмов обмена (Лайфхак для разработчиков)

Опытные программисты «1С» часто используют свойство ОбменДанными.Загрузка как легальный инструмент (лайфхак) при написании различных сервисных и групповых обработок для быстрого изменения данных в информационной базе.

Например, перед нами стоит задача — у 50 000 элементов справочника «Номенклатура» изменить значение одного реквизита (допустим, установить новую группу доступа или признак учета). Если делать это стандартным образом, то запись каждого элемента может занимать до нескольких секунд из-за тяжелых сопутствующих проверок в модуле номенклатуры. Процесс рискует затянуться на всю ночь.

Мы можем искусственно включить режим загрузки для записываемого объекта, чтобы обойти эти проверки и мгновенно обновить реквизит:


Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    
    ОбъектНоменклатуры = Выборка.ПолучитьОбъект();
    ОбъектНоменклатуры.ГруппаДоступа = Справочники.ГруппыДоступаНоменклатуры.Общая;
    
    // Включаем режим обмена данными для быстрой записи без проверок
    ОбъектНоменклатуры.ОбменДанными.Загрузка = Истина;
    
    Попытка
        ОбъектНоменклатуры.Записать();
    Исключение
        ЗаписьЖурналаРегистрации("ОшибкаЗаписиНоменклатуры",,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    КонецПопытки;
    
КонецЦикла;

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

Выводы и резюме

Мы подробно разобрали концепцию работы флага ОбменДанными.Загрузка и выяснили, для чего нужна проверка прерывания в модулях объектов. Резюмируем основные правила работы с этим механизмом:

← На главную