При изучении типовых конфигураций «1С:Предприятие» разработчики часто сталкиваются со следующей конструкцией в самом начале предопределенных процедур модулей объектов (справочников, документов, процессов):
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Для начинающих специалистов и тех, кто только знакомится с механизмами интеграции, назначение этой строки кода может быть неочевидным. Возникает множество вопросов: зачем принудительно прерывать выполнение модуля? Какую роль играет свойство ОбменДанными.Загрузка? Каковы стандарты его применения и где именно в коде должна располагаться эта проверка? В этой статье мы подробно разберем все нюансы использования данного механизма, проанализируем поведение платформы «1С» и рассмотрим практические примеры.
Свойство ОбменДанными.Загрузка принадлежит объектам конфигурации, которые могут быть записаны в базу данных (справочники, документы, регистры и т.д.). Оно имеет тип Булево. По умолчанию при интерактивной работе пользователя или при стандартном программном создании объектов это свойство всегда равно Ложь.
Однако при переносе данных из других информационных систем (например, через планы обмена, правила конвертации данных КД 2.0 / КД 3.0 или веб-сервисы) специализированные механизмы платформы устанавливают это свойство в значение Истина перед записью объекта в базу данных. Это сигнализирует системе о том, что происходит не создание нового элемента пользователем, а импорт уже существующего, проверенного и корректного объекта из другой базы-источника.
Когда свойство ОбменДанными.Загрузка установлено в Истина, сама платформа «1С:Предприятие» переходит в режим «минимальных проверок»:
ОбменДанными.Загрузка в состояние Ложь.Если сама платформа уже делает поблажки при записи объектов с установленным флагом Загрузка = Истина, зачем нам вручную писать код прерывания процедур в модулях объектов? Выясним причину.
Дело в том, что в модулях объектов (особенно в предопределенных процедурах ПередЗаписью и ПриЗаписи) разработчики прописывают сложнейшую прикладную бизнес-логику:
Представим, что мы выполняем первоначальный обмен данными и загружаем в базу-приемник 100 000 контрагентов или документов. Если при записи каждого из них начнет выполняться вся эта интерактивная логика, мы столкнемся со следующими критическими проблемами:
Именно для предотвращения этих проблем и используется конструкция Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;. Она мгновенно прекращает выполнение тяжелой прикладной логики, позволяя платформе просто сохранить пришедшие «чистые» данные в СУБД.
Рассмотрим важный архитектурный вопрос: где именно должна располагаться эта проверка? Среди разработчиков велись споры о возможности размещения этой конструкции непосредственно в теле модуля объекта (вне каких-либо процедур).
Внимание: размещать этот код вне процедур — грубейшая ошибка! Код в теле модуля объекта (вне процедур и функций) выполняется ровно один раз — в момент инициализации объекта в оперативной памяти компьютера (например, при вызове методов СоздатьДокумент(), СоздатьЭлемент() или при получении объекта из ссылки через ПолучитьОбъект()). В этот момент объект только создается в памяти, транзакция записи еще не началась, и свойство ОбменДанными.Загрузка гарантированно равно Ложь. Написание такой конструкции в теле модуля просто не сработает при записи и может привести к непредсказуемому поведению платформы.
Проверка должна находиться строго внутри предопределенных процедур-обработчиков событий модуля объекта. Чаще всего это:
ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)ПриЗаписи(Отказ)ПередУдалением(Отказ)Согласно Официальным стандартам разработки фирмы «1С» (в частности, стандарту, регулирующему правила написания обработчиков событий), код внутри этих процедур рекомендуется разделять на две логические части:
Разберем по шагам правильную структуру обработчика ПередЗаписью в модуле объекта справочника:
Процедура ПередЗаписью(Отказ)
// ЧАСТЬ 1: Действия, выполняемые ВСЕГДА
// Например, заполнение служебных реквизитов БСП для регистрации изменений
ЭтотОбъект.ДополнительныеСвойства.Вставить("ВыполненаРегистрация", Истина);
// Блок отсечения при обмене данными
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// ЧАСТЬ 2: Бизнес-логика (выполняется только при интерактивной работе или обычном программном создании)
// Выясним причину незаполнения важных реквизитов
Если Не ЗначениеЗаполнено(ЭтотОбъект.НаименованиеПолное) Тогда
ЭтотОбъект.НаименованиеПолное = ЭтотОбъект.Наименование;
КонецЕсли;
// Проверим корректность заполнения ИНН для юрлиц
Если ЭтотОбъект.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮридическоеЛицо Тогда
ПроверитьЗаполнениеИНН(Отказ);
КонецЕсли;
КонецПроцедуры
Отдельное внимание уделим Подпискам на события (Event Subscriptions). Это мощный инструмент платформы «1С», позволяющий вынести общий код обработчиков событий для множества разных объектов в один общий модуль. Например, подписка на событие ПередЗаписью для всех документов конфигурации, которая автоматически проверяет запрет редактирования прошлых периодов.
Если вы создаете собственную подписку на события записи или удаления объектов, вы обязаны в самом начале ее обработчика сделать проверку свойства Загрузка у источника события. Иначе при первом же обмене данными ваша подписка начнет срабатывать для каждого загружаемого объекта, что приведет к критическим ошибкам или полной блокировке загрузки.
Рассмотрим шаблон правильного написания обработчика подписки на событие:
Процедура ИмяПодпискиПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Обязательная проверка режима загрузки для Источника (им выступает записываемый объект)
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Далее следует прикладной код подписки
ПроверитьДоступностьПериодаРедактирования(Источник, Отказ);
КонецПроцедуры
Среди начинающих разработчиков распространено заблуждение, что проверку ОбменДанными.Загрузка нужно вставлять также в процедуру ОбработкаПроведения модуля документа. Давайте проанализируем, почему это не имеет смысла и является методологической ошибкой.
Когда документ переносится через механизмы обмена данными в проведенном состоянии, платформа «1С» ведет себя следующим образом:
Проведен = Истина).ОбработкаПроведения не вызывается вообще**!Платформа не инициирует проведение заново, так как движения уже сформированы в источнике и переданы «как есть». Пытаться же программно провести документ, у которого в этот момент свойство ОбменДанными.Загрузка установлено в значение Истина, запрещено на уровне ядра платформы — система выдаст ошибку времени выполнения. Поэтому в процедуре ОбработкаПроведения проверку флага загрузки делать не нужно.
Опытные программисты «1С» часто используют свойство ОбменДанными.Загрузка как легальный инструмент (лайфхак) при написании различных сервисных и групповых обработок для быстрого изменения данных в информационной базе.
Например, перед нами стоит задача — у 50 000 элементов справочника «Номенклатура» изменить значение одного реквизита (допустим, установить новую группу доступа или признак учета). Если делать это стандартным образом, то запись каждого элемента может занимать до нескольких секунд из-за тяжелых сопутствующих проверок в модуле номенклатуры. Процесс рискует затянуться на всю ночь.
Мы можем искусственно включить режим загрузки для записываемого объекта, чтобы обойти эти проверки и мгновенно обновить реквизит:
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
ОбъектНоменклатуры = Выборка.ПолучитьОбъект();
ОбъектНоменклатуры.ГруппаДоступа = Справочники.ГруппыДоступаНоменклатуры.Общая;
// Включаем режим обмена данными для быстрой записи без проверок
ОбъектНоменклатуры.ОбменДанными.Загрузка = Истина;
Попытка
ОбъектНоменклатуры.Записать();
Исключение
ЗаписьЖурналаРегистрации("ОшибкаЗаписиНоменклатуры",,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
Важное предупреждение: Используя данный метод обхода проверок, разработчик берет на себя 100% ответственности за корректность и непротиворечивость данных. Платформа запишет абсолютно любые значения, которые вы укажете в реквизитах, даже если они нарушают логику конфигурации или ссылаются на несуществующие элементы. Пользуйтесь этим инструментом аккуратно и только тогда, когда вы точно уверены в правильности записываемых данных.
Мы подробно разобрали концепцию работы флага ОбменДанными.Загрузка и выяснили, для чего нужна проверка прерывания в модулях объектов. Резюмируем основные правила работы с этим механизмом:
Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; — это обязательный стандарт разработки «1С», предотвращающий выполнение ресурсоемких проверок и расчетов при импорте данных.ПередЗаписью, ПриЗаписи, ПередУдалением), но ни в коем случае не в теле самого модуля объекта.ОбработкаПроведения проверку ставить не нужно — при обмене эта процедура не вызывается платформой.Загрузка = Истина в собственных обработках для ускорения записи больших массивов данных, но помните о рисках нарушения ссылочной и логической целостности базы.