Как получить список товаров с ценой последнего поступления в 1С:Управление торговлей 10.3

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В типовой конфигурации «1С:Управление торговлей 10.3» часто возникает задача оперативного получения цен, по которым товар приходил в последний раз. Стандартные отчеты, такие как «Анализ цен», опираются на регистр сведений ЦеныНоменклатурыКонтрагентов. Однако на практике пользователи часто забывают ставить флаг «Регистрировать цены поставщика» в документе «Поступление товаров и услуг» (ПТУ), из-за чего регистр остается пустым, а стандартные отчеты — бесполезными.

В этой статье мы подробно разберем, как получить данные напрямую из документов поступления, проанализируем нюансы работы с запросами и рассмотрим способы оптимизации для больших баз данных.

Метод 1. Прямой запрос к табличным частям документов

Если в вашей базе не ведется строгий учет партий или не всегда заполняются регистры цен, самым надежным источником данных становятся сами документы ПоступлениеТоваровУслуг. Нам необходимо найти для каждой номенклатуры самый свежий документ и вытащить из него цену.

Разберем логику построения такого запроса по шагам. Основная сложность заключается в том, что в одном запросе нельзя просто выбрать МАКСИМУМ(Дата) и Цена, так как группировка по цене выдаст все уникальные цены, а не цену конкретной даты. Поэтому мы будем использовать временные таблицы.

Проанализируем пример кода, который эффективно решает эту задачу:


// Шаг 1. Собираем все даты поступлений по нужной номенклатуре
ВЫБРАТЬ
    ПоступлениеТоваровУслугТовары.Номенклатура КАК Номенклатура,
    ПоступлениеТоваровУслугТовары.Ссылка.Дата КАК ДатаПоступления,
    ПоступлениеТоваровУслугТовары.Цена КАК Цена
ПОМЕСТИТЬ ВтЦеныПоступлений
ИЗ
    Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
ГДЕ
    ПоступлениеТоваровУслугТовары.Ссылка.Проведен = ИСТИНА;

////////////////////////////////////////////////////////////////////////////////
// Шаг 2. Выбираем только максимальную дату для каждой позиции
ВЫБРАТЬ
    ВтЦеныПоступлений.Номенклатура КАК Номенклатура,
    МАКСИМУМ(ВтЦеныПоступлений.ДатаПоступления) КАК ДатаПоступления
ПОМЕСТИТЬ ВтДатыПоследнихПоступлений
ИЗ
    ВтЦеныПоступлений КАК ВтЦеныПоступлений
СГРУППИРОВАТЬ ПО
    ВтЦеныПоступлений.Номенклатура;

////////////////////////////////////////////////////////////////////////////////
// Шаг 3. Соединяем максимальные даты с исходными данными для получения цены
ВЫБРАТЬ
    ВтДатыПоследнихПоступлений.Номенклатура,
    ВтДатыПоследнихПоступлений.ДатаПоступления,
    МАКСИМУМ(ВтЦеныПоступлений.Цена) КАК Цена
ИЗ
    ВтДатыПоследнихПоступлений КАК ВтДатыПоследнихПоступлений
    ЛЕВОЕ СОЕДИНЕНИЕ ВтЦеныПоступлений КАК ВтЦеныПоступлений 
        ПО ВтЦеныПоступлений.Номенклатура = ВтДатыПоследнихПоступлений.Номенклатура
        И ВтЦеныПоступлений.ДатаПоступления = ВтДатыПоследнихПоступлений.ДатаПоступления
СГРУППИРОВАТЬ ПО
    ВтДатыПоследнихПоступлений.Номенклатура,
    ВтДатыПоследнихПоступлений.ДатаПоступления

Рассмотрим, почему в финальном шаге мы снова используем МАКСИМУМ(Цена). Это необходимо на случай, если в одну и ту же секунду были проведены два разных документа поступления по одной и той же номенклатуре с разными ценами. Функция МАКСИМУМ позволит запросу вернуть корректную (наивысшую) цену, не вызывая дублирования строк в отчете.

Метод 2. Учет валюты и налогов (НДС)

При использовании первого метода мы сталкиваемся с серьезной проблемой: в документах поступления цены могут быть указаны в разных валютах (USD, EUR, RUB). Просто сравнивать числовые значения из колонки Цена некорректно. Кроме того, в одном документе цена может включать НДС, а в другом — нет.

Чтобы получить релевантные данные, нам нужно привести все цены к единому знаменателю. Выясним, как это сделать в запросе:

  1. Приведение к валюте управленческого учета: Цену необходимо умножать на Курс и делить на Кратность из шапки документа.
  2. Учет НДС: Проверяем флаг СуммаВключаетНДС. Если он ложный, к цене нужно прибавить сумму налога (например, умножить на 1.20 для ставки 20%).

Рассмотрим пример того, как должна вычисляться цена в первом пакете запроса:


ВЫБРАТЬ
    ПоступлениеТоваровУслугТовары.Номенклатура,
    ВЫБОР 
        КОГДА ПоступлениеТоваровУслугТовары.Ссылка.СуммаВключаетНДС 
        ТОГДА ПоступлениеТоваровУслугТовары.Цена 
        ИНАЧЕ ПоступлениеТоваровУслугТовары.Цена * (1 + ПоступлениеТоваровУслугТовары.СтавкаНДС.Ставка / 100) 
    КОНЕЦ * ПоступлениеТоваровУслугТовары.Ссылка.КурсВзаиморасчетов / ПоступлениеТоваровУслугТовары.Ссылка.КратностьВзаиморасчетов КАК ЦенаУпр
...

Метод 3. Оптимизация через регистр «Закупки»

Обращение напрямую к табличным частям документов (Документ.ПоступлениеТоваровУслуг.Товары) — это «тяжелая» операция для SQL-сервера, особенно если документов в базе сотни тысяч. Профессиональные разработчики рекомендуют использовать регистр накопления «Закупки».

Преимущества использования регистра «Закупки»:

Однако помните, что если в вашей базе регистр «Закупки» не закрывается или данные в нем искажены из-за корректировок, результаты могут отличаться от первичных документов.

Метод 4. Точность определения «последнего» документа

Использование только даты документа (МАКСИМУМ(Дата)) может быть недостаточно точным. В 1С документы с одинаковой датой и временем различаются по позиции на временной оси (Момент времени).

Для получения абсолютно точного «последнего» поступления, в запросе рекомендуется использовать соединение по полю МоментВремени. Если ваша версия платформы позволяет, во временную таблицу лучше помещать именно МАКСИМУМ(МоментВремени), а затем соединяться по нему для получения ссылки на документ и цены.

Метод 5. Учет характеристик

Если в «1С:Управлении торговлей 10.3» вы ведете учет по характеристикам (размеры, цвета), крайне важно добавить поле ХарактеристикаНоменклатуры во все группировки и условия связи запроса. Без этого система выдаст вам случайную цену одного из последних поступлений этого товара, проигнорировав разницу в характеристиках.

Важный совет по производительности: При работе с временными таблицами (пакетные запросы), всегда используйте конструкцию ИНДЕКСИРОВАТЬ ПО. Например:


ПОМЕСТИТЬ ВтДатыПоследнихПоступлений
ИНДЕКСИРОВАТЬ ПО
    Номенклатура

Это позволит SQL-серверу мгновенно выполнять левое соединение, даже если в списке на получение цен находятся десятки тысяч позиций номенклатуры.

Таким образом, мы разобрали основные подходы к получению цен последнего поступления. Наиболее быстрым и простым способом для разовой задачи является запрос к табличным частям через временные таблицы с поиском максимальной даты, а для постоянного использования в отчетах лучше настроить автоматическую регистрацию цен в регистре ЦеныНоменклатурыКонтрагентов.

← На главную