Не есть null в запросе 1с 8.3. Использование функции естьnull(). Пример проверки значения на NULL

Язык запросов 1С — одно из основных отличий между версиями 7.7 и 8. Одним из важнейших пунктов в изучении 1С-программирования является язык запросов. В 1С 8.3 запросы — самый мощный и эффективный инструмент получения данных. Язык запросов позволяет в удобном виде получать информацию из базы данных.

Сам синтаксис очень сильно напоминает классический T-SQL, за исключением того, что в 1С с помощью языка запросов можно только получать данные, используя конструкцию Выбрать(select). Язык поддерживает и более сложные конструкции, например, (запрос в запросе). Запросы в 1С 8 можно составлять как на кириллице, так и на латинице.

В статье я постараюсь рассказать про основные ключевые слова в языке запросов 1С:

  • выбрать
  • разрешенные
  • различные
  • выразить
  • первые
  • для изменения
  • значение
  • тип значения (и оператор ССЫЛКА)
  • выбор
  • сгруппировать по
  • имеющие
  • ЕСТЬNULL
  • Есть NULL
  • соединения — правые, левые, внутренние, полные .

А так же небольшие хитрости языка 1С, применяя которые вы сможете оптимально построить текст запроса.

Для отладки запросов в системе 1С 8.2 предусмотрен специальный инструмент — консоль запросов. Увидеть описание и скачать его можно по ссылке — .

Рассмотрим самые важные и интересные операторы языка запросов 1С.

ВЫБРАТЬ (SELECT)

В языке запросов 1С предприятия 8 любой запрос начинается с ключевого слова ВЫБРАТЬ . В языке 1С нет конструкций UPDATE, DELETE, CREATE TABLE, INSERT, эти манипуляции производятся в объектной технике. Предназначение его — только чтение данных.

Например:

ВЫБРАТЬ
ТекущийСправочник.Наименование
ИЗ
Справочник.Номенклатура КАК ТекущийСправочник

Запрос вернёт таблицу с наименованиями номенклатуры.

Рядом с конструкцией ВЫБРАТЬ можно встретить ключевые слова ДЛЯ ИЗМЕНЕНИЯ , РАЗРЕШЕННЫЕ , РАЗЛИЧНЫЕ , ПЕРВЫЕ

РАЗРЕШЕННЫЕ — выбирает только записи из таблицы, на которые есть права у текущего пользователя.

РАЗЛИЧНЫЕ — означает, что в результат не попадет дублирующих строк.

ВЫБОР (CASE)

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

ТекущийСправочник.Наименование,

КОГДА ТекущийСправочник.Услуга ТОГДА

«Услуга»

КОНЕЦ КАК ВидНоменклатуры

Справочник.Номенклатура КАК ТекущийСправочник

Пример возвратит в поле «ВидНоменклатуры» текстовое значение — «Товар» или «Услуга».

ГДЕ (WHERE)

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

ВЫБРАТЬ
Справочник.Наименование
ИЗ
ТекущийСправочник.Номенклатура КАК ТекущийСправочник
ГДЕ ТекущийСправочник.Услуга = ИСТИНА

В примере мы отбираем записи, у которых значение реквизита «Услуга» установлено в положение «Истина». В данном примере можно было бы обойтись и таким условием:

«ГДЕ Услуга»

По сути, мы отбираем строки, у которых выражение после ключевого слова равно «Истина».

В выражениях можно использовать прямые условия:

ГДЕ Код = «005215»

С помощью оператора «ЗНАЧЕНИЕ()» в условиях использовать обращение к предопределенным элементам и перечислениям в запросе 1С:

ГДЕ ТипНоменклатуры= Значение(Перечисление.ТипыНоменклатуры.Товар)

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

ГДЕ ДатаПоступления > ДАТАВРЕМЯ(2012,01,01):

Чаще всего условия указываются в виде параметров, передаваемых в запрос:

Получите 267 видеоуроков по 1С бесплатно:

ГДЕ НоменклатурнаяГруппа= &НоменклатурнаяГруппа

Условие можно наложить на тип реквизита, если он составного типа:

Если необходимо ограничивать отбор из списка значений или массива, можно поступить следующим образом:

ГДЕ РегистрНакопления.Регистратор В (&СписокДокументовДляОтбора)

Условие может быть и сложное, состоящее из нескольких условий:

ГДЕ ДатаПоступления > ДАТАВРЕМЯ(2012,01,01) И НоменклатурнаяГруппа= &НоменклатурнаяГруппа И НЕ Услуга

СГРУППИРОВАТЬ ПО (GROUP BY)

Конструкция языка запросов 1С 8.2, используемая для группировки результата.

Например:

ВЫБРАТЬ
ПоступлениеТоваровУслугTовары.Товар,
СУММА(ПоступлениеТоваровУслугTовары.Количество) КАК Количество,
СУММА(ПоступлениеТоваровУслугTовары.Сумма) КАК Сумма
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугTовары

СГРУППИРОВАТЬ ПО
ПоступлениеТоваровУслугTовары.Товар

Данный запрос просуммирует все поступления по сумме и количеству в разрезе номенклатуры.

Помимо ключевого слова СУММА можно использовать другие агрегатные функции: КОЛИЧЕСТВО , КОЛИЧЕСТВО РАЗНЫХ , МАКСИМУМ , МИНИМУМ , СРЕДНЕЕ .

ИМЕЮЩИЕ (HAVING)

Конструкция, о которой часто забывают, но она очень важна и полезна. Она позволяет указать отбор в виде агрегатной функции, этого нельзя сделать в конструкции ГДЕ .

Пример использования ИМЕЮЩИЕ в запросе 1С:

ВЫБРАТЬ
ПоступлениеТоваровУслугТовары.Товар,
СУММА(ПоступлениеТоваровУслугТовары.Количество) КАК Количество,
СУММА(ПоступлениеТоваровУслугТовары.Сумма) КАК Сумма
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары

СГРУППИРОВАТЬ ПО
ПоступлениеТоваровУслугТовары.товар

СУММА(ПоступлениеТоваровУслугТовары.Количество) > 5

Так мы отберем количество товаров, которых поступило более 5 штук.

ЗНАЧЕНИЕ()

Например:

ГДЕ Банк = Значение(Справочник.Банки.ПустаяСсылка)

ГДЕ ВидНоменклатуры = Значение(Справочник.ВидыНоменклатуры.Товар)

ГДЕ ТипНоменклатуры= Значение(Перечисление.ТипыНоменклатуры.Услуга)

ТИП в запросе

Тип данных можно проверить следующим образом: с помощью функций ТИП() и ТИПЗНАЧЕНИЯ() или с помощью логического оператора ССЫЛКА.

ВЫРАЗИТЬ()

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

Синтаксис: ВЫРАЗИТЬ(<Выражение> КАК <Тип значения>)

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

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

ВЫБРАТЬ
КонтактнаяИнформация.Объект,
ВЫРАЗИТЬ(КонтактнаяИнформация.Представление КАК СТРОКА(150)) КАК Представление
ИЗ
РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация

СГРУППИРОВАТЬ ПО
ВЫРАЗИТЬ(КонтактнаяИнформация.Представление КАК СТРОКА(150)),
КонтактнаяИнформация.Объект

ЕСТЬNULL (ISNULL)

Достаточно полезная функция языка запросов 1С, которая проверяет значение в записи, и если оно равно NULL, то позволяет заменить на своё значение. Чаще всего используется при получении виртуальных таблиц остатков и оборотов, чтобы скрыть NULL и поставить понятный 0 (ноль).

ЕСТЬNULL(НалогиПредМесяца.ПримененнаяЛьготаФСС, 0)

Такая функция языка запросов 1С ЕСТЬNULL при отсутствии значения вернет ноль, что позволит избежать ошибки.

СОЕДИНЕНИЕ (JOIN)

Соединения бывают 4 типов: ЛЕВОЕ , ПРАВОЕ , ПОЛНОЕ, ВНУТРЕННЕЕ .

ЛЕВОЕ и ПРАВОЕ СОЕДИНЕНИЕ

Соединения используются для связи двух таблиц по определенному условию. Особенность при ЛЕВОМ СОЕДИНЕНИИ в том, что мы берём первую указанную таблицу полностью и привязываем по условию вторую таблицу. Поля второй таблицы, которые не удалось привязать по условию, заполняются значением NULL .

Пример левого соединения в запросе 1С:

Вернет всю таблицу и заполнит поле «Банк» лишь в тех местах, где будет соблюдаться условие «Контрагенты.Наименование = Банки.Наименование». Если условие не соблюдается, в поле Банк будет установлено NULL .

ПРАВОЕ СОЕДИНЕНИЕ в языке 1С 8.3 абсолютно аналогично ЛЕВОМУ соединению , за исключением одного отличия: в ПРАВОМ СОЕДИНЕНИИ «главная» таблица — вторая, а не первая.

ПОЛНОЕ СОЕДИНЕНИЕ

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

Например:

ПОЛНОЕ СОЕДИНЕНИЕ
Справочник.Банки КАК Банки

ПО

Язык запросов вернет обе таблицы полностью лишь по выполненному условию Соединить записи. В отличие от левого/правого соединения возможно появления NULL в двух полях.

ВНУТРЕННЕЕ СОЕДИНЕНИЕ

ВНУТРЕННЕЕ СОЕДИНЕНИЕ отличается от полного тем, что выводит только те записи, которые смогли соединить по заданному условию.

Например:

ИЗ
Справочник.Контрагенты КАК Клиенты

ВНУТРЕННЕЕ СОЕДИНЕНИЕ
Справочник.Банки КАК Банки

ПО
Клиенты.Наименование = Банки.Наименование

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

Заключение

Это лишь небольшая часть синтаксиса из языка запросов 1С 8, в дальнейшем я попробую рассмотреть более подробно некоторые моменты, показать и многое другое!

NULL – это не что иное, как отсутствие значения. Многие путают его со значением «0» типа число, пустой ссылкой на какой-либо объект или же с пустой строкой. Из-за этого заблуждения возникает много ошибок.

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

Основан на SQL, который не позволяет проверять на значение NULL обычным равенством. Ниже описаны два способа проверки на NULL в 1С 8.3.

Функция языка запросов 1С 8.3 ЕСТЬNULL() имеет два входных параметра:

  • проверяемое выражение;
  • выражение замены.

Если проверяемое значение будет NULL, то эта функция вернет значение выражения замены. Если же значение будет отлично от NULL, то вернется само проверяемое выражение.

Ниже рассмотрен пример. В нем выбираются все номенклатурные позиции табличной части товара из документа «Поступление товаров и услуг». При помощи левого соединения каждой номенклатуре проставляется последняя цена из регистра сведений «Цены номенклатуры».

В данном случае может возникнуть такая ситуация, что для какой-либо позиции может просто не быть цены в регистре. В таком случае функция ЕСТЬNULL вернет нам привычный ноль. Если ей не воспользоваться, то при попытке произвести арифметические операции над полем «Цена» со значением NULL мы получим ошибку.

ВЫБРАТЬ

ЕСТЬNULL(Цены.Цена, 0) КАК АктуальнаяЦена
ИЗ



ГДЕ

ЕСТЬ NULL в операторе ВЫБОР

Аналогом функции ЕСТЬNULL() является «ЕСТЬ NULL», которая используется в операторе ВЫБОР и проверяет, является ли значение NULL. «ЕСТЬ» в данном случае подразумевает равенство и запрос предыдущего примера будет выглядеть следующим образом:

ВЫБРАТЬ
Товары.Номенклатура КАК Товар,
ВЫБОР
КОГДА Цены.Цена ЕСТЬ NULL
ТОГДА 0
ИНАЧЕ Цены.Цена
КОНЕЦ КАК АктуальнаяЦена
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ПО Товары.Номенклатура = Цены.Номенклатура
ГДЕ
Товары.Ссылка = &СсылкаНаДокумент

Отличия функции ЕСТЬNULL() от ЕСТЬ NULL

Как вы могли увидеть из предыдущих примеров, в обоих случаях запрос возвращает одни и те же данные. Функция ЕСТЬNULL() является сокращенным вариантом ВЫБОР КОГДА … ЕСТЬ NULL … КОНЕЦ, но она все же будет предпочтительнее по следующим причинам:

  1. Функция EСТЬNULL() оптимизирует запрос. Она считывается один раз, поэтому при проверке сложного выражения, запрос отработает быстрее.
  2. Функция EСТЬNULL() сокращает конструкцию, за счет чего запрос становится более читабельным.
  3. При выполнении функции EСТЬNULL() выражение замены приводится к типу проверяемого выражения для типов строковых типов (к длине строки) и числовых (к разрядности).

NULL – отсутствующие значения.
Не путать с нулевым значением! NULL – это не число, не равно пробелу, пустой ссылке, Неопределено.

NULL – типообразующее значение, т.е. есть тип NULL и единственное значение этого типа.

NULL значения появляются в запросе в следующих ситуациях:
а) Внешнее соединение, при котором не было найдено соответствующей записи в другой таблице (при левом – во второй, при правом – в первой, при полном – в обоих)
б) Обращение к реквизитам элементов для группы и наоборот.
в) NULL в списке полей выборки (ВЫБРАТЬ)
г) Обращение к реквизитам для битой ссылки

ЕСТЬ NULL используется в операторе ВЫБРАТЬ (как бы проверя, что значение это есть пустое (Значение ЕСТЬ NULL)):
Код 1C v 8.х
ВЫБОР
КОГДА Значение ЕСТЬ NULL ТОГДА РезультатЕслиNULL
ИНАЧЕ Значение
КОНЕЦ

еще пример:
Код 1C v 8.х ВЫБРАТЬ

ВЫБОР КОГДА УчетНоменклатурыОстатки.КоличествоОстаток ЕСТЬ NULL ТОГДА 0
ИНАЧЕ УчетНоменклатурыОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ



ГДЕ

Функция ЕСТЬNULL (значение, РезультатЕслиNULL) возвращает значение своего первого параметра, в случае если он не равен NULL, и значение второго параметра в противном случае
Является свернутым ВЫБОР…КОНЕЦ, но ЕСТЬNULL предпочтительнее.
Код 1C v 8.х
ВЫБРАТЬ
ЕСТЬNULL(Справочник.Номенклатура.Артикул, "---") КАК Артикул,
Справочник.Номенклатура.Представление КАК Номенклатура

еще пример:
Код 1C v 8.х
ВЫБРАТЬ
СправочникНоменклатуры.Наименование,
ЕСТЬNULL(УчетНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
ИЗ
Справочник.Номенклатура КАК СправочникНоменклатуры
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.УчетНоменклатуры.Остатки КАК УчетНоменклатурыОстатки
ПО УчетНоменклатурыОстатки.Номенклатура = СправочникНоменклатуры.Ссылка
ГДЕ
СправочникНоменклатуры.ЭтоГруппа = ЛОЖЬ
В данном примере получаются все элементы справочника номенклатуры, после чего, для каждой номенклатуры из регистра накопления получаются текущие остатки. Т.к. для номенклатуры, по которой отсутствуют остатки, виртуальная таблица остатков не запись вернет, то в результате соединения в поле "УчетНоменклатурыОстатки.КоличествоОстаток" будут значения NULL для номенклатуры, по которой не было остатков. Для того чтобы вместо значения NULL в результате запроса присутствовало значение 0, мы использовали функцию ЕСТЬNULL(), которая осуществит желаемую замену.

ЕСТЬNULL отличается от ВЫБОР по следующим причинам:
а) При ЕСТЬNULL лучше читается запрос (проще)
б) При ЕСТЬNULL, если проверяется сложное выражение, то работает быстрее, поскольку вычисляется один раз
в) При ЕСТЬNULL выражение замены приводится к типу проверяемого выражения, если оно имеет тип Строка (длина) или Число (разрядность).

Нельзя проверять значения на NULL обычным равенством, потому что в SQL действует трехзначная логика – Истина, Ложь, NULL, и результатом такого сравнения будет UNKNOWN, что в 1С 8.0 аналогично ЛОЖЬ.
NULL <> 0, поэтому при левых внешних соединениях спр. Номенклатура с таблицами остатков, цен, Контрагентов со взаиморасчетами при отсутствии таких записей там будет NULL, который не равен 0. Лучшее решение – ЕСТЬNULL

Функция ЕСТЬNULL(английский синоним ISNULL) используется для подмены нулевого(отсутствующего) значения при соединениях таблиц. Таблицы могут быть произвольными (как совпадающими по полям).

Null — это не число 0, а именно отсутствующее значение.

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

Быстрый переход

Результат ее выполнения:

  • Значение определенного типа, если оно существует.
  • Указанное вторым параметром значение (любого типа).

Синтаксис ISNULL

ЕстьNULL(<ПроверяемоеПоле>,<ЗначениеЗамены>)

Аналогом этой функции может быть конструкция:
ВЫБОР
КОГДА Таблица.Поле1 ЕСТЬ NULL ТОГДА "Некое значение"
ИНАЧЕ
Таблица.Поле1
КОНЕЦ

Как на практике используется ЕстьNULL

1. Подмена значения константой
ЕСТЬNULL(Таблица1.Поле1,"Некое значение")

ЕСТЬNULL(Таблица1.Количество, 0)

2. Подмена значения параметром

ЕСТЬNULL(Таблица1.Поле1,&Параметр)

3. Подмена значением из другой таблицы

ЕСТЬNULL (Таблица1.Поле1,Таблица2.Поле1)

4.Использование функции для получения предопределенного или пустого значения

ЕСТЬNULL(Таблица2.Поле1,ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка))

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

Функция ЕСТЬNULL

В языке запросов реализована функция ЕСТЬNULL(), предназначение которой - заменять выражение на другое выражение в случае, если выражения имело значение NULL. Синтаксическая диаграмма данной функции выглядит так:

ЕСТЬNULL(<Проверяемое выражение>, <Выражение замены>)

Данная функция вернет значение первого параметра, в случае, если оно не является NULL, и значение второго выражения, в противном случае.


ВЫБРАТЬ
ЕСТЬNULL(УчетНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
ИЗ

ГДЕ

В данном примере получаются все элементы справочника номенклатуры, после чего, для каждой номенклатуры из регистра накопления получаются текущие остатки. Т.к. для номенклатуры, по которой отсутствуют остатки, виртуальная таблица остатков не запись вернет, то в результате соединения в поле "УчетНоменклатурыОстатки.КоличествоОстаток" будут значения NULL для номенклатуры, по которой не было остатков. Для того чтобы вместо значения NULL в результате запроса присутствовало значение 0, мы использовали функцию ЕСТЬNULL(), которая осуществит желаемую замену.

Использование операции ВЫБОР

Для решения описанной ранее задачи можно воспользоваться операцией языка запросов ВЫБОР. Пример, как будет выглядеть запрос, аналогичный предыдущему, будет выглядеть так:


ВЫБРАТЬ
СправочникНоменклатуры.Наименование,
ВЫБОР КОГДА УчетНоменклатурыОстатки.КоличествоОстаток ЕСТЬ NULL ТОГДА 0
ИНАЧЕ УчетНоменклатурыОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
Справочник.Номенклатура КАК СправочникНоменклатуры
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.УчетНоменклатуры.Остатки КАК УчетНоменклатурыОстатки
ПО УчетНоменклатурыОстатки.Номенклатура = СправочникНоменклатуры.Ссылка
ГДЕ
СправочникНоменклатуры.ЭтоГруппа = ЛОЖЬ

Результат данного запроса будет идентичен результату запроса, приведенного в предыдущем разделе.

Использование функции ЕСТЬNULL() предпочтительней использования операции ВЫБОР по следующим причинам: запись с использованием ЕСТЬNULL() несколько компактней, что повышает читабельность запроса. Кроме того, в случае, когда проверяемое выражение является сложной функцией, в том числе агрегатной функцией, вычисление функции ЕСТЬNULL() может выполняться быстрей чем аналог, записанный с использованием функции ВЫБОР.

Особенности функции ЕСТЬNULL

Функция ЕСТЬNULL() хоть и является аналогом операции ВЫБРАТЬ с проверкой значения на NULL, тем не менее, имеет отличие. Отличие заключается в том, что в случае, если выражение функции имеет строковой или числовой тип, то выражение замены будет преобразовано к типу проверяемого выражения.

Так, например, в случае когда проверяемое выражение имеет тип Строка(5), а выражение замены тип Строка(10), тип результата будет преобразован к типу Строка(5). В результате, когда функция будет возвращать выражение замены, значение будет обрезано до пяти символов.

С числовыми выражениями ситуация аналогична: значение заменяемого выражения будет преобразовано к типу проверяемого, т.е. заменяемое выражение может быть обрезано. В случае если значение не может быть преобразовано, язык запросов закончит выполнение запроса с ошибкой. Например, с ошибкой закончится попытка преобразования числа 1000 в тип Число(2).