• Проверить пустую дату запросе 1с. Работа с пустыми значениями в запросе

    У всех документов, существующих в конфигурациях 1С, а, следовательно, и практически у всех регистров обязательно должен быть хотя бы один реквизит с типом Дата, именно поэтому каждому разработчику необходимо знать и понимать:

    • Как выполнять преобразования параметров других типов к рассматриваемому типу;
    • Как определить пустую дату в запросе 1С;
    • Чем отличается дата и граница времени.

    Именно на эти вопросы мы и постараемся ответить в нашей статье.

    Что такое дата и как ее определить

    Так как для принятия большинства управленческих решений и ведения учета не требуется точность времени, превышающая 1 секунду, разработчики платформы 1С решили, что именно эта величина будет предельным минимумом в формате даты. Таким образом, каждая реквизит, описывающий время события в программе должен содержать:

    • Год, когда произошло событие;
    • Месяц этого события;
    • День.

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

    Существующие в мире форматы даты имеют существенное различие:

    1. В России мы привыкли на первое место ставить день, затем идет месяц события, в конце – год;
    2. Жители США начинают дату с месяца;
    3. Чехи, поляки и словенцы записывают период в формате «Год – Месяц – День».

    Именно последний формат и использует платформа 1С.

    Преобразование к дате

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

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

    Важно понимать, что год даты должен содержать четыре цифры, включая тысячелетие и век события, месяц, день, часы и секунды – должны иметь длину в два символа, включая лидирующие нули.

    Отсчет времени в программе идет от начала дня 1 января 0001 года. Для приведенного выше кода это значение можно определить одним из двух способов (Рис. 2).

    Рис. 2

    Во второй строке мы опустили часы, минуты и секунды события, что нисколько не повлияло на работоспособность нашего кода.

    Особенности использования даты в запросах 1С

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

    Важно понять, что даже если в значении реквизита формы, имеющем рассматриваемый тип, не указано никаких цифр, то есть окно имеет вид (Рис. 3), это не означает что в нем ничего не указано, сравнение этого параметра с пустой строкой не пройдет.

    Рис. 3

    Получив пустую дату, мы можем указать ее в качестве параметра к нашему запросу, то есть использовать конструкцию (Рис. 4)

    Однако, существуют моменты, когда проверку лучше проводить внутри текста запроса, не передавая пустую дату в качестве параметра. Для этого в коде запроса можно ввести соответствующее условие (Рис. 5) и использовать функцию запроса ДатаВремя().

    Рис. 5

    В приведенном тексте запроса мы опустили лидирующие нули у года, месяца и дня, а так же не указали часов, минут и секунд и программа, что называется, скушала это допущение.

    Дата и граница времени

    Еще один интересный факт, касающийся соотношения запросов и даты – это использование понятия «момент времени» при обращении к различным таблицам базы данных.

    Точность «до миллисекунды», указанная в технической документации при описании примитивного типа Дата ярче всего проявляется при выборке записей из виртуальных таблиц регистра накопления: если у регистра накопления помимо таблицы Обороты, существуют таблицы Остатки и ОстаткиИОбороты, то выборка по ним, осуществленная на определенное время, может дать различные результаты.

    Для того чтобы понять, как и почему это происходит, рассмотрим простой пример:

    1. До проведения в 12 часов 31 минуту 36 секунд документа реализации остатки по номенклатуре Сахар составляли 30 кг;
    2. Документом в указанное время было списано 10 кг;
    3. Отчет, формируемый на дату документа на 12 часов 31 минуту 36 секунд по таблице Остатки, покажет остаток 30кг;
    4. Тот же самый отчет по таблице ОстаткиИОбороты на то же самое время покажет остаток в 20 кг.

    В чем же причина подобного поведения и как этого избежать?

    Проблема в том, что в таблице Остатки период задается открытым отрезком, то есть, движения, осуществленные на момент времени формирования отчета не берутся в расчет, то есть время берется на начало указанной в параметре секунды. В то же самое время, для таблицы Оборотов и для таблицы ОстаткиИОбороты границы времени берутся в расчет то есть время берется на конец указанной секунды.

    Выходов из этой ситуации несколько:

    1. При использовании таблицы Остатки, указывать момент времени на 1 секунду больший, чем заданный;
    2. Использовать только таблицу ОстаткиИОбороты (не самый оптимальный с точки зрения производительности вариант);
    3. Использовать понятие Граница.

    Последний вариант можно представить кодом, указанном на Рис. 6.

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

    В ходе работы с запросами любому программисту приходится так или иначе взаимодействовать с пустыми значениями. Что мы понимаем под пустым значением?

    Пустое значение – это или отсутствие значения, или значение по умолчанию для типа данных. С примитивными типами все довольно просто: значением по умолчанию является некое начальное значение, служащее точкой отсчета.

    Виды пустых значений

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

    • Для типа Число – пустым значением является ноль – 0.
    • Для типа Строка – пустая строка – «».
    • Для типа Дата – первое января первого года – 01.01.0001 00:00:00. Именно с этой даты ведется отсчет времени в 1С.*
    • Для типа Булево – значением по умолчанию, технически, является Ложь, но логически оба значения типа являются заполненными. Поэтому принятие решения о том пустое значение Ложь или нет, основывается на логике конкретного алгоритма.

    *Будьте внимательны, вне 1С существуют различные системы счисления дат с разными точками отсчета.

    Отсутствующее значение в полном смысле соответствует только типу Null. Этот тип содержит лишь одно значение, которое обозначает отсутствие значения.

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

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

    Работа с пустыми значениями в запросе

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

    Типы Число, Строка, Булево описываются в запросе как во встроенном языке:

    ВЫБРАТЬ 0 КАК ПримерТипаЧисло, "Привет мир" КАК ПримерТипаСтрока, Истина КАК ПримерТипаБулево

    Неопределено, являясь по существу примитивным типом, описывается аналогично:

    Выбрать Партии.Период Из РегистрНакопления.Партии Как Партии Где Остатки.ДокументПартии = Неопределено

    Пустые ссылочные значения определяются немного сложнее. У всех ссылочных объектов предусмотрено предопределенное служебное значение ПустаяСсылка. Благодаря этому есть возможность единым способом выбрать пустую ссылку – через функцию Значение:

    Выбрать Значение (Справочник.Номенклатура.ПустаяСсылка) Как Пустая Номенклатура

    Возможности работы со значениями типа Null несколько богаче. Как и другие примитивные типы, Null описывается так же, как во встроенном языке. Помимо этого, предусмотрены специальный оператор Есть Null и функция ЕстьNull.

    • Оператор Есть Null позволяет создать логическое выражение сравнивающее выбранное значение со значением Null.
    • Функция ЕстьNull возвращает первый аргумент, если он не равен Null, и второй аргумент в обратном случае.

    Выражения, определяющие пустые значения, можно использовать в любых разделах запроса поддерживающих выражения. Например, вы можете добавить пустую ссылку в секцию Выбрать или проверку на Null в Условие.

    Практические примеры

    С использованием функции Значение

    Выбрать Товары.Ссылка Как Номенклатура, Товары.Ссылка = Значение(Справочник.Номенклатура.ПустаяСсылка) Как ЭтаСсылкаПустая Из втТовары Как втТовары

    С использованием оператора Есть Null

    Выбрать Товары.Ссылка Как Номенклатура, Товары.Ссылка Есть Null Как ЭтаСсылкаПустая Из втТовары Как втТовары

    Null при левом или полном соединении

    Проверка на Null

    Пример демонстрирует частую практическую ситуацию, когда при левом соединении, для первой таблицы не находится соответствия во второй. В этом случае все поля второй таблицы будут равны Null.

    Выбрать втТовары.Ссылка Как Номенклатура, Остатки.КоличествоОстаток Как Количество, Остатки.КоличествоОстаток Есть Null Как НетОстатка Из втТовары как втТовары Левое Соединение РегистрНакопления.ТоварыНаСкладах.Остатки Как Остатки По втТовары.Ссылка = Остатки.Номенклатура

    Обработка Null-значений

    Модификация предыдущего запроса для демонстрации часто встречающейся методики по получению каких-либо значений по умолчанию, взамен отсутствующих. В данном примере с использованием функции ЕстьNull, производится замена отсутствующего значения остатка, на логически правильное 0.

    Выбрать втТовары.Ссылка Как Номенклатура, ЕстьNull (Остатки.КоличествоОстаток, 0) Как Количество Из втТовары как втТовары Левое Соединение РегистрНакопления.ТоварыНаСкладах.Остатки Как Остатки По втТовары.Ссылка = Остатки.Номенклатура

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

    В этой статье будут рассмотрены способы проверки на пустое значение в зависимости от типа проверяемого реквизита в , в том числе пустой ссылки.

    Значение NULL возвращается в том случае, когда реквизита попросту нет. Тип в этом случае будет тоже NULL. Например, вы объединяете две таблицы через левое соединение. В том случае, когда для левой таблицы не будет найдено ни одного значения в правой, вернется NULL.

    Проверку на данное значение можно осуществить при помощи конструкции «ЕСТЬ NULL» и « ». В первом случае возвращается Истина или Ложь. Во втором случае можно сразу задать другое значение в том случае, когда возвращается NULL.

    В приведенном ниже запросе 1С 8.3 будут возвращен список контактных лиц тех партнеров, у кого не задан сегмент.

    ВЫБРАТЬ
    КонтактныеЛицаПартнеров.Ссылка
    ИЗ
    Справочник.КонтактныеЛицаПартнеров КАК КонтактныеЛицаПартнеров
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СегментыПартнеров КАК СегментыПартнеров
    ПО КонтактныеЛицаПартнеров.Владелец = СегментыПартнеров.Родитель
    ГДЕ
    СегментыПартнеров.Ссылка ЕСТЬ NULL

    Пустая дата

    Проверка значения на пустую дату производится путем сравнения с конструкцией ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0). Пример использования приведен ниже:

    Пустая ссылка в запросе 1С

    В случае, когда возвращаемый реквизит имеет ссылочный тип, например, это элемент какого-либо справочника, документа и т. п., используется следующая конструкция: ЗНАЧЕНИЕ(Справочник.ИмяСправочника.ПустаяСсылка).

    В приведенном ниже примере запрос выбирает всех партнеров, у которых не указан бизнес-регион.

    Чтобы проверить на «ЗначениеЗаполнено» нужно сделать обратное условие:

    Партнеры.БизнесРегион <> ЗНАЧЕНИЕ(Справочник.БизнесРегионы.ПустаяСсылка)

    Пустая строка

    Для проверки строковых типов производится сравнение с другим образцом. В данном случае – «».

    Приведенный ниже запрос отберет всех партнеров с незаполненным наименованием.

    При работе с датами 1С, типовой порядок частей даты – год, месяц, день, час, минуты, секунды. При этом часы, минуты, секунды можно пропустить.

    При создании даты из строки («приведение к дате») можно указать в локализованном формате (день.месяц.год часы:минуты:секунды), но только полностью.

    Например:
    //Работа с датами 1С - преобразовать дату в 1С из частей - год, месяц, день (плюс необязательно время)
    Дата = Дата(2012,10,30); //без времени
    Дата = Дата(2012,10,30,12,00,00); //со временем

    //Работа с датами 1С - преобразовать дату в 1С из строки, разные способы
    Дата = Дата("20121030"); //год, месяц, день
    Дата = Дата("30.10.2012 12:00:00"); //локализованный формат, только полностью

    //Работа с датами 1С - указание значения даты без приведения, напрямую
    Дата = "20121030"; //без времени
    Дата = "20121030120000"; //со временем

    Работа с датами 1С — Пустая дата 1С

    Чтобы проверить дату 1С на заполненность – ее сравнивают с «пустой датой». При наличии в справочнике/документе реквизита с типом дата, если пользователь не заполнил это поле, то ее значение также будет – «пустая дата».

    «Пустая дата» — это 01.01.0001 00:00:00.

    Например:
    ПустаяДата = "00010101000000";
    Если НужнаяДата = "00010101000000" Тогда
    Сообщить("Вы не заполнили очень нужную дату");
    КонецЕсли;

    Работа с датами 1С — Дата в реквизитах (справочников, документов и т.п.)

    При указании типа реквизита можно указать использовать:

    • Только дату (время тогда всегда равно 00:00:00)
    • Только время (дата тогда всегда равна 01.01.0001)
    • Дату и время

    Получение даты

    Для получения даты и времени используется функция 1С ТекущаяДата().

    Очень важно место – где вызывается эта функция – на клиенте или на сервере. Подробнее см. тему «Режим исполнения/Исполнение». Часто бывает, что на клиентских машинах время немного разное, поэтому стараются везде использовать серверное время – даже если оно установлено на сервере не верно, то хотя бы у всех клиентов будет одинаковое неверное время.

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

    //вызов этой функции для использования из другого модуля выглядит так
    ДокументОбъект.Дата = СерверныеФункции.ПолучитьДатуСервера(); //ИмяМодуля.ИмяФункции()

    Также в тонком клиенте непосредственно у функций модулей указывается где она будет исполнена:

    Начало и конец дня

    Для даты «30.10.2012»:

    • дата начала дня выглядит так «30.10.2012 00:00:00»
    • дата конца дня выглядит так «30.10.2012 23:59:59»

    Используется в отчетах и запросах, требующих получить данные за период – день, месяц, год.

    Так например период с «01.01.2012 00:00:00» по «31.01.2012 00:00:00» неверен, так как не включает в себя один день месяца (но включает в себя одну секунду последнего дня месяца).

    Работа с датами 1С — Сравнение дат

    Дата содержит дату и время. При сравнении дат (без учета времени) их обычно приводят к началу дня (месяца, года).

    Например:
    Дата1 = Дата("30.10.2012 12:00:00");
    Если НачалоДня(Дата1) = НачалоДня(ДокументСсылка.Дата) Тогда
    Сообщить("Документ введен заданной датой");
    КонецЕсли;

    На всякий случай, пример сравнения даты в периоде:
    Если ДокументСсылка.Дата >= НачалоМесяца(ТекущаяДата()) и
    ДокументСсылка.Дата

    Работа с датами 1С - Изменение даты

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

    Например:
    СНачалаДня = ТекущаяДата() – НачалоДня(ТекущаяДата());
    Сообщить("С начала дня прошло " + Строка(СНачалаДня) + " секунд");
    Сообщить("С начала дня прошло " + Строка(СНачалаДня/60) + " минут");
    Сообщить("С начала дня прошло " + Строка(СНачалаДня/60/60) + " часов");

    Также мы можем изменить дату, при изменении мы добавляем или отнимаем количество секунд:
    НачалоЭтогоДня = НачалоДня(ТекущаяДата());

    НачалоПредыдущегоДня = НачалоДня(НачалоЭтогоДня – 1); //убираем секунду – делая «вчера» и берем начало дня у «вчера»

    НачалоПредыдущегоДня = НачалоЭтогоДня – 24*60*60; //другой способ – отнимаем 24 часа – 24(часа)*60(получились минуты)*60(секунды)

    Работа с датами 1С - Момент времени

    Момент времени – это расширенное представление даты, применимое к документам (и соответственно регистрам).

    Оно требуется для сравнения времени документов, если дата и время документов одно и то же. Соответственно его можно использовать при отборах в запросах.

    Момент времени можно получить у документа следующими способами:
    //способ 1
    МоментВремениДокумента = ДокументСсылка.МоментВремени();

    Также можно сравнить момент времени с датой/временем:
    МоментВремениЭталон = Новый МоментВремени(НачалоДня(ТекущаяДата()));
    Если ДокументСсылка.МоментВремени().Сравнить(МоментВремениЭталон) = -1 Тогда
    Сообщить("Документ введен раньше, чем сегодня");
    КонецЕсли;
    //Если документ введен сегодняшней датой в 00:00:00, то он все равно введен - сегодня

    Работа с датами 1С - Форматирование дат