Как правильно составить запрос к регистру сведений для получения цены в 1С:Управление торговлей 11?
Мне нужно получить цену на номенклатуру в УТ11. Я использую следующий запрос:
Запрос.Текст = "ВЫБРАТЬ
| ЦеныНоменклатуры.Номенклатура.Ссылка КАК НоменклатураСсылка,
| ЦеныНоменклатуры.ВидЦены.Ссылка КАК ВидЦеныСсылка,
| ЦеныНоменклатуры.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
|ГДЕ
| ЦеныНоменклатуры.ВидЦены.Ссылка = &ВидЦены
| И ЦеныНоменклатуры.Номенклатура.Ссылка = &Номенклатура
| И ЦеныНоменклатуры.Период МЕЖДУ &ДатаНачало И &ДатаКонец";
Запрос.УстановитьПараметр("Номенклатура", НоваяСтрока.Номенклатура.Ссылка);
Запрос.УстановитьПараметр("ВидЦены", НоваяСтрока.ВидЦены.Ссылка);
Запрос.УстановитьПараметр("ДатаНачало", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКонец", КонецДня(ТекущаяДата()));
Проблема в том, что когда я добавляю условие по периоду, запрос не возвращает никаких данных. Без условия по периоду я получаю цены за старые даты. Я понимаю, что нужно выбрать цену на определенную номенклатуру, которая действует на указанный период. Что я делаю не так?
Для получения цены на номенклатуру в 1С:Управление торговлей 11 из регистра сведений “ЦеныНоменклатуры” нужно использовать правильный подход к выборке данных по периоду. Ваша проблема заключается в том, что вы пытаетесь выбрать цены в диапазоне дат, а вам нужна конкретная цена, действующая на указанную дату.
Содержание
- Основные проблемы в вашем запросе
- Структура регистра “ЦеныНоменклатуры”
- Правильный синтаксис запроса
- Методы получения цены на конкретную дату
- Распространенные ошибки и их решения
- Продвинутые сценарии работы с регистром
- Выводы и рекомендации
Основные проблемы в вашем запросе
Ваш текущий запрос использует условие МЕЖДУ &ДатаНачало И &ДатаКонец, что приводит к выборке всех записей цен в указанном диапазоне, а не к получению конкретной цены, действующей на нужную дату.
Проблема заключается в том, что:
- Регистр “ЦеныНоменклатуры” является периодическим, что означает, что каждая запись имеет интервал времени действия
- При простом отборе по диапазону вы получаете все цены, установленные за этот период
- Вам нужно получить конкретную цену, которая была действительной на определенную дату
Структура регистра “ЦеныНоменклатуры”
Из исследования источников можно определить, что регистр “ЦеныНоменклатуры” имеет следующую структуру:
Измерения:
- Номенклатура (ссылка на справочник)
- ВидЦены (ссылка на справочник)
Ресурсы:
- Цена (числовое значение)
Реквизиты:
- ВалютаЦены (ссылка на справочник валют)
- Упаковка (числовое значение)
Периодичность: “В пределах секунды”
Режим записи: “Подчинение регистратору”
Правильный синтаксис запроса
Для получения цены на конкретную дату нужно использовать следующие подходы:
Вариант 1: Использование виртуальной таблицы “СрезПоследний”
Запрос.Текст = "ВЫБРАТЬ
| ЦеныНоменклатуры.Номенклатура.Ссылка КАК НоменклатураСсылка,
| ЦеныНоменклатуры.ВидЦены.Ссылка КАК ВидЦеныСсылка,
| ЦеныНоменклатуры.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры.СрезПоследний(&ДатаВыбора,
| Номенклатура = &Номенклатура,
| ВидЦены = &ВидЦены) КАК ЦеныНоменклатуры";
Запрос.УстановитьПараметр("Номенклатура", НоваяСтрока.Номенклатура.Ссылка);
Запрос.УстановитьПараметр("ВидЦены", НоваяСтрока.ВидЦены.Ссылка);
Запрос.УстановитьПараметр("ДатаВыбора", ТекущаяДата());
Вариант 2: Использование стандартной функции “Цена”
Запрос.Текст = "ВЫБРАТЬ
| ЦеныНоменклатуры.Номенклатура.Ссылка КАК НоменклатураСсылка,
| ЦеныНоменклатуры.ВидЦены.Ссылка КАК ВидЦеныСсылка,
| ЦеныНоменклатуры.Цена КАK Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАK ЦеныНоменклатуры
|ГДЕ
| ЦеныНоменклатуры.Номенклатура.Ссылка = &Номенклатура
| И ЦеныНоменклатуры.ВидЦены.Ссылка = &ВидЦены
| И &ДатаВыбора МЕЖДУ ЦеныНоменклатуры.Период.Начало
| И ЦеныНоменклатуры.Период.Конец";
Запрос.УстановитьПараметр("Номенклатура", НоваяСтрока.Номенклатуры.Ссылка);
Запрос.УстановитьПараметр("ВидЦены", НоваяСтрока.ВидЦены.Ссылка);
Запрос.УстановитьПараметр("ДатаВыбора", ТекущаяДата());
Методы получения цены на конкретную дату
Метод 1: Виртуальная таблица “СрезПоследний” (рекомендуемый)
Этот метод является наиболее эффективным и правильным для получения цены на конкретную дату:
// Получение цены на указанную дату
Функция ПолучитьЦенуНоменклатуры(Номенклатура, ВидЦены, ДатаВыбора) Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| ЦеныНоменклатуры.Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАK ЦеныНоменклатуры
|ГДЕ
| ЦеныНоменклатуры.Номенклатура = &Номенклатура
| И ЦеныНоменклатуры.ВидЦены = &ВидЦены
| И &ДатаВыбора МЕЖДУ ЦеныНоменклатуры.Период.Начало
| И ЦеныНоменклатуры.Период.Конец";
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Запрос.УстановитьПараметр("ВидЦены", ВидЦены);
Запрос.УстановитьПараметр("ДатаВыбора", ДатаВыбора);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Цена;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Метод 2: Использование встроенных функций 1С
// Использование встроенной функции Цена
Цена = УправлениеТорговлейЦенообразование.Цена(Номенклатура, ВидЦены, ДатаВыбора);
Распространенные ошибки и их решения
Ошибка 1: Неправильное использование условия по периоду
Проблема: Ваш исходный запрос использовал диапазон дат для отбора:
И ЦеныНоменклатуры.Период МЕЖДУ &ДатаНачало И &ДатаКонец
Решение: Нужно проверять, попадает ли искомая дата в интервал действия цены:
И &ДатаВыбора МЕЖДУ ЦеныНоменклатуры.Период.Начало И ЦеныНоменклатуры.Период.Конец
Ошибка 2: Отсутствие сортировки по дате
Проблема: Если за один день может быть установлено несколько цен, нужно получить последнюю.
Решение: Добавить сортировку по дате убывания:
УПОРЯДОЧИТЬ ПО ЦеныНоменклатуры.Период.Конец УБЫВАНИЮ
Ошибка 3: Неправильная обработка пустых интервалов
Проблема: Некоторые цены могут иметь неограниченный интервал действия.
Решение: Обрабатывать случаи, когда КонецПериода = Дата(0001, 1, 1):
И (&ДатаВыбора >= ЦеныНоменклатуры.Период.Начало
И (ЦеныНоменклатуры.Период.Конец = ДатаВремя(1, 1, 1)
ИЛИ &ДатаВыбора <= ЦеныНоменклатуры.Период.Конец))
Продвинутые сценарии работы с регистром
Сценарий 1: Получение цен с учетом характеристик номенклатуры
Запрос.Текст = "ВЫБРАТЬ
| ЦеныНоменклатуры.Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАK ЦеныНоменклатуры
|ГДЕ
| ЦеныНоменклатуры.Номенклатура = &Номенклатура
| И ЦеныНоменклатуры.Характеристика = &Характеристика
| И ЦеныНоменклатуры.ВидЦены = &ВидЦены
| И &ДатаВыбора МЕЖДУ ЦеныНоменклатуры.Период.Начало
| И ЦеныНоменклатуры.Период.Конец
|УПОРЯДОЧИТЬ ПО
| ЦеныНоменклатуры.Период.Конец УБЫВАНИЮ";
Сценарий 2: Получение истории изменения цен
Запрос.Текст = "ВЫБРАТЬ
| ЦеныНоменклатуры.Период.Начало КАK ДатаНачала,
| ЦеныНоменклатуры.Период.Конец КАK ДатаОкончания,
| ЦеныНоменклатуры.Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАK ЦеныНоменклатуры
|ГДЕ
| ЦеныНоменклатуры.Номенклатура = &Номенклатура
| И ЦеныНоменклатуры.ВидЦены = &ВидЦены
| И ЦеныНоменклатуры.Период.Начало МЕЖДУ &ДатаНачала и &ДатаОкончания
|УПОРЯДОЧИТЬ ПО
| ЦеныНоменклатуры.Период.Начало ВОЗРАСТАНИЮ";
Выводы и рекомендации
-
Используйте виртуальную таблицу “СрезПоследний” для получения цены на конкретную дату - это самый эффективный и правильный метод.
-
Проверяйте интервал действия цены с помощью условия
&ДатаВыбора МЕЖДУ Период.Начало И Период.Конец. -
Обрабатывайте случаи с неограниченным периодом действия, когда Период.Конец = Дата(0001, 1, 1).
-
Всегда добавляйте сортировку по дате убывания, если за один день может быть установлено несколько цен.
-
Для получения истории изменения цен используйте выборку по диапазону дат с сортировкой по дате возрастания.
-
Для новых версий УТ 11 (11.5 и выше) используйте регистр “ЦеныНоменклатуры25”, который имеет расширенную функциональность.
Правильная работа с регистром “ЦеныНоменклатуры” позволит вам получать актуальные цены на любую дату и избегать проблем с устаревшими данными.
Источники
- Получение в запросе цен на дату документа
- Новое в версии 11.5.6 :: Информация об обновлениях программных продуктов 1С:Предприятие
- Регистр сведений ЦеныНоменклатуры25 — разбираем как получать цены
- Отбор в регистре сведений 1C | Блог 1С программиста
- Установка цен Управление Торговлей 11. Произвольный запрос к данным ИБ