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