Разберем распространенную проблему, с которой сталкиваются разработчики при попытке получить актуальную цену товара из регистра сведений ЦеныНоменклатуры с помощью виртуальной таблицы СрезПоследних. Бывают ситуации, когда в программе заданы разные цены для одной и той же номенклатуры и одного типа цен, но в разных единицах измерения (например, за штуку и за килограмм). Однако запрос к виртуальной таблице возвращает только одну из этих цен.
Выясним, почему так происходит, как устроена архитектура регистра и какими способами можно корректно получить цены с учетом единицы измерения или устранить проблемы с копеечными отклонениями.
Рассмотрим, как платформа 1С формирует виртуальную таблицу СрезПоследних. Согласно синтаксис-помощнику и механике работы платформы, метод или виртуальная таблица СрезПоследних получает наиболее поздние записи регистра для каждого сочетания значений измерений.
В типовых конфигурациях (таких как «1С:Управление торговлей», «1С:Комплексная автоматизация» или «1С:УПП») реквизитный состав регистра сведений ЦеныНоменклатуры обычно настроен следующим образом:
Номенклатура, ХарактеристикаНоменклатуры, СерияНоменклатуры, ТипЦен (или ВидЦены).Цена.ЕдиницаИзмерения, Валюта, ПроцентСкидкиНаценки.Поскольку поле ЕдиницаИзмерения является ресурсом или реквизитом, а не измерением регистра, платформа не использует его в качестве уникального ключа при построении среза. В результате для одной комбинации Номенклатура + ТипЦен виртуальная таблица вернет строго одну запись — самую свежую по дате периода, полностью проигнорировав различия в единицах измерения.
Проанализируем пример запроса, который не дает ожидаемого результата:
ВЫБРАТЬ
ЦеныСрезПоследних.ТипЦен КАК ТипЦен,
ЦеныСрезПоследних.Номенклатура КАК Номенклатура,
ЦеныСрезПоследних.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
ЦеныСрезПоследних.Цена КАК Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
&Период,
Номенклатура = &Номенклатура
И ТипЦен = &ТипЦен) КАК ЦеныСрезПоследних
В данном запросе, даже если в регистре записаны две цены на одну дату (одна в штуках, другая в килограммах), виртуальная таблица СрезПоследних вернет только ту запись, которая оказалась последней. Запись с другой единицей измерения будет проигнорирована.
Если в вашей конфигурации цены действительно хранятся в регистре сведений с привязкой к полю ЕдиницаИзмерения, мы можем составить пакетный запрос к физической таблице РегистрСведений.ЦеныНоменклатуры. Прямое обращение без фильтрации по дате вернет всю историю изменений, поэтому необходимо применить эмуляцию среза последних.
Рассмотрим, как реализовать такой запрос с помощью временных таблиц:
ВЫБРАТЬ
Цены.Номенклатура КАК Номенклатура,
Цены.ТипЦен КАК ТипЦен,
Цены.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
МАКСИМУМ(Цены.Период) КАК Период
ПОМЕСТИТЬ ВТ_МаксимальныеДаты
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК Цены
ГДЕ
Цены.Период <= &Период
И Цены.Номенклатура = &Номенклатура
И Цены.ТипЦен = &ТипЦен
И Цены.ЕдиницаИзмерения = &ЕдиницаИзмерения
ГРУППИРОВАТЬ ПО
Цены.Номенклатура,
Цены.ТипЦен,
Цены.ЕдиницаИзмерения
;
ВЫБРАТЬ
Цены.Номенклатура КАК Номенклатура,
Цены.ТипЦен КАК ТипЦен,
Цены.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
Цены.Цена КАК Цена
ИЗ
ВТ_МаксимальныеДаты КАК МаксДаты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены
ПО МаксДаты.Номенклатура = Цены.Номенклатура
И МаксДаты.ТипЦен = Цены.ТипЦен
И МаксДаты.ЕдиницаИзмерения = Цены.ЕдиницаИзмерения
И МаксДаты.Период = Цены.Период
В этом запросе мы явно сгруппировали данные по единице измерения, найдя максимальную дату записи для нужного фильтра, а затем соединили результат с физической таблицей для получения актуального значения ресурса Цена.
С методической точки зрения в типовых решениях 1С принято хранить базовую цену за одну основную единицу (или базовую упаковку), а цены для остальных единиц измерения рассчитывать динамически. Пересчет выполняется через коэффициент единицы измерения из справочника ЕдиницыИзмерения или Упаковки.
Посмотрим на формулу расчета цены за необходимую единицу:
ЦенаЗаЕдиницу = (БазоваяЦена * КоэффициентЦелевойЕдиницы) / КоэффициентБазовойЕдиницы
Этот подход избавляет от необходимости хранить множество цен в регистре и исключает дублирование данных при изменении прайс-листа.
Часто необходимость получать цену за килограмм возникает из-за требований контрагентов выводить в накладных (ТОРГ-12, УПД) данные в весовых единицах, в то время как учет ведется в штуках. При обратном расчете цены (деление общей суммы на вес) нередко появляются расхождения в 1 копейку из-за округления.
Разберем методически верный подход к формированию печатной формы:
При использовании такого способа сумма в печатной форме гарантированно совпадет с суммой проведенного документа, а у вас отпадет необходимость создавать искусственные цены в регистре для разных единиц измерения.