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