Как правильно настроить отбор по периоду для реальной таблицы регистра накопления в СКД

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

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

Зачем использовать реальную таблицу вместо виртуальной?

Прежде чем перейти к технической реализации, проанализируем ситуацию, когда нам действительно нужна реальная таблица. Виртуальные таблицы предоставляют уже агрегированные данные (готовые остатки на дату или обороты за период). Реальная же таблица содержит каждое конкретное движение (запись), сделанное документом-регистратором. Мы обращаемся к ней, когда нам необходимо:

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

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

Метод 1. Использование конструкции ГДЕ в тексте запроса

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

Проанализируем пример кода запроса:


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

Этот метод рабочий, но у него есть существенный минус для СКД: если пользователь не заполнит один из параметров в настройках отчета, запрос либо выдаст ошибку, либо вернет пустой результат (зависит от настроек обязательности параметров).

Метод 2. Расширение языка запросов (Фигурные скобки)

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

Посмотрим на правильный синтаксис:


ВЫБРАТЬ
    РегистрНакопленияТоварыНаСкладах.Период,
    РегистрНакопленияТоварыНаСкладах.Регистратор,
    РегистрНакопленияТоварыНаСкладах.Номенклатура,
    РегистрНакопленияТоварыНаСкладах.Количество
ИЗ
    РегистрНакопления.ТоварыНаСкладах КАК РегистрНакопленияТоварыНаСкладах
{ГДЕ
    (РегистрНакопленияТоварыНаСкладах.Период >= &НачалоПериода 
     И РегистрНакопленияТоварыНаСкладах.Период <= &КонецПериода)}

В этом случае, если пользователь не укажет даты, СКД просто проигнорирует этот блок ГДЕ и выберет все данные из таблицы. Это делает отчет гораздо более отказоустойчивым.

Метод 3. Использование стандартного периода для удобства пользователя

Работа с двумя отдельными датами (начало и конец) часто неудобна для конечного пользователя. Разберем, как объединить их в один удобный селектор «Стандартный период» (где можно выбрать «Этот месяц», «Прошлый квартал» и т.д.).

  1. Перейдем на вкладку Параметры в схеме компоновки данных.
  2. Создадим новый параметр с именем ПериодОтчета и типом данных СтандартныйПериод.
  3. Для существующих параметров НачалоПериода и КонецПериода установим флаг Ограничение доступности (чтобы пользователь их не видел).
  4. В поле Выражение для параметра НачалоПериода пропишем: &ПериодОтчета.ДатаНачала.
  5. В поле Выражение для параметра КонецПериода пропишем: &ПериодОтчета.ДатаОкончания.

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

Критический нюанс: Обработка границы конца периода

Выясним одну из самых частых причин «потери» данных в отчетах. Когда пользователь выбирает дату, например, 31.12.2023, система по умолчанию воспринимает это как 31.12.2023 00:00:00. Если документ был проведен в 15:00 того же дня, он не попадет в отчет, так как его время больше, чем время границы.

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

КонецПериода(&ПериодОтчета.ДатаОкончания, "ДЕНЬ")

Применяя эту функцию, мы гарантируем, что граница будет установлена на 23:59:59, и все движения последнего дня месяца будут включены в выборку.

Метод 4. Роли полей и автоматические отборы

Рассмотрим еще один способ, упомянутый в дискуссии — использование стандартного отбора СКД без прописывания условий в запросе. Если мы просто выберем поле Период в запросе, СКД позволит пользователю добавить его в настройках на вкладке «Отбор».

Однако для корректной работы «умных» механизмов СКД (например, дополнения периодов) важно правильно настроить Роль поля:

  1. На вкладке Наборы данных найдем поле Период.
  2. В колонке Роль нажмем на кнопку редактирования.
  3. Укажем тип «Период» и выберем соответствующий тип (например, День).

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

Оптимизация: Индексы и производительность

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

Особенности расчета знака суммы

Посмотрим на важное отличие реальной таблицы от виртуальной ОстаткиИОбороты. В реальной таблице нет готовых полей КоличествоПриход и КоличествоРасход. Есть только общее поле Количество и поле ВидДвижения.

Для получения корректных итогов нам нужно самостоятельно обрабатывать знак суммы. Рассмотрим пример выражения:


ВЫБОР 
    КОГДА Регистр.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) 
    ТОГДА Регистр.Количество 
    ИНАЧЕ -Регистр.Количество 
КОНЕЦ

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

Подводя итог, можно сказать, что работа с периодом в реальной таблице требует внимательности к границам времени и понимания механизмов расширения языка запросов СКД. Используя связку СтандартныйПериод + КонецПериода(..., "ДЕНЬ") + {ГДЕ ...}, вы создадите надежный и удобный для пользователя отчет.

← На главную