Работа с датами в 1С:Предприятие — одна из самых частых задач, с которыми сталкиваются разработчики, администраторы и даже обычные пользователи системы. Но что делать, когда дата в базе или документе внезапно оказывается «пустой»? Чем это значение отличается от NULL в SQL, как его правильно обрабатывать в запросах и почему иногда пустая дата ведёт себя неожиданно?
В этой статье мы детально разберём, чему равна пустая дата в 1С, как она представлена в разных версиях платформы (8.3, 8.2), чем опасно её неправильное использование и как избежать типичных ошибок при работе с такими значениями. Особое внимание уделим нюансам хранения в СУБД (Microsoft SQL Server, PostgreSQL, файловом варианте), а также приведём практические примеры кода для проверки и замены пустых дат.
Если вы когда-нибудь сталкивались с ошибками вроде «Ошибка при вызове метода контекста (ЗаполнитьЗначенияСвойств): Значение не является значением типа Дата» или не могли отфильтровать записи с пустыми датами в отчёте — эта статья поможет разобраться в причинах и найти решение.
Что такое пустая дата в 1С: определение и внутреннее представление
В 1С:Предприятие пустая дата — это специальное значение типа Дата, которое обозначает отсутствие даты как таковой. В отличие от NULL в SQL (который означает «значение неизвестно»), пустая дата в 1С — это конкретное значение, равное 0001-01-01 00:00:00 (1 января 1 года). Такое представление закреплено на уровне платформы и не зависит от версии или конфигурации.
Внутренне это значение хранится как минимально возможная дата, которую может обработать система. Например, если вы попытаетесь ввести в поле даты пустое значение через интерфейс, 1С автоматически подставит именно эту «нулевую» дату. Это важно понимать, потому что:
- 🔹 Пустая дата не равна
NULLв базе данных (если используется SQL-сервер). - 🔹 Она не является ошибкой — это штатное значение типа
Дата. - 🔹 В запросах 1С пустая дата обрабатывается как обычная дата, но с особыми правилами сравнения.
Пример: если вы выполните запрос вида ВЫБРАТЬ ДатаДокумента ИЗ Документ.ЗаказКлиента ГДЕ ДатаДокумента = ДАТАВРЕМЯ(1,1,1,0,0,0), то получите все записи с пустой датой. Однако такой же запрос в SQL (например, WHERE DateField = '0001-01-01') может не сработать из-за различий в хранении данных.
⚠️ Внимание: В файловом варианте 1С (без SQL-сервера) пустая дата хранится именно как 0001-01-01, но в клиент-серверном варианте с Microsoft SQL Server или PostgreSQL она может преобразовываться в NULL или другое значение в зависимости от настроек СУБД. Всегда проверяйте поведение на вашей конкретной базе!
Как пустая дата хранится в разных СУБД: SQL Server vs PostgreSQL vs файловая база
Одно из ключевых различий между вариантами работы 1С — это способ хранения пустой даты в базе данных. Рассмотрим три основных сценария:
| Вариант базы | Как хранится пустая дата | Особенности работы |
|---|---|---|
| Файловая база (1Cv8.1CD) | 0001-01-01 00:00:00 |
Полностью контролируется платформой, нет конфликтов с SQL. |
| Microsoft SQL Server | Преобразуется в NULL (по умолчанию) |
Может вызывать ошибки при прямом SQL-запросе, если не учитывать IS NULL. |
| PostgreSQL | Хранится как 0001-01-01, но может блокироваться настройками СУБД |
Требует явного разрешения на хранение дат до 1000 года в конфигурации PostgreSQL. |
Например, в Microsoft SQL Server по умолчанию даты до 1753 года не поддерживаются (из-за особенностей григорианского календаря), поэтому платформа 1С автоматически заменяет пустую дату на NULL. Это приводит к тому, что:
- 📌 В запросах 1С пустая дата сравнивается как
ДАТАВРЕМЯ(1,1,1). - 📌 В прямом SQL-запросе к базе нужно использовать
IS NULLвместо= '0001-01-01'. - 📌 При обмене данными между базами (например, через Универсальный формат обмена) пустые даты могут теряться или преобразовываться некорректно.
В PostgreSQL ситуация иная: база поддерживает даты до 1 года, но может требовать дополнительных настроек в postgresql.conf (параметр datestyle). Если эти настройки не верны, 1С не сможет записать пустую дату и выдаст ошибку.
Как проверить дату на пустоту: методы в коде 1С
В языке 1С есть несколько способов проверить, является ли дата пустой. Выбор метода зависит от контекста: работаете ли вы в модуле, запросе или отчёте. Рассмотрим основные подходы:
1. Проверка через сравнение с константой
Самый простой и надёжный способ — сравнить дату с ДАТАВРЕМЯ(1,1,1):
Если ДатаДокумента = ДАТАВРЕМЯ(1, 1, 1) Тогда
Сообщить("Дата пустая!");
КонецЕсли;
Этот метод работает во всех версиях платформы и не зависит от СУБД. Однако он может быть неудобен, если нужно проверять много полей — придётся дублировать условие.
2. Использование функции ЗначениеЗаполнено()
Функция ЗначениеЗаполнено() возвращает Ложь для пустой даты, но Пример:
Если НЕ ЗначениеЗаполнено(ДатаДокумента) Тогда
// Дата либо пустая, либо NULL в SQL
КонецЕсли;
⚠️ Внимание: В клиент-серверном варианте с Microsoft SQL Server функцияЗначениеЗаполнено()может вести себя неожиданно, если поле в базе имеет значениеNULL, а не пустую дату. Всегда уточняйте, что именно вам нужно проверить!
3. Проверка в запросах 1С
В языке запросов 1С для проверки пустой даты используется конструкция ЕСТЬ NULL или сравнение с ДАТАВРЕМЯ(1,1,1):
ВЫБРАТЬ
Номер,
ДатаДокумента
ИЗ
Документ.ЗаказКлиента
ГДЕ
ДатаДокумента = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
Однако в SQL-варианте базы лучше использовать:
ВЫБРАТЬ
Номер,
ДатаДокумента
ИЗ
Документ.ЗаказКлиента
ГДЕ
ДатаДокумента ЕСТЬ NULL
Сравнить с ДАТАВРЕМЯ(1,1,1)|Использовать ЗначениеЗаполнено() для не-SQL баз|В запросах к SQL использовать ЕСТЬ NULL|Учитывать особенности СУБД-->
Типичные ошибки при работе с пустыми датами и как их избежать
Неправильная обработка пустых дат — одна из самых распространённых причин ошибок в 1С. Рассмотрим наиболее частые проблемы и способы их решения:
1. Ошибка «Значение не является значением типа Дата»
Эта ошибка возникает, когда вы пытаетесь присвоить полю типа Дата значение, которое не является датой, например, NULL из SQL или некорректную строку. Решение:
- 🛠 Перед присвоением проверяйте тип значения с помощью
ТипЗнч(). - 🛠 Используйте
ЗначениеВТип()для безопасного преобразования:
ДатаДокумента = ЗначениеВТип(ПолученноеЗначение, Тип("Дата"));
2. Пустые даты в отчётах и диаграммах
Если в отчёте есть группировка по дате, пустые значения могут искажать результаты или вызывать ошибки. Чтобы исключить их:
- 📊 Добавляйте фильтр
ГДЕ Дата <> ДАТАВРЕМЯ(1,1,1). - 📊 Используйте конструкцию
ВЫРАЗИТЬ(Дата КАК Строка) = ""для проверки в сложных отчётах.
3. Проблемы при обмене данными
При обмене через Универсальный формат или XML пустые даты могут теряться или преобразовываться в некорректные значения. Решение:
- 🔄 Явно указывайте обработку пустых дат в правилах обмена.
- 🔄 Проверяйте данные после загрузки с помощью отчёта.
Если вы работаете с внешними системами (например, через REST API), всегда преобразуйте пустую дату 1С в null в JSON, а не передавайте её как строку "0001-01-01". Это избавит от ошибок на стороне получателя.
Как заменить пустую дату на актуальную: практические примеры
Иногда пустую дату нужно заменить на текущую, дату документа-основания или другое значение. Рассмотрим несколько сценариев:
1. Замена на текущую дату
Если поле даты пустое, можно автоматически подставить сегодняшнюю дату:
Если ДатаДокумента = ДАТАВРЕМЯ(1, 1, 1) Тогда
ДатаДокумента = ТекущаяДата();
КонецЕсли;
2. Замена на дату из другого поля
Например, если дата оплаты пустая, можно взять дату из документа-основания:
Если ДатаОплаты = ДАТАВРЕМЯ(1, 1, 1) Тогда
ДатаОплаты = ДокументОснование.Дата;
КонецЕсли;
3. Массовая замена в базе
Для массового обновления пустых дат в таблице можно использовать запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка КАК Ссылка
|ИЗ
| Документ.ЗаказКлиента
|ГДЕ
| ДатаДокумента = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Док = Выборка.Ссылка.ПолучитьОбъект();
Док.ДатаДокумента = ТекущаяДата();
Док.Записать();
КонецЦикла;
⚠️ Внимание: Массовое обновление данных может заблокировать базу и вызвать конфликты с другими пользователями. Выполняйте такие операции в нерабочее время или в транзакции с контролем ошибок!
Всегда делайте резервную копию базы перед массовыми изменениями данных, особенно если речь идёт о системных полях вроде дат документов.
Пустая дата в отчётах и СКД: как исключить или обработать
В Системе компоновки данных (СКД) пустые даты могут портить внешний вид отчётов или искажать расчёты. Рассмотрим, как с ними работать:
1. Исключение пустых дат из отчёта
В настройках отчёта добавьте фильтр:
ЭлементыФормы.Отчет.КомпоновщикНастроек.Настройки.Отбор.Добавить("ДатаДокумента");
ЭлементыФормы.Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы.Найти("ДатаДокумента").Использование = Истина;
ЭлементыФормы.Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы.Найти("ДатаДокумента").ВидСравнения = ВидСравнения.НеРавно;
ЭлементыФормы.Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы.Найти("ДатаДокумента").Значение = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0);
2. Замена пустой даты на текст в выводе
Если нужно показать вместо пустой даты текст (например, «Не указана»), используйте выражение в СКД:
ВЫРАЗИТЬ(
ЕСЛИ ДатаДокумента = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
ТОГДА "Не указана"
ИНАЧЕ ФОРМАТ(ДатаДокумента, "ДФ=dd.MM.yyyy")
КОНЕЦ
КАК Строка)
3. Пустые даты в диаграммах
В диаграммах пустые даты могут приводить к ошибкам построения. Чтобы их исключить:
- 📈 Добавьте отбор по дате в настройки диаграммы.
- 📈 Используйте параметр «Игнорировать пустые значения» (если доступен в вашей версии СКД).
Особенности пустой даты в разных версиях 1С: 8.2 vs 8.3
Хотя внутреннее представление пустой даты (0001-01-01) не изменилось, в новых версиях платформы появились дополнительные нюансы:
| Версия 1С | Особенности работы с пустой датой |
|---|---|
| 1С 8.2 | Пустая дата всегда равна ДАТАВРЕМЯ(1,1,1). Нет явной поддержки NULL в запросах. |
| 1С 8.3 (до 8.3.10) | Появилась возможность использовать ЕСТЬ NULL в запросах для SQL-баз, но поведение зависит от СУБД. |
| 1С 8.3.10 и выше | Улучшена обработка NULL в запросах, добавлены новые функции для работы с датами (НачалоДня(), КонецДня()). |
Например, в 1С 8.3.18 при работе с PostgreSQL пустая дата может корректно обрабатываться в запросах с использованием ЕСТЬ NULL, тогда как в 1С 8.2 такой синтаксис не поддерживается. Также в новых версиях улучшена совместимость с внешними системами через REST и JSON.
Если вы поддерживаете устаревшие конфигурации, учитывайте, что:
- 🔄 В 1С 8.2 нет функции
ЗначениеЗаполнено()для дат — используйте явное сравнение. - 🔄 В запросах к SQL-базе в 1С 8.2 нельзя использовать
ЕСТЬ NULL— только сравнение сДАТАВРЕМЯ(1,1,1).
FAQ: Частые вопросы о пустой дате в 1С
Почему при экспорте в Excel пустая дата становится 01.01.0001?
Это связано с тем, что 1С передаёт в Excel внутреннее представление пустой даты (0001-01-01). Excel не поддерживает даты до 1900 года, поэтому отображает её как есть. Чтобы избежать этого, замените пустую дату на пустую строку перед экспортом:
Если Дата = ДАТАВРЕМЯ(1,1,1) Тогда
ЗначениеДляExcel = "";
Иначе
ЗначениеДляExcel = Формат(Дата, "ДФ=dd.MM.yyyy");
КонецЕсли;
Можно ли в 1С сделать поле даты действительно пустым (NULL)?
В самой 1С поле типа Дата не может быть NULL — оно всегда будет содержать минимальную дату. Однако в SQL-базе (например, Microsoft SQL Server) это поле может храниться как NULL. Чтобы работать с такими значениями, используйте:
- 🔹 В запросах 1С — конструкцию
ЕСТЬ NULL. - 🔹 В коде — проверку через
ЗначениеЗаполнено()(но учитывайте нюансы для SQL).
Как в запросе 1С выбрать записи, где дата НЕ пустая?
Используйте одно из двух условий:
// Вариант 1: для любых баз
ГДЕ ДатаДокумента <> ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
// Вариант 2: для SQL-баз (более корректно)
ГДЕ НЕ ДатаДокумента ЕСТЬ NULL
Второй вариант предпочтительнее для клиент-серверных баз, так как учитывает особенности хранения NULL в SQL.
Почему после обновления 1С пустые даты стали отображаться как 01.01.1970?
Это может быть связано с:
- 🔹 Изменением настроек совместимости в новой версии платформы.
- 🔹 Ошибкой конвертации данных при обновлении базы.
- 🔹 Особенностями драйвера СУБД (например, в PostgreSQL).
Проверьте настройки хранения дат в конфигураторе (Администрирование → Поддержка → Настройки совместимости) и при необходимости выполните тестовое и исправительное обновление.
Как в отчёте СКД показать пустую дату как прочерк?
В настройках поля отчёта используйте условное оформление или выражение:
ВЫРАЗИТЬ(
ЕСЛИ ДатаДокумента = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
ТОГДА "-"
ИНАЧЕ ФОРМАТ(ДатаДокумента, "ДФ=dd.MM.yyyy")
КОНЕЦ
КАК Строка)
Либо настройте формат поля в СКД, добавив обработку пустых значений через параметр «Представление пустых значений».