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