При работе с механизмом ценообразования в конфигурации «Управление торговлей», редакция 11 (а также в ERP 2.5 и Комплексной автоматизации), разработчики часто сталкиваются с ошибкой при попытке рассчитать цены, если для Вида цены выбран способ задания «Произвольный запрос к данным ИБ». Ошибка возникает в общем модуле УстановкаЦенСервер и прерывает процесс формирования прайс-листа.
В этой статье мы подробно проанализируем ситуацию, разберем причины возникновения ошибки и предложим пошаговый алгоритм её решения, основываясь на опыте работы с типовыми механизмами платформы 1С:Предприятие 8.3.
Рассмотрим ситуацию: вы создали произвольный алгоритм, написали запрос, который успешно проходит проверку в консоли запросов и корректно сохраняется в схеме СКД (Система компоновки данных). Однако при попытке заполнить цены в обработке «Прайс-лист» система выдает исключение:
Несоответствие типов (параметр номер '1')
{ОбщийМодуль.УстановкаЦенСервер.Модуль(8680)}:КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиИзВидаЦены);
Проанализируем контекст. Ошибка «Несоответствие типов» в данном методе означает, что переменная НастройкиИзВидаЦены имеет значение Неопределено, в то время как метод ЗагрузитьНастройки ожидает объект типа НастройкиКомпоновкиДанных. Выясним, почему настройки теряются при передаче в процедуру расчета.
Это наиболее распространенная причина в современных типовых конфигурациях. В УТ 11 расчет цен практически всегда выносится в фоновое задание для обеспечения отзывчивости интерфейса. Рассмотрим механизм передачи данных подробнее.
Когда вы инициируете расчет из формы прайс-листа, система подготавливает данные и помещает их во Временное хранилище. Однако стоит помнить важную техническую особенность: адрес временного хранилища, созданный в одном сеансе (сеанс пользователя), по умолчанию недоступен в другом сеансе (сеанс фонового задания), если только этот адрес не был передан явно и не обеспечена привязка к идентификатору формы или сеанса.
Разберем, как это происходит в коде:
Неопределено.ЗагрузитьНастройки, что и вызывает критическую ошибку.Иногда проблема кроется не в программном коде, а в самих данных. Настройки компоновки данных для произвольных запросов хранятся в реквизите НастройкиКомпоновкиДанных справочника ВидыЦен. Этот реквизит имеет тип ХранилищеЗначения.
Проанализируем возможные сценарии повреждения данных:
НастройкиКомпоновкиДанных был записан некорректно, метод Получить() вернет пустую ссылку или Неопределено.Рассмотрим этапы диагностики и исправления ошибки, начиная от простых действий и заканчивая глубокой отладкой кода.
Первым делом попробуем исключить ошибку данных в справочнике. Для этого выполним следующие действия:
ХранилищеЗначения.Типовой механизм УстановкаЦенСервер ожидает, что ваш произвольный запрос вернет определенный набор полей. Проанализируем ваш запрос. В нем обязательно должны присутствовать поля со следующими именами (псевдонимами):
НоменклатураХарактеристика (если в системе включен учет по характеристикам)ЦенаУпаковка (если требуется расчет по упаковкам)ВалютаЕсли компоновщик настроек обнаружит несоответствие структуры колонок ожидаемым правилам заполнения, он может сформировать пустой объект настроек.
Если простые методы не помогли, необходимо прибегнуть к отладке. Поскольку расчет идет в фоне, обычная точка останова не сработает. Выполним следующие настройки:
УстановкаЦенСервер на строке, где вызывается ЗагрузитьНастройки.Посмотрим на пример кода, который поможет вам проверить содержимое переменной прямо в момент возникновения ошибки. Вы можете временно вставить этот блок перед проблемной строкой для анализа:
Если НастройкиИзВидаЦены = Неопределено Тогда
ЗаписьЖурналаРегистрации("ОшибкаРасчетаЦен",
УровеньЖурналаРегистрации.Ошибка, , ,
"Настройки для вида цены не получены из хранилища!");
КонецЕсли;
Если в журнале регистрации появилось это сообщение, значит, проблема подтверждена: данные не доходят до фонового задания.
Для исправления ситуации на программном уровне (если вы создаете свое расширение или дорабатываете конфигурацию), убедитесь, что при вызове длительной операции передается именно структура настроек, а не адрес во временном хранилище, который может быть очищен.
Рассмотрим правильный подход к получению настроек из вида цены:
Функция ПолучитьНастройкиСКД(СсылкаВидЦены)
// Получаем данные непосредственно из объекта ссылки,
// чтобы избежать проблем с временным хранилищем в фоновом задании
ОбъектВидаЦены = СсылкаВидЦены.ПолучитьОбъект();
Настройки = ОбъектВидаЦены.НастройкиКомпоновкиДанных.Получить();
Если Настройки = Неопределено Тогда
// Инициализируем настройки по умолчанию, если в хранилище пусто
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОбъектВидаЦены.СхемаКомпоновкиДанных));
Настройки = Компоновщик.Настройки;
КонецЕсли;
Возврат Настройки;
КонецФункции
Стоит отметить, что в релизах ветки 11.5.18 наблюдалась специфическая ошибка в модуле УстановкаЦенСервер. При определенных условиях (использование расширений или специфических настроек обеспечения) типовой код неверно определял контекст и пытался загрузить настройки из неинициализированного объекта.
В этом случае помогает создание расширения, которое в процедуре ПередВычислитьЗначенияЦеныПоДаннымИБ проверяет наличие настроек и, если они пусты, принудительно считывает их из справочника ВидыЦен по ссылке, как показано в примере выше.
Мы выяснили, что ошибка «Несоответствие типов» при загрузке настроек компоновщика — это следствие того, что в процедуру передается пустое значение (Неопределено). Основными векторами решения являются проверка корректности записи справочника Виды цен, контроль структуры полей в СКД-запросе и обеспечение доступности данных в контексте фонового задания. Проанализировав эти моменты, вы сможете восстановить работоспособность автоматического расчета цен в вашей системе.