Как рассчитать максимальную дату в группировке СКД, если часть дат пустые?

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

Приветствуем всех разработчиков 1С! При проектировании сложных отчетов в Системе компоновки данных (СКД) мы регулярно сталкиваемся с задачами, которые выходят за рамки стандартного суммирования или поиска максимума. Типичный пример — необходимость рассчитать контрольные сроки по задачам сотрудников.

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

Стандартная агрегатная функция Максимум(ДатаВыполнения) в данном случае вернет наибольшую из заполненных дат, полностью проигнорировав тот факт, что по одной из строк работа еще продолжается. Это происходит потому, что в платформе 1С пустая дата (01.01.0001 00:00:00) физически является минимально возможным значением и всегда меньше любой реальной даты.

Давайте подробно разберем, как решить эту задачу красиво, производительно и без перегрузки СУБД лишними временными таблицами.

Способ 1. Использование комбинации функций МИНИМУМ и МАКСИМУМ в выражении ресурса

Этот способ является наиболее изящным и простым в реализации. Он не требует абсолютно никаких изменений в тексте запроса и работает напрямую на уровне механизма ресурсов СКД. Разберем его логику.

Поскольку пустая дата является минимальной, при наличии хотя бы одной невыполненной задачи функция Минимум(ДатаВыполнения) по группировке сотрудника обязательно вернет пустую дату — 01.01.0001. Если же все задачи закрыты, то минимальное значение будет вполне реальной датой, отличной от пустой.

Перейдем на вкладку Ресурсы в СКД и для нашего поля-ресурса пропишем следующее выражение:


Выбор 
    Когда Минимум(ДатаВыполнения) = ДатаВремя(1, 1, 1) 
        Тогда ДатаВремя(1, 1, 1) 
    Иначе Максимум(ДатаВыполнения) 
Конец

Проанализируем работу этого выражения по шагам:

  1. Система анализирует все детальные записи, входящие в текущую группировку по сотруднику.
  2. Вычисляется функция Минимум(ДатаВыполнения). Если среди дат затесалась пустая, условие Когда срабатывает, и СКД возвращает пустую дату для всей группировки.
  3. Если незакрытых задач нет (все даты заполнены), управление переходит к ветке Иначе, и СКД корректно возвращает самую позднюю (максимальную) дату выполнения.

Способ 2. Условный подсчет пустых дат через СУММА

Если вам по какой-то причине неудобно использовать сравнение через минимум, или логика требует более наглядного подсчета незаполненных строк, можно прибегнуть к математическому подсчету признаков пустых дат. Нам нужно определить, есть ли в текущей группировке строки, у которых дата равна 01.01.0001.

Для этого в выражении ресурса на вкладке Ресурсы применим следующую формулу:


Выбор 
    Когда Сумма(Выбор Когда ДатаВыполнения = ДатаВремя(1, 1, 1) Тогда 1 Иначе 0 Конец) > 0 
        Тогда ДатаВремя(1, 1, 1) 
    Иначе Максимум(ДатаВыполнения) 
Конец

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

Способ 3. Преобразование в NULL и сравнение количества записей

Этот подход базируется на фундаментальном свойстве агрегатных функций SQL и СКД: функции МАКСИМУМ и КОЛИЧЕСТВО полностью игнорируют значения типа NULL.

Для реализации этого метода нам потребуется сделать два простых шага:

Шаг 1. В тексте запроса СКД преобразуем пустую дату в значение NULL:


ВЫБОР 
    КОГДА ТаблицаЗадач.ДатаВыполнения = ДАТАВРЕМЯ(1, 1, 1) 
        ТОГДА NULL 
    ИНАЧЕ ТаблицаЗадач.ДатаВыполнения 
КОНЕЦ КАК ДатаВыполнения

Шаг 2. На вкладке Ресурсы настроим логику сравнения количества записей. Мы сравним общее число задач сотрудника с числом задач, у которых заполнена дата выполнения:


Выбор 
    Когда Количество(Задача) > Количество(ДатаВыполнения) 
        Тогда ДатаВремя(1, 1, 1) 
    Иначе Максимум(ДатаВыполнения) 
Конец

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

Способ 4. Расчет в сложных иерархических отчетах

Иногда структура отчета усложняется дополнительными уровнями группировок. Например, если у нас есть иерархия Подразделение -> Сотрудник -> Задача, и нам требуется, чтобы на уровне подразделения также корректно "всплывала" пустая дата при наличии хотя бы одного незавершенного дела у любого из сотрудников.

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


Максимум(ВычислитьВыражениеСГруппировкойМассив("Выбор Когда ДатаВыполнения = ДатаВремя(1,1,1) Тогда ДатаВремя(1,1,1) Иначе ДатаВыполнения Конец", "Сотрудник"))

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

Полезный лайфхак: Настройка эстетичного отображения пустой даты

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

Рассмотрим, как правильно скрыть пустую дату:

  1. Откроем свойства поля ресурса (или вычисляемого поля) на вкладке Наборы данных или перейдем в настройки Условного оформления на уровне отчета.
  2. Найдем параметр Формат и в открывшемся конструкторе формата введем строку:

ДФ=dd.MM.yyyy; ДП=''

Параметр ДФ задаст красивый вывод реальных дат (например, 25.10.2026), а параметр ДП='' (две одинарные кавычки) скажет системе компоновки данных о том, что при обнаружении пустой даты 01.01.0001 ячейку в отчете нужно оставить абсолютно чистой. Это сделает ваш отчет презентабельным и удобным для конечного пользователя.

Используйте предложенные варианты в зависимости от сложности вашей схемы компоновки данных, чтобы создавать быстрые, функциональные и красивые отчеты в 1С!

← На главную