Как настроить период для произвольного реквизита в СКД и рассчитать количество просроченных документов

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

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

Задача 1. Связывание произвольного реквизита даты со «Стандартным периодом»

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

Рассмотрим по шагам, как это реализовать наиболее эффективным образом.

Шаг 1. Подготовка запроса в схеме компоновки данных

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


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

Этот запрос ожидает на входе два параметра: &ДатаНачала и &ДатаОкончания. Однако напрямую выводить их пользователю неудобно — заполнять две даты вручную занимает много времени.

Шаг 2. Настройка параметров на вкладке «Параметры» СКД

Перейдем на вкладку Параметры в конструкторе схемы компоновки данных. Система автоматически добавила туда параметры ДатаНачала и ДатаОкончания. Наша цель — связать их в один удобный элемент управления. Выполним следующие настройки:

  1. Добавим новый параметр вручную, нажав на кнопку «Добавить» (плюс). Назовем его Период.
  2. В колонке Тип для нового параметра выберем значение СтандартныйПериод.
  3. В строке параметра ДатаНачала в колонке Выражение пропишем связь с началом стандартного периода: &Период.ДатаНачала.
  4. В строке параметра ДатаОкончания в колонке Выражение пропишем выражение с приведением к концу дня (это критически важно!): КонецПериода(&Период.ДатаОкончания, "ДЕНЬ").
  5. Для параметров ДатаНачала и ДатаОкончания установим флажок в колонке Ограничение доступности. Это скроет их от пользователя на форме настроек, чтобы они не путали его.
  6. Для параметра Период, напротив, снимем флажок ограничения доступности и при необходимости установим флажок «Быстрый доступ», чтобы параметр сразу отображался в шапке отчета.

Важное примечание по поводу конца дня: Если вы укажете в выражении окончания периода просто &Период.ДатаОкончания, то время этой границы установится в значение 00:00:00. Это приведет к тому, что все документы, выписанные в последний день периода в течение дня (например, в 12:00 или 18:00), не попадут в отчет. Использование функции КонецПериода гарантирует корректный захват всего последнего дня выбранного интервала.

Альтернативный вариант: Использование расширения языка запросов СКД

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


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

Благодаря фигурным скобкам СКД сама проанализирует, заполнен ли параметр Период. Если он пуст, условие фильтрации будет бесследно удалено из конечного SQL-запроса к базе данных, и отчет сформируется без ошибок.

---

Задача 2. Подсчет количества документов по булевому реквизиту

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

У начинающих разработчиков часто возникает мысль: «Давайте добавим в сам документ новый реквизит с типом Число, будем при проведении документа записывать туда 1, если он просрочен, и 0 в противном случае, а потом просто просуммируем его в отчете». Это классический пример архитектурной ошибки («костыля»). Изменение структуры метаданных ради одного отчета усложняет поддержку конфигурации, увеличивает размер базы данных и требует написания лишнего кода для обновления этого реквизита при изменении данных документа.

Выясним, как решить эту задачу правильно исключительно средствами СКД.

Способ А. Вычисление числового значения непосредственно в запросе

Самый простой и распространенный путь — переложить задачу преобразования типов на СУБД с помощью конструкции языка запросов ВЫБОР. Изменим наш запрос СКД следующим образом:


ВЫБРАТЬ
    Док.Ссылка КАК Ссылка,
    Док.ДатаВыписки КАК ДатаВыписки,
    Док.Просрочен КАК Просрочен,
    ВЫБОР
        КОГДА Док.Просрочен = ИСТИНА
            ТОГДА 1
        ИНАЧЕ 0
    КОНЕЦ КАК КоличествоПросроченных
ИЗ
    Документ.НашДокумент КАК Док

Теперь у нас появилось новое числовое поле КоличествоПросроченных. Настроим агрегацию этих полей на вкладке Ресурсы нашей СКД:

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

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

Способ Б. Расчет в ресурсах без изменения текста запроса

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

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

Сумма(Выбор Когда Просрочен Тогда 1 Иначе 0 Конец)

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

Способ В. Вычисляемые поля СКД

Если мы хотим отделить логику вычислений от ресурсов и запроса, мы можем воспользоваться вкладкой Вычисляемые поля в конструкторе СКД:

  1. Перейдем на вкладку «Вычисляемые поля».
  2. Добавим новую строку. Зададим имя пути к данным: КоличествоПросрочено.
  3. В поле Выражение напишем: Выбор Когда Просрочен Тогда 1 Иначе 0 Конец.
  4. После этого перейдем на вкладку Ресурсы и добавим наше новое вычисляемое поле в список ресурсов с функцией Сумма(КоличествоПросрочено).

Этот подход невероятно удобен при работе с нетиповыми или сложными отчетами, так как исходный SQL-запрос к базе данных остается максимально простым и читаемым, а вся логика трансформации данных наглядно сосредоточена в настройках компоновки.

---

Резюме и рекомендации по разработке

Разрабатывая отчеты в системе 1С, всегда стремитесь разделять слой хранения данных и слой их представления:

← На главную