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

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

Одной из наиболее частых задач, с которой сталкиваются разработчики 1С, является получение актуальных значений из РегистрСведений на дату конкретного документа. Многие новички пытаются использовать виртуальную таблицу СрезПоследних, однако она предназначена для получения данных на одну фиксированную точку времени, переданную в параметре Период. Когда же требуется получить «срез» для каждой строки списка документов, необходимо применять иной подход.

Почему нельзя использовать виртуальную таблицу СрезПоследних

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

Алгоритм решения задачи

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

  1. Сбор дат документов: Сначала мы выбираем все документы, для которых нужно получить ответственных лиц, и сохраняем их вместе с датами во временную таблицу.
  2. Поиск максимального периода: Используя соединение с физической таблицей регистра, мы находим для каждого документа запись с максимальным значением поля Период, условие соединения при этом: РС.Период <= Документ.Дата.
  3. Финальное соединение: Получив точную дату актуальной записи для каждого документа, мы делаем финальное соединение с физической таблицей регистра уже по совпадению Период и другим измерениям (например, Организация).

Пример программного кода

Давайте проанализируем реализацию данного алгоритма на практике. Мы будем использовать конструкцию ПОМЕСТИТЬ для временных таблиц и оператор МАКСИМУМ для поиска нужной записи.


ВЫБРАТЬ 
    ОтветственныеЛицаОрганизаций.Период, 
    ОтветственныеЛицаОрганизаций.ФизическоеЛицо,
    ОтветственныеЛицаОрганизаций.Организация
ПОМЕСТИТЬ вт_руководители 
ИЗ РегистрСведений.ОтветственныеЛицаОрганизаций КАК ОтветственныеЛицаОрганизаций 
ГДЕ ОтветственныеЛицаОрганизаций.ОтветственноеЛицо = ЗНАЧЕНИЕ(Перечисление.ОтветственныеЛицаОрганизаций.Руководитель) 
; 

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

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

Важные замечания

При реализации данного запроса стоит обратить внимание на следующие аспекты:

Использование этого подхода позволяет избежать ошибок «на глазок» и получить точную картину ответственных лиц на любую дату проведения документа. Это классический навык, который требует глубокого понимания работы с временными таблицами в Запрос 1С.

← На главную