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