Как правильно получить цену из последнего документа поступления в 1С?

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

В процессе разработки отчетов в 1С часто возникает задача получить актуальную цену товара на дату продажи, опираясь на данные из разных документов прихода (например, поставки из РФ и КНР). При попытке реализовать это «в лоб» через прямое соединение табличных частей, разработчики часто сталкиваются с критическим падением производительности системы. Давайте разберем, почему это происходит и как правильно организовать такой запрос.

Почему ваш запрос может «вешать» базу?

Основная проблема заключается в попытке выполнения ЛЕВОЕ СОЕДИНЕНИЕ всей таблицы РеализацияТоваровУслуг.Товары с таблицами поступлений напрямую. Когда вы используете СГРУППИРОВАТЬ ПО по большому количеству полей, система выполняет избыточные операции. Попытка перебрать миллионы строк документов для каждой записи реализации создает «декартово произведение», которое перегружает сервер базы данных. Мы должны стремиться к минимизации объема обрабатываемых данных на каждом этапе.

Пошаговое решение задачи с использованием временных таблиц

Чтобы избежать зависания системы, рекомендуется использовать механизм пакетных запросов и временных таблиц. Рассмотрим алгоритм действий:

  1. Получение номенклатуры: Сначала выберем только ту номенклатуру, которая участвовала в реализациях за нужный период, и поместим её во временную таблицу.
  2. Сбор поступлений: Создадим вторую временную таблицу, куда соберем все данные о поступлениях из всех документов (РФ и КНР) с помощью объединения ОБЪЕДИНИТЬ ВСЕ.
  3. Поиск максимума: Отдельно вычислим МАКСИМУМ(Дата) для каждой номенклатуры из временной таблицы поступлений.
  4. Финишное соединение: Соединим полученные данные, чтобы получить цену из конкретного документа с последней датой.

Пример реализации кода

Разберем, как может выглядеть структура такого запроса. Обратите внимание, что сначала мы изолируем данные в ПОМЕСТИТЬ, чтобы снизить нагрузку:


ВЫБРАТЬ 
    РеализацияТовары.Номенклатура, 
    РеализацияТовары.Цена КАК ЦенаРеализации
ПОМЕСТИТЬ ВТ_Реализации
ИЗ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары
ГДЕ РеализацияТовары.Ссылка.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания;

ВЫБРАТЬ 
    ПоступлениеТовары.Ссылка КАК СсылкаПоступление, 
    ПоступлениеТовары.Ссылка.Дата КАК ДатаПоступление, 
    ПоступлениеТовары.Номенклатура,
    ПоступлениеТовары.Цена
ПОМЕСТИТЬ ВТ_ВсеПоступления
ИЗ Документ.ПоступлениеТоваровРФ.Товары КАК ПоступлениеТовары
ГДЕ ПоступлениеТовары.Ссылка.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ 
    ПоступлениеКНР.Ссылка, 
    ПоступлениеКНР.Ссылка.Дата, 
    ПоступлениеКНР.Номенклатура,
    ПоступлениеКНР.Цена
ИЗ Документ.ПоступлениеТоваровКНР.Товары КАК ПоступлениеКНР;

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

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

Важные рекомендации по оптимизации

Если данные в вашей базе значительно увеличиваются, обратите внимание на следующие советы:

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

← На главную