Как получить дату первого прихода товара в 1С:УПП 8.2 через запрос

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

В процессе разработки отчетов в системе 1С:Управление производственным предприятием (УПП) часто возникает задача определить дату первого поступления номенклатуры на склад. Это может потребоваться для анализа оборачиваемости, вычисления срока жизни товара или контроля складских запасов. Рассмотрим подробно, как правильно составить запрос к регистрам накопления, чтобы получить корректную дату первого прихода, и разберем типичные ошибки, которые могут замедлить работу системы.

Разграничение понятий: Первый приход или Дата партии в остатке

Прежде чем приступать к написанию кода, проанализируем ситуацию и определимся, что именно мы подразумеваем под «первым приходом». В контексте 1С существует две принципиально разные задачи:

  1. Самый первый приход за всю историю: Нам нужно найти дату самого раннего документа с видом движения Приход, который когда-либо фиксировался в базе для данного товара. При этом текущий остаток этого товара может быть нулевым.
  2. Дата самого старого товара из текущего остатка: Если мы ведем партионный учет по FIFO, нам может потребоваться дата документа оприходования, который сформировал текущий остаток. В УПП это реализовано через измерение ДокументОприходования.

Вариант 1: Использование агрегатной функции МИНИМУМ

Самый простой и эффективный способ найти дату первого прихода — обратиться к таблице движений (оборотов) регистра накопления ПартииТоваровНаСкладах (или его бухгалтерского аналога) и использовать агрегатную функцию МИНИМУМ. Рассмотрим пример запроса:


ВЫБРАТЬ
    ПартииТоваров.Номенклатура КАК Товар,
    ПартииТоваров.Склад КАК Склад,
    МИНИМУМ(ПартииТоваров.Период) КАК ДатаПервогоПрихода
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваров
ГДЕ
    ПартииТоваров.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
    И ПартииТоваров.Номенклатура = &ВашаНоменклатура
СГРУППИРОВАТЬ ПО
    ПартииТоваров.Номенклатура,
    ПартииТоваров.Склад

В данном примере мы фильтруем записи по виду движения Приход. Использование функции МИНИМУМ(Период) позволяет движку базы данных быстро найти самое раннее значение. Обратите внимание, что мы используем группировку по аналитике (Номенклатура, Склад), чтобы получить результат в разрезе мест хранения.

Вариант 2: Получение даты первого прихода из текущих остатков

В конфигурации 1С:УПП 1.3, если используется классический партионный учет, в регистре остатков есть измерение ДокументОприходования. Это позволяет нам узнать дату поступления тех товаров, которые физически находятся на складе прямо сейчас. Посмотрим на этот пример:


ВЫБРАТЬ
    ПартииОстатки.Номенклатура,
    ПартииОстатки.Склад,
    МИНИМУМ(ПартииОстатки.ДокументОприходования.Дата) КАК ДатаПартии
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&Период, ) КАК ПартииОстатки
СГРУППИРОВАТЬ ПО
    ПартииОстатки.Номенклатура,
    ПартииОстатки.Склад

Преимущество этого метода: Виртуальная таблица Остатки работает значительно быстрее, чем сканирование всех движений регистра за несколько лет. Если вам нужно вывести дату поступления в отчете по остаткам, используйте именно этот подход.

Разбор типичной ошибки: Соединение с основной таблицей регистра

Проанализируем ситуацию из сообщения №13 в обсуждении. Автор пытается соединить виртуальную таблицу ОстаткиИОбороты с физической таблицей того же регистра. Это классическая ошибка, которая приводит к критическому снижению производительности.

Почему так делать нельзя:

Оптимизация: Работа через временные таблицы

Для создания быстрого отчета, объединяющего текущие остатки и даты первых приходов, рекомендуем использовать Временные Таблицы. Разберем этот процесс по шагам:

Шаг 1: Получаем список товаров с остатками


ВЫБРАТЬ
    Остатки.Номенклатура КАК Номенклатура,
    Остатки.Склад КАК Склад,
    Остатки.КоличествоОстаток КАК Остаток
ПОМЕСТИТЬ ВТ_Остатки
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&МоментВремени, ) КАК Остатки
ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Склад
;

Шаг 2: Получаем минимальные даты прихода только для этих товаров


ВЫБРАТЬ
    Движения.Номенклатура,
    Движения.Склад,
    МИНИМУМ(Движения.Период) КАК ДатаПервогоПрихода
ПОМЕСТИТЬ ВТ_ПервыеДаты
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах КАК Движения
ГДЕ
    Движения.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
    И (Движения.Номенклатура, Движения.Склад) В (ВЫБРАТЬ Номенклатура, Склад ИЗ ВТ_Остатки)
СГРУППИРОВАТЬ ПО
    Движения.Номенклатура,
    Движения.Склад
;

Шаг 3: Соединяем данные в итоговый результат


ВЫБРАТЬ
    ВТ_Остатки.Номенклатура,
    ВТ_Остатки.Склад,
    ВТ_Остатки.Остаток,
    ВТ_ПервыеДаты.ДатаПервогоПрихода
ИЗ
    ВТ_Остатки КАК ВТ_Остатки
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ПервыеДаты КАК ВТ_ПервыеДаты
    ПО ВТ_Остатки.Номенклатура = ВТ_ПервыеДаты.Номенклатура
    И ВТ_Остатки.Склад = ВТ_ПервыеДаты.Склад

Важные технические нюансы

При реализации задачи стоит учитывать специфические моменты платформы 1С:

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

← На главную