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

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

Почему стандартная проверка на пустую дату не работает

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

ДатаДокумента = ''

или даже:

ДатаДокумента = NULL

Но оба этих подхода неверны и приведут к ошибкам или некорректной фильтрации. Дело в том, что в 1С пустая дата — это не пустая строка и не SQL-значение NULL, а специальный объект типа Дата со значением '00010101' (1 января 1 года). При этом:

  • 🔹 В выражениях СКД пустая дата отображается как Дата(1,1,1)
  • 🔹 При выводе в отчёт она может показываться как пустое поле или "01.01.0001" (в зависимости от настроек)
  • 🔹 Сравнение с пустой строкой или NULL всегда возвращает Ложь

Более того, даже если вы укажете явное сравнение с Дата(1,1,1), это может не сработать в некоторых контекстах из-за особенностей оптимизации запросов в СКД. Например, при использовании виртуальных таблиц или объединений условие может быть проигнорировано.

⚠️ Внимание: В некоторых конфигурациях (например, 1С:ERP или 1С:УТ 11) пустые даты могут обрабатываться иначе из-за кастомизированных механизмов. Всегда проверяйте поведение в вашей конкретной базе!

Способ 1: Проверка через функцию ЗначениеЗаполнено()

Самый надёжный и универсальный метод — использование встроенной функции ЗначениеЗаполнено(). Она работает со всеми типами данных, включая даты, и возвращает Истина, если значение не является пустым. Для проверки на пустоту условие нужно инвертировать:

НЕ ЗначениеЗаполнено(ДатаДокумента)

Примеры применения в СКД:

  • 📌 В условиях отбора на закладке "Настройки":
  • НЕ ЗначениеЗаполнено(ДатаДокумента)
  • 📌 В вычисляемых полях:
  • ВЫБОР
    

    КОГДА НЕ ЗначениеЗаполнено(ДатаДокумента) ТОГДА "Дату не указали"

    ИНАЧЕ Формат(ДатаДокумента, "ДФ=dd.MM.yyyy")

    КОНЕЦ

  • 📌 В параметрах группировки для исключения пустых дат из итогов

Преимущества этого метода:

  • 🔵 Работает во всех версиях 1С 8.x
  • 🔵 Корректно обрабатывает не только даты, но и другие типы (справочники, документы и т.д.)
  • 🔵 Не зависит от формата хранения даты в базе
⚠️ Внимание: В некоторых сложных отчётах с большим количеством объединений (ОБЪЕДИНИТЬ) функция ЗначениеЗаполнено() может снижать производительность. В таких случаях рассмотрите альтернативные способы (см. раздел про ЕстьNULL).

Убедитесь, что поле действительно содержит дату, а не строку|Проверьте регистр функции (ЗначениеЗаполнено, а не значениезаполнено)|Тестируйте на реальных данных, а не только на тестовых записях|Для виртуальных таблиц может потребоваться явное указание источника данных-->

Способ 2: Сравнение с минимальной датой

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

ДатаДокумента = Дата(1,1,1)

Этот метод особенно полезен, когда:

  • 📅 Нужно проверить пустоту в запросе (не в СКД напрямую)
  • 📅 Работаете с внешними источниками данных, где функция ЗначениеЗаполнено может не поддерживаться
  • 📅 Требуется оптимизация производительности в больших отчётах

Пример использования в вычисляемом поле СКД:

ВЫБОР

КОГДА ДатаДокумента = Дата(1,1,1) ТОГДА "Нет данных"

ИНАЧЕ ""

КОНЕЦ

Однако у этого способа есть важное ограничение: в некоторых конфигурациях (например, при работе с регистрами сведений) дата 01.01.0001 может быть легитимным значением, а не признаком пустоты. Всегда уточняйте логику хранения данных в вашей базе!

Метод Преимущества Недостатки Когда использовать
ЗначениеЗаполнено() Универсален, работает везде Может снижать производительность в сложных отчётах Стандартные отчёты, простые условия
Сравнение с Дата(1,1,1) Быстрее в некоторых случаях Может конфликтовать с реальными данными Оптимизированные отчёты, внешние источники
ЕстьNULL Оптимален для запросов Только для SQL-части Сложные запросы с объединениями

Способ 3: Использование функции ЕстьNULL в запросах

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

Синтаксис:

ВЫБРАТЬ

ЕстьNULL(ДатаДокумента, 1) КАК ПустаяДата

ИЗ

Документ.ЗаказПокупателя КАК Заказ

В этом примере функция вернёт 1, если дата пустая, и 0 — если заполнена. Для обратной логики (проверки на непустоту) используйте:

ЕстьNULL(ДатаДокумента, 0) = 0

Важные нюансы:

  • 🛠 Функция работает только в тексте запроса, а не в выражениях СКД
  • 🛠 В некоторых СУБД (например, PostgreSQL) может требовать особого синтаксиса
  • 🛠 Для виртуальных таблиц лучше комбинировать с ЗначениеЗаполнено

Пример комплексного использования в отчёте:

// В тексте запроса:

ВЫБРАТЬ

ЕстьNULL(ДатаДокумента, 1) КАК ПустаяДата,

ДатаДокумента

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

// В настройках СКД (условие отбора):

ПустаяДата = 1

💡

Если вам нужно отфильтровать пустые даты в большом отчёте, сначала попробуйте сделать это на уровне запроса с помощью ЕстьNULL — это может значительно ускорить выполнение по сравнению с фильтрацией в СКД.

Способ 4: Проверка через параметры и макросы

В некоторых сценариях удобно вынести проверку пустой даты в параметр отчёта или макрос. Это позволяет:

  • 🎛 Гибко настраивать фильтрацию без изменения схемы компоновки
  • 🎛 Переиспользовать логику в нескольких отчётах
  • 🎛 Давать пользователям возможность выбора (показывать/скрывать пустые даты)

Пример реализации:

  1. Создайте параметр отчёта типа Булево с именем ИгнорироватьПустыеДаты
  2. В настройках СКД добавьте условие отбора:
  3. 
    

    ВЫБОР

    КОГДА &ИгнорироватьПустыеДаты ТОГДА ЗначениеЗаполнено(ДатаДокумента)

    ИНАЧЕ Истина

    КОНЕЦ

  4. Настройте форму отчёта для управления параметром

Для более сложных сценариев можно использовать макросы. Например, создать макрос ПустаяДата:

#Область Макросы

// Макрос для проверки пустой даты

Макрос ПустаяДата = "НЕ ЗначениеЗаполнено(ДатаДокумента)"

#КонецОбласти

А затем применять его в выражениях:

ВЫБОР

КОГДА &ПустаяДата ТОГДА "Требует уточнения"

ИНАЧЕ ""

КОНЕЦ

Этот подход особенно полезен, когда:

  • 🔧 Логика проверки используется в нескольких местах отчёта
  • 🔧 Нужно быстро менять условие без поиска по всему коду
  • 🔧 Требуется документация прямо в схеме компоновки
📊 Какой способ проверки пустых дат вы используете чаще всего?
ЗначениеЗаполнено()
Сравнение с Дата(1,1,1)
ЕстьNULL в запросах
Параметры и макросы
Другой способ

Способ 5: Программная обработка в модуле отчёта

Когда стандартные средства СКД не справляются (например, при работе с динамическими списками или сложными алгоритмами), можно перенести логику проверки в модуль отчёта. Это даёт максимальную гибкость, но требует знания встроенного языка.

Типичные сценарии для программной обработки:

  • 💻 Динамическая фильтрация по нескольким датам одновременно
  • 💻 Сложные условия, зависящие от других параметров
  • 💻 Обработка исключений, когда пустая дата должна заменяться на текущую

Пример кода в модуле отчёта:

Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)

// Получаем данные отчёта

Данные = ДанныеРасшифровки.Данные;

// Проходим по всем строкам

Для Каждого Строка Из Данные Цикл

Если НЕ ЗначениеЗаполнено(Строка.ДатаДокумента) Тогда

Строка.ДатаДокумента = ТекущаяДата();

Строка.Примечание = "Дата была пустой, подставлена текущая";

КонецЕсли;

КонецЦикла;

СтандартнаяОбработка = Ложь;

КонецПроцедуры

Критически важно: При программной обработке больших наборов данных всегда учитывайте производительность. Например, цикл по 100 000 строк может значительно замедлить формирование отчёта. В таких случаях лучше использовать Запрос с предварительной фильтрацией.

Ещё один полезный приём — создание обработчика события "ПриКомпоновкеДанных", где можно модифицировать исходный набор данных до компоновки:

Процедура ПриКомпоновкеДанных(ЭлементыОтчёта, ДанныеРасшифровки, СтандартнаяОбработка)

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ЕстьNULL(ДатаДокумента, 1) КАК ПустаяДата,

| Документ.Номер КАК Номер

|ИЗ

| Документ.ЗаказПокупателя КАК Документ

|ГДЕ

| ЕстьNULL(ДатаДокумента, 1) = 0";

Результат = Запрос.Выполнить();

ДанныеРасшифровки.Данные = Результат.Выгрузить();

СтандартнаяОбработка = Ложь;

КонецПроцедуры

⚠️ Внимание: При программной модификации данных отчёта следите за целостностью связей между таблицами. Например, если вы фильтруете пустые даты в основной таблице, убедитесь, что связанные детализации тоже корректно обновляются.

Типичные ошибки и как их избежать

Даже опытные разработчики иногда допускают ошибки при работе с пустыми датами в СКД. Вот наиболее распространённые проблемы и способы их решения:

  • Сравнение с пустой строкой:
    ДатаДокумента = ""

    Исправление: Используйте ЗначениеЗаполнено() или сравнение с Дата(1,1,1)

  • Неучёт временной части:

    Если дата имеет тип ДатаВремя, сравнение с Дата(1,1,1) может не сработать из-за ненулевого времени.

    Исправление: Используйте НачалоДня(ДатаДокумента) = Дата(1,1,1)

  • Путаница с NULL в объединениях:

    При использовании ОБЪЕДИНИТЬ или ЛЕВОЕ СОЕДИНЕНИЕ пустые даты могут превращаться в SQL-NULL.

    Исправление: Используйте ЕстьNULL в запросе или обработку в модуле

  • Неправильная сортировка:

    Пустые даты могут отображаться в начале или конце отчёта в зависимости от настроек.

    Исправление: Явно укажите порядок сортировки: ПОРЯДОК ЗначениеЗаполнено(ДатаДокумента) УБЫВ, ДатаДокумента ВОЗР

Ещё одна распространённая проблема — некорректное отображение пустых дат в печатных формах. Например, вместо пустого поля может выводиться "01.01.0001". Чтобы этого избежать, используйте условное оформление:

ВЫБОР

КОГДА НЕ ЗначениеЗаполнено(ДатаДокумента) ТОГДА ""

ИНАЧЕ Формат(ДатаДокумента, "ДФ=dd.MM.yyyy")

КОНЕЦ

Почему пустые даты иногда игнорируются в отчётах?

В некоторых версиях 1С (особенно при работе с управляемыми формами) пустые даты могут не попадать в результат из-за оптимизации запросов. Это происходит, когда:

1. В настройках СКД включён флаг "Игнорировать пустые группы"

2. Используются виртуальные таблицы с предопределёнными отборами

3. Запрос выполняется в режиме "Для получения результата", а не "Для получения данных"

Чтобы это исправить, попробуйте:

- Явно указать условие ЗначениеЗаполнено(ДатаДокумента) = Ложь

- Перенести фильтрацию в основной запрос

- Отключить оптимизацию запросов в настройках СКД (если это допустимо по производительности)

FAQ: Частые вопросы по проверке пустых дат в СКД

Как проверить пустую дату в динамическом списке?

В динамических списках логика аналогична СКД, но есть нюансы:

  1. Для отбора используйте условие: НЕ ЗначениеЗаполнено(ДатаДокумента)
  2. Если нужно вывести замену для пустой даты, настройте условное оформление колонки
  3. Для сложных случаев создайте вычисляемое поле в настройках списка

Пример кода для вычисляемого поля:

ВЫБОР

КОГДА НЕ ЗначениеЗаполнено(ДатаДокумента) ТОГДА "Не указана"

ИНАЧЕ Формат(ДатаДокумента, "ДЛФ=DT")

КОНЕЦ

Почему условие ДатаДокумента = Дата(1,1,1) не работает в моём отчёте?

Вероятные причины:

  • Поле на самом деле содержит ДатаВремя, а не Дата → используйте НачалоДня(ДатаДокумента) = Дата(1,1,1)
  • В вашей конфигурации пустые даты хранятся иначе (например, как NULL в SQL) → проверьте через ЕстьNULL
  • Условие применяется к виртуальной таблице, где даты обрабатываются особо → перенесите фильтрацию в основной запрос

Для диагностики добавьте в отчёт колонку с выражением ТипЗнч(ДатаДокумента) — это покажет реальный тип данных.

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

Используйте многоуровневую сортировку:

  1. Добавьте вычисляемое поле: ЗначениеЗаполнено(ДатаДокумента) КАК ДатаЗаполнена
  2. В настройках сортировки укажите:
    ПОРЯДОК ДатаЗаполнена УБЫВ, ДатаДокумента ВОЗР

Это сначала выведет все непустые даты (отсортированные по возрастанию), а затем — пустые.

Можно ли в СКД проверить пустоту даты без использования функций?

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

  • Сравнение с минимальной датой: ДатаДокумента < Дата(2,1,1) (работает, потому что 01.01.0001 — самая ранняя возможная дата)
  • Проверка через строковое представление: Строка(ДатаДокумента) = "01.01.0001" (ненадёжно, зависит от локали)

Эти методы могут ломаться при изменении версий платформы или настроек региональных стандартов. Используйте их только в крайних случаях.

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

В сводных таблицах пустые даты могут искажать итоги. Решения:

  1. Исключите пустые даты из группировки: в настройках поля группировки добавьте условие ЗначениеЗаполнено(ДатаДокумента)
  2. Замените на дефолтное значение: создайте вычисляемое поле:
    ВЫБОР
    

    КОГДА НЕ ЗначениеЗаполнено(ДатаДокумента) ТОГДА Дата(2000,1,1)

    ИНАЧЕ ДатаДокумента

    КОНЕЦ

  3. Настройте условное оформление: для ячеек с пустыми датами установите серый фон или прочерк

Для корректного подсчёта итогов используйте функцию ВЫРАЗИТЬ с явным указанием типа:

ВЫРАЗИТЬ(СУММА(ЕстьNULL(СуммаДокумента, 0)) КАК Число(15,2))
💡

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