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