Работа с датами в системе компоновки данных (СКД) — одна из самых частых задач при разработке отчётов в 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: Проверка через параметры и макросы
В некоторых сценариях удобно вынести проверку пустой даты в параметр отчёта или макрос. Это позволяет:
- 🎛 Гибко настраивать фильтрацию без изменения схемы компоновки
- 🎛 Переиспользовать логику в нескольких отчётах
- 🎛 Давать пользователям возможность выбора (показывать/скрывать пустые даты)
Пример реализации:
- Создайте параметр отчёта типа
Булевос именемИгнорироватьПустыеДаты - В настройках СКД добавьте условие отбора:
- Настройте форму отчёта для управления параметром
ВЫБОР
КОГДА &ИгнорироватьПустыеДаты ТОГДА ЗначениеЗаполнено(ДатаДокумента)
ИНАЧЕ Истина
КОНЕЦ
Для более сложных сценариев можно использовать макросы. Например, создать макрос ПустаяДата:
#Область Макросы
// Макрос для проверки пустой даты
Макрос ПустаяДата = "НЕ ЗначениеЗаполнено(ДатаДокумента)"
#КонецОбласти
А затем применять его в выражениях:
ВЫБОР
КОГДА &ПустаяДата ТОГДА "Требует уточнения"
ИНАЧЕ ""
КОНЕЦ
Этот подход особенно полезен, когда:
- 🔧 Логика проверки используется в нескольких местах отчёта
- 🔧 Нужно быстро менять условие без поиска по всему коду
- 🔧 Требуется документация прямо в схеме компоновки
Способ 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: Частые вопросы по проверке пустых дат в СКД
Как проверить пустую дату в динамическом списке?
В динамических списках логика аналогична СКД, но есть нюансы:
- Для отбора используйте условие:
НЕ ЗначениеЗаполнено(ДатаДокумента) - Если нужно вывести замену для пустой даты, настройте условное оформление колонки
- Для сложных случаев создайте вычисляемое поле в настройках списка
Пример кода для вычисляемого поля:
ВЫБОР
КОГДА НЕ ЗначениеЗаполнено(ДатаДокумента) ТОГДА "Не указана"
ИНАЧЕ Формат(ДатаДокумента, "ДЛФ=DT")
КОНЕЦ
Почему условие ДатаДокумента = Дата(1,1,1) не работает в моём отчёте?
Вероятные причины:
- Поле на самом деле содержит
ДатаВремя, а неДата→ используйтеНачалоДня(ДатаДокумента) = Дата(1,1,1) - В вашей конфигурации пустые даты хранятся иначе (например, как
NULLв SQL) → проверьте черезЕстьNULL - Условие применяется к виртуальной таблице, где даты обрабатываются особо → перенесите фильтрацию в основной запрос
Для диагностики добавьте в отчёт колонку с выражением ТипЗнч(ДатаДокумента) — это покажет реальный тип данных.
Как в СКД сделать так, чтобы пустые даты отображались последними?
Используйте многоуровневую сортировку:
- Добавьте вычисляемое поле:
ЗначениеЗаполнено(ДатаДокумента) КАК ДатаЗаполнена - В настройках сортировки укажите:
ПОРЯДОК ДатаЗаполнена УБЫВ, ДатаДокумента ВОЗР
Это сначала выведет все непустые даты (отсортированные по возрастанию), а затем — пустые.
Можно ли в СКД проверить пустоту даты без использования функций?
Технически да, но это не рекомендуется. Альтернативные способы:
- Сравнение с минимальной датой:
ДатаДокумента < Дата(2,1,1)(работает, потому что 01.01.0001 — самая ранняя возможная дата) - Проверка через строковое представление:
Строка(ДатаДокумента) = "01.01.0001"(ненадёжно, зависит от локали)
Эти методы могут ломаться при изменении версий платформы или настроек региональных стандартов. Используйте их только в крайних случаях.
Как обработать пустую дату в сводной таблице СКД?
В сводных таблицах пустые даты могут искажать итоги. Решения:
- Исключите пустые даты из группировки: в настройках поля группировки добавьте условие
ЗначениеЗаполнено(ДатаДокумента) - Замените на дефолтное значение: создайте вычисляемое поле:
ВЫБОРКОГДА НЕ ЗначениеЗаполнено(ДатаДокумента) ТОГДА Дата(2000,1,1)
ИНАЧЕ ДатаДокумента
КОНЕЦ
- Настройте условное оформление: для ячеек с пустыми датами установите серый фон или прочерк
Для корректного подсчёта итогов используйте функцию ВЫРАЗИТЬ с явным указанием типа:
ВЫРАЗИТЬ(СУММА(ЕстьNULL(СуммаДокумента, 0)) КАК Число(15,2))
Для надёжной проверки пустых дат в СКД всегда используйте ЗначениеЗаполнено() или ЕстьNULL в запросах. Сравнение с Дата(1,1,1) может давать ложные срабатывания в некоторых конфигурациях, особенно при работе с регистрами сведений или внешними источниками данных.