При разработке отчетов на системе компоновки данных (СКД) программисты часто сталкиваются с необходимостью получить данные «на начало» и «на конец» периода. Если для получения конечных данных стандартная виртуальная таблица СрезПоследних работает идеально, то с начальными данными (особенно если это самая первая запись в истории объекта, например, ввод ОС в эксплуатацию) возникают сложности. Проблема заключается в том, что виртуальной таблицы «СрезПервых» в платформе 1С не существует, а дата «начала» у каждого объекта (основного средства, сотрудника, номенклатуры) может быть своя.
В этой статье мы подробно разберем, как правильно построить запрос в СКД, чтобы получить самые ранние записи из регистра сведений, и как обойти типичные ловушки механизма автозаполнения параметров.
Поскольку готовой виртуальной таблицы для получения первых записей нет, нам необходимо обратиться к основной (физической) таблице регистра. Наша задача — найти для каждого объекта минимальную дату записи, а затем получить все остальные реквизиты, соответствующие этой дате. Разберем этот процесс по шагам.
Проанализируем ситуацию: если мы просто выберем МИНИМУМ(Период) в группировке по объекту, мы получим только дату, но не сможем вытащить значения ресурсов (например, стоимость или состояние ОС). Поэтому нам нужно соединить таблицу саму с собой.
Рассмотрим пример построения такого запроса:
ВЫБРАТЬ
ОсновныеСредства.ОсновноеСредство КАК ОС,
МИНИМУМ(ОсновныеСредства.Период) КАК ДатаПервойЗаписи
ПОМЕСТИТЬ ВТ_МинимальныеДаты
ИЗ
РегистрСведений.ОсновныеСредстваМеждународныйУчет КАК ОсновныеСредства
ГРУППИРОВАТЬ ПО
ОсновныеСредства.ОсновноеСредство
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_МинимальныеДаты.ОС КАК ОС,
ДанныеРегистра.Состояние КАК СостояниеНаНачало,
ДанныеРегистра.Стоимость КАК СтоимостьНаНачало,
ВТ_МинимальныеДаты.ДатаПервойЗаписи КАК ДатаВвода
ИЗ
ВТ_МинимальныеДаты КАК ВТ_МинимальныеДаты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ОсновныеСредстваМеждународныйУчет КАК ДанныеРегистра
ПО ВТ_МинимальныеДаты.ОС = ДанныеРегистра.ОсновноеСредство
И ВТ_МинимальныеДаты.ДатаПервойЗаписи = ДанныеRec.Период
Обратите внимание на важный нюанс: если в одну и ту же секунду по одному объекту было введено несколько записей, такое соединение приведет к дублированию строк. Чтобы этого избежать, в реальных задачах рекомендуется использовать дополнительную группировку или выбирать МИНИМУМ(НомерСтроки) или МИНИМУМ(Регистратор) во временной таблице.
Когда мы работаем внутри системы компоновки данных, она автоматически пытается управлять параметрами виртуальных таблиц. Если в вашем отчете есть стандартный период, СКД может принудительно подставить дату окончания периода в параметры запроса. Это «сломает» логику получения первой записи, так как запрос начнет искать минимальную дату не во всей истории, а только внутри выбранного пользователем интервала.
Выясним причину такого поведения: это работает механизм Автозаполнения. Чтобы получить данные на «самое начало» вне зависимости от настроек периода в отчете, нам нужно «пнуть» СКД, как выразились на форуме, — то есть явно указать, какие параметры использовать.
Рассмотрим, как правильно оформить запрос с использованием фигурных скобок, чтобы СКД не подставляла лишние условия:
ВЫБРАТЬ
Регистр.ОсновноеСредство,
Регистр.Период,
Регистр.Стоимость
ИЗ
РегистрСведений.ОсновныеСредстваМеждународныйУчет КАК Регистр
ГДЕ
(Регистр.ОсновноеСредство, Регистр.Период) В
(ВЫБРАТЬ
ВнРегистр.ОсновноеСредство,
МИНИМУМ(ВнРегистр.Период)
ИЗ
РегистрСведений.ОсновныеСредстваМеждународныйУчет КАК ВнРегистр
// Здесь мы НЕ указываем период, чтобы получить самую первую запись в истории
ГРУППИРОВАТЬ ПО
ВнReg.ОсновноеСредство)
Если же вам нужно объединить это со СрезомПоследних на дату отчета, используйте конструкцию {...} для параметров виртуальной таблицы, чтобы разделить влияние глобального периода отчета на разные части запроса.
Проанализируем еще один эффективный способ — разделение запросов на разные наборы данных. Это зачастую самый прозрачный и надежный метод для сложных отчетов.
СрезПоследних для получения текущих данных.ОсновноеСредство.Преимущество этого метода в том, что для каждого набора данных можно настроить свои правила применения параметров. Для набора с «первой записью» мы можем вообще не передавать параметр даты, тем самым заставляя систему всегда искать самую раннюю точку входа данных в базу.
Посмотрим на ситуацию с точки зрения быстродействия. Запросы к физическим таблицам регистров сведений с использованием МИНИМУМ могут работать медленно на миллионах записей. Чтобы ускорить выполнение, убедитесь, что:
ОсновноеСредство (или другое ведущее измерение) является индексированным.Для получения данных на «самую первую запись» без конкретной даты в СКД необходимо:
СрезПервых (ее нет).МИНИМУМ(Период).Регистратор, НомерСтроки).Используя эти подходы, вы сможете корректно выводить данные о вводе в эксплуатацию или начальных состояниях объектов в любых аналитических отчетах.