1с тип значения в запросе
В языке запросов 1С часто требуется проверить: является ли значение пустой ссылкой.
Пустая ссылка — это такое значение ссылочных объектов, когда оно имеет этот же тип, но само значение не выбрано.
На языке программирования 1С данное значение можно получить через менеджеры объекта.
- Перечисления.Пол.ПустаяСсылка(),
- Справочники.Организации.ПустаяСсылка(),
- ПланыСчетов.Хозрасчетный.ПустаяСсылка(),
- ПредопредленноеЗначение(«ПланСчетов.Хозрасчетный.ПустаяСсылка»)
Альтернативой сравнению с пустой ссылкой имеется метод Пустая() у значения ссылочного типа:
Например:
булКонтрагентВыбран = ВыбКонтрагент.Пустая();
Как же в запросе 1С сравнить на пустое значение
Для этого у нас есть несколько вариантов в зависимости от требований задачи:
1.Если требуется получить значение пустого типа.
Воспользуемся функцией ЗНАЧЕНИЕ()
Выбрать
ЗНАЧЕНИЕ (Перечисление.Пол.ПустаяСсылка)//Без вопроса в единственном числе
Либо через переданный в запрос параметр:
Выбрать
&ПустойПараметрНужногоТипа
2. Если требуется сравнить со значением не составного типа:
Выбрать
Значение(Перечисление.Пол.ПустаяСсылка)<>Значение(Перечисление.Пол.Мужской) как ЭтоБулевоИстина
Выбрать
Выбор когда &ПустойПараметрНужногоТипа ИЛИ Значение(Перечисление.Пол.Мужской) Тогда Истина Иначе Ложь Конец как ЭтоНеЖенскийПол
3. Если требуется проверка составного значения:
В этом случае значение
- может быть неопределенного типа (очищено или ни разу не выбрано)
- пустой ссылкой любого из типов (выбран тип, но не выбрано значение)
- выбранным значением любого из типов (выбрано значение)
В этом случае обычно первые два варианта считаются пустым значением, но пустыми ссылками являются только вторые.
//Мы инициализировали массив заполненных значений и сравнили его с пустым
Выбор когда ЗНАЧЕНИЕ(Значение(Перечисление.Пол.ПустаяСсылка) в (Значение(Перечисление.Пол.Мужской),Значение(Перечисление.Пол.Женский)) ИЛИ Есть NULL Тогда Истина Иначе Ложь конец ЗначениеПустое
//Мы инициализировали массив пустых ссылок и проверили вхождение в него нашего «неизвестного» значения
Выбор когда ЗНАЧЕНИЕ(Значение(Перечисление.Пол.Мужской) в (Значение(Перечисление.Пол.ПустаяСсылка),Значение(Справочник.Контрагенты.ПустаяСсылка)) Тогда Истина Иначе Ложь конец ЗначениеПустое
Также мы можем передать массив параметром
Выбрать Выбор когда ЗНАЧЕНИЕ(Значение(Перечисление.Пол.ПустаяСсылка) в (&МассивВсехПустыхСсылок) Тогда Истина Иначе Ложь конец ЗначениеПустое
Как получить значение ЛюбаяСсылка?
Еще про перечисление в запросе 1С.
Реклама — виновница того, что народ выбрал себе в вожди Гитлера. Реклама призвана убеждать граждан, что ситуация нормальна, когда она катастрофически ненормальна.
— Фредерик Бегбедер
Войдите как ученик, чтобы получить доступ к материалам школы
Язык запросов 1С 8.3 для начинающих программистов: функции и операторы для работы с типами (ТИПЗНАЧЕНИЯ, ТИП, ССЫЛКА, ЕСТЬNULL, ВЫРАЗИТЬ)
Автор уроков и преподаватель школы: Владимир Милькин
Давайте вспомним, что каждый реквизит (свойство, поле) справочника, документа или любого другого прикладного объекта имеет свой тип . И этот тип мы можем посмотреть в конфигураторе:
В языке запросов существует целый класс функций и операторов для работы с типами реквизитов. Давайте рассмотрим их.
Функция ТИПЗНАЧЕНИЯ
Эта функция принимает один параметр (значение) и возвращает его тип. Для описанного на картинке (выше) реквизита Вкус справочника Еда вернётся следующее:
Если мы запросим тип поля Наименование, то, как и ожидается, получим Строка:
А теперь давайте рассмотрим реквизит ОтличительныйПризнак у справочника Города:
Вы видите, что этот реквизит может иметь один из нескольких типов: Строка, Справочник.Вкусы, Справочник.Цвета. Такой тип реквизитов называется СОСТАВНЫМ .
Если мы попытаемся заполнить значение такого реквизита в режиме 1С:Предприятие, то система спросит нас, какого типа будет вводимое значение:
И только после нашего выбора позволит ввести значение выбранного типа.
Таким образом, элементы справочника одного вида (Справочник.Города) смогут хранить в одном и том же реквизите (ОтличительныйПризнак) значения разных типов (Строка, Цвета или Вкусы).
Вы можете убедиться в этом сами пощёлкав по элементам справочника Города в режиме 1С:Предприятие. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Здесь значение отличительного признака является элементом справочника Вкусы:
А здесь вообще элементом справочника Цвета:
Вот какие возможности открывает перед нами составной тип данных!
Интересно, как поведёт себя функция ТИПЗНАЧЕНИЯ на реквизите ОтличительныйПризнак, имеющий составной тип данных:
Это уже очень интересно. Давайте разбираться с каждой строкой в отдельности.
Тип значения отличительного признака для элемента Россия равен NULL. Мы впервые сталкиваемся с этим типом. Значения данного типа используются исключительно для определения отсутствующего значения при работе с базой данных.
Так и есть, ведь элемент Россия является группой, а не обычным элементом справочника Города, поэтому у него отсутствует поле ОтличительныйПризнак. А тип у отсутствующего значения, как мы прочитали выше, всегда равен NULL.
Тип значения отличительного признака для Перми равен Вкусы. Так и есть, ведь значение отличительного признака забитое в базе для города Пермь является ссылкой на элемент справочника Вкусы.
Для Красноярска тип признака равен Цвета, потому что значение выбранное в базе является ссылкой на элемент справочника Цвета.
Для Воронежа тип признака равен Строка, потому что значение введенное в базе является обычной строкой.
Индия снова группа, поэтому значение отсутствует. А тип у отсутствующего значения, как мы помним, равен NULL.
Далее всё аналогично, кроме Сан-Паулу. Это не группа, а обычный элемент справочника (город), но тип его значения пустой. Как так?
А дело вот в чём. Если вы зайдёте в элемент справочника Города с наименованием Сан-Паулу, то увидите, что поле ОтличительныйПризнак совершенно никак не заполнено. Оно пустое. А все незаполненные поля составного типа имеют специальное значение НЕОПРЕДЕЛЕНО .
С НЕОПРЕДЕЛЕНО мы также сталкиваемся впервые.
Значение НЕОПРЕДЕЛЕНО применяется, когда необходимо использовать пустое значение, не принадлежащее ни к одному другому типу. Это как раз наша ситуация.
А тип для значения, которое не принадлежит ни к одному из типов, как вы уже наверное догадались отсутствует.
Функция ТИП
Она принимает всего один параметр - имя примитивного типа (СТРОКА, ЧИСЛО, ДАТА, БУЛЕВО), либо имя таблицы, тип ссылки которой нужно получить.
Результатом данной конструкции будет значение типа Тип для указанного типа.
Звучит туманно, не правда ли?
Давайте рассмотрим применение данной конструкции и всё сразу станет на свои места.
Пусть нам требуется отобрать все записи справочника Города, у которых составной реквизит ОтличительныйПризнак имеет значение типа СТРОКА:
Теперь давайте отберём все записи, у которых значения реквизита ОтличительныйПризнак являются ссылками на элементы справочника Цвета (таблица Справочник.Цвета):
Отступление
Как вы помните, некоторые элементы справочника Города не имеют реквизита ОтличительныйПризнак. Функция ТИПЗНАЧЕНИЯ для таких элементов выдаёт NULL.
Как можно сделать отбор таких элементов в запросе? Для этого предусмотрен специальный логический оператор ЕСТЬ NULL (не путать с функцией ЕСТЬNULL, которую мы рассмотрим ниже). Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Вот пример его использования:
Но есть и такие элементы (Сан-Паулу), у которых реквизит ОтличительныйПризнак (составного типа) просто не заполнен и равен специальному значению НЕОПРЕДЕЛЕНО.
Чтобы отобрать такие записи следует использовать другую конструкцию:
Но сравнение с НЕОПРЕДЕЛЕНО для определения пустых (не заполненных) реквизитов будет работать только для составных типов.
Кстати, у логического оператора ЕСТЬ NULL форма отрицания выглядит следующим образом:
Логический оператор ССЫЛКА
Оператор ССЫЛКА позволяет проверить, является ли значение выражения, указанного слева от него, ссылкой на таблицу , указанную справа.
К примеру, давайте выберем из справочника Города только те записи, у которых значение составного реквизита ОтличительныйПризнак являются ссылкой на элемент справочника Вкусы:
Как вы помните, эту же задачу мы могли бы решить используя ТИПЗНАЧЕНИЯ и ТИП:
Функция ЕСТЬNULL
Функция предназначена для замены значения NULL на другое значение.
Мы помним, что значение NULL возвращается в том случае, если запрашиваемый реквизит (поле, свойство) не существует.
Как например, реквизит ОтличительныйПризнак для групп справочника Города:
Функция ЕСТЬNULL поможет нам вывести другое значение в том случае, если это значение равно NULL. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Пусть в данном случае это будет строка "Такого реквизита нет!":
Получается, что если первый параметр функции ЕСТЬNULL не равен NULL, то возвращается он. Если же он равен NULL, то возвращается второй параметр.
Функция ВЫРАЗИТЬ
Эта функция предназначена только для полей , имеющих составной тип . Отличным примером такого поля является свойство ОтличительныйПризнак у элементов справочника Города.
Как мы помним, составные поля могут быть одного из нескольких типов, указанных в конфигураторе.
Для поля ОтличительныйПризнак такими допустимыми типами являются СТРОКА, Справочник.Цвета и Справочник.Вкусы.
Иногда возникает необходимость привести значения составного поля к какому-либо определенному типу.
Давайте приведём все значения поля ОтличительныйПризнак к типу Справочник.Цвета:
В результате, все значения элементов, которые имели тип Справочник.Цвета, остались заполненными и оказались приведенными к указанному типу. Все значения других типов (СТРОКА, Справочник.Вкусы) теперь стали равны NULL. В этом состоит особенность приведения типа при помощи функции ВЫРАЗИТЬ.
Приводить тип можно или к примитивному типу (БУЛЕВО, ЧИСЛО, СТРОКА, ДАТА) или к ссылочному типу. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Но тип, к которому делается приведение, обязательно должен входить в список типов для данного составного поля, иначе система выдаст ошибку.
Пройдите тест
Не все реквизиты справочников или документов имеют свой тип, но те что имеют можно посмотреть в конфигураторе
Не все реквизиты справочников или документов имеют свой тип, но те что имеют можно посмотреть в режиме 1С:Предприятие
Каждый реквизит справочника или документа имеет свой тип, который можно посмотреть в режиме 1С:Предприятие
Для работы с типами в запроса для сравнения и отборов существует две функции: ТИП() и ТИПЗНАЧЕНИЯ(), а также конструкция ССЫЛКА для ссылочных типов. В общем случае тип значения применяется для работы с составными полями, так как в других случаях тип значения известен заранее или не меняется.
Примеры проверки типа в запросах:
Получить тип в полях выборки:
ВЫБРАТЬ ТИП(Строка), ТИП(Справочник.Контрагенты)
Получить совпадение типа в выборке
Выбрать ТИПЗНАЧЕНИЯ(Ссылка) = ТИП(Справочник.Контрагенты)
Отбор по типу значения:
ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ ТИПЗНАЧЕНИЯ(ОсновнойМенеджер) = ТИП(Справочник.ФизическиеЛица)
Использование конструкции ССЫЛКА:
ВЫБРАТЬ ИНН ИЗ Справочник.Контрагенты ГДЕ ОсновнойМенеджер ССЫЛКА Справочник.ФизическиеЛица
Последние две конструкции идентичны по результату исполнения, но последняя применима только к ссылочным типам, что не всегда так, но более компактна.
Допустимо использование данных конструкций и в качестве условия для соединения таблиц.
На тип значения можно проверять не только поля из выборки запроса, но и параметры:
ВЫБРАТЬ * из Справочник.Контрагенты ГДЕ ТИПЗНАЧЕНИЯ(&Параметр) = ТИП(Справочник.Контрагенты)
Параметром функции ТИПЗНАЧЕНИЯ могут выступать:
СТРОКА, ЧИСЛО, ДАТА, а также все ссылочные типы.
Чтобы проверить на несколько значений применяется условие ИЛИ или множество В()
ВЫБРАТЬ Ссылка ИЗ Справочник.Пользователи ГДЕ ФизЛицо ССЫЛКА Справочник.ФизическиеЛица ИЛИ Физлицо ССЫЛКА Справочник.Пользователи
ВЫБРАТЬ Ссылка ИЗ Справочник.Пользователи ГДЕ ТИПЗНАЧЕНИЯ(Физлицо) В (ТИП(Справочник.ФизическиеЛица),ТИП(Справочник.Пользователи))
При сравнении ссылочных типов пустые ссылки, также дают совпадение, то есть для проверки на заполненность они применимы только как вспомогательные функции
Выбрать * ИЗ Справочник.Пользователи ГДЕ ТИПЗНАЧЕНИЯ(Физлицо) <> ТИП(Неопределено) И ТИПЗНАЧЕНИЯ(Физлицо) <> ТИП(NULL) И НЕ Физлицо = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
Единственные настоящие поэты нашего времени служат в рекламных агентствах.
— Теннеси Уильямс
Кроме преобразования строк и числа функция применяется для выделения одного типа в составных реквизитах.
Зачем использовать ВЫРАЗИТЬ для полей составного типа?
Поля составного типа — реквизиты, в которых допустимо указание значения различных типов.
В случае, когда такое поле не заполнено в нём хранится НЕОПРЕДЕЛЕНО, с которым не совсем удобно работать на выходе:
- необходимо постоянно проверять на заполнено
- если используется обращение к реквизитам через точку, при обращении возможно появление ошибки.
Пример №1:
Есть реквизит составного типа: Число+Перечисление
Если выполнить ВЫРАЗИТЬ(Реквизит как ЧИСЛО(15,0)) тогда на выходе получится NULL, что ничем не лучше.
Если вызвать ВЫРАЗИТЬ(Реквизит КАК Перечисление.ВидыЗаявок), в результате получится значение Перечисления.ВидыЗаявок.Пустая(), что вполне удобно.
Вышестоящий пример я привел для ситуации, когда удобство не так заметно.
Пример №2:
Реквизит составного типа: Справочник.ФизическиеЛица+Справочник.Сотрудники
Если вы сделаете отбор в запросе:
ГДЕ
Сотрудник ССЫЛКА Справочник.Сотрудник
У вас на выходе получатся только записи, где реквизит Сотрудник типа сотрудники, но если это поле пустое, там будет Неопределено.
В случае использования конструкции
ВЫРАЗИТЬ (Сотрудник как Справочник.Сотрудники) как ПолеСотрудник
В данном поле всегда будет значение ссылки и допустимо обращение к нему: в момент обработки результата запроса «ПолеСотрудник.Наименование», ПолеСотрудник.Пустая(), не вызывая ошибки.
Дополнительное преимущество такого использования:
В случае если составное поле имеет тип Справочник.Ссылка или Документ.Ссылка (любой справочник и любой документ, совместно) при выполнении запроса 1С присоединит все связанные таблицы:
- В лучшем случае это замедлит выполнение запроса.
- В больших конфигурациях типа УПП или ERP, такие запросы могут вызвать ошибку превышения количества таблиц в запросе — он попросту не выполнится.
Если же вы знаете, что там будет и ограничите значения функцией ВЫРАЗИТЬ, такого не происходит — и вы помогаете оптимизатору запросов, а для файловой версии это может оказаться критичным.
В типовых конфигурациях реквизит «ДокументОснование»,»ДокументОприходования», «Партия» или «Сделка», торговых документов чаще всего нуждается в таком преобразовании, т.к. составные поля используются редко: чаще разносят по различным реквизитам, которые видимы в зависимости от вида операции/ситуации.
Другие статьи про работу с ВЫРАЗИТЬ:
Клиент получает ту рекламу, которую он заслуживает!
— Дэвид Огилви
Параметры запроса в 1С 8.3 необходимы для оптимизации кода запроса. Параметры бывают простых типов, ссылочных типов, списочных типов, в виде таблиц значений. Чтобы объявить параметра в языке запроса используется символ "&" и название параметра, Например: &ДатаДокумента. Для вставки параметра в запрос, используется функция УстановитьПараметр().
&НаСервере
Процедура ПередачаПараметровПростыхТиповВЗапросе ()
// Создание отбора по поступлению материала за 2020 год
Запрос = Новый Запрос ( "ВЫБРАТЬ
| Ссылка
|ИЗ
| Документ.ПоступлениеМатериалов
|ГДЕ
| Дата МЕЖДУ &НачДата И &КонДата
|УПОРЯДОЧИТЬ ПО
| Дата ВОЗР" );
Запрос . УстановитьПараметр ( "НачДата" , '20200101000000' );
Запрос . УстановитьПараметр ( "КонДата" , '20201231235959' );
РезультатЗапроса = Запрос . Выполнить (); Записи = РезультатЗапроса . Выбрать ();
Пока Записи . Следующий () Цикл
// Обход результата запроса по каждой записи в полученной выборке
КонецЦикла;
&НаСервере
Процедура ПередачаПараметровСсылочныхТиповВЗапросе ()
// Создание отбора по материалам с единицей измерения "Куб.см."
Запрос = Новый Запрос ( "ВЫБРАТЬ
| Наименование,
| ЕдиницаИзмерения
|ИЗ
| Справочник.Материалы
|ГДЕ
| ЕдиницаИзмерения = &ЕдинИзмер" );
Запрос . УстановитьПараметр ( "ЕдинИзмер" , Справочники . ЕдиницыИзмерения . НайтиПоНаименованию ( "Куб.см." ));
РезультатЗапроса = Запрос . Выполнить (); Записи = РезультатЗапроса . Выбрать ();
Пока Записи . Следующий () Цикл
// Обход результата запроса по каждой записи в полученной выборке
КонецЦикла;
&НаСервере
Процедура ПередачаПараметровСписочногоТипаВЗапросе ()
// Создание отбора по материалам, единицы измерения входят в переданный список
Запрос = Новый Запрос ( "ВЫБРАТЬ
| Наименование,
| ЕдиницаИзмерения
|ИЗ
| Справочник.Материалы
|ГДЕ
| ЕдиницаИзмерения В (&СписокЕдиницИзмерения)" );
СписокЕИ = Новый Массив ;
СписокЕИ . Добавить ( Справочники . ЕдиницыИзмерения . НайтиПоНаименованию ( "Куб.см." ));
СписокЕИ . Добавить ( Справочники . ЕдиницыИзмерения . НайтиПоНаименованию ( "Куб.дм." ));
СписокЕИ . Добавить ( Справочники . ЕдиницыИзмерения . НайтиПоНаименованию ( "Куб.м." ));
Запрос . УстановитьПараметр ( "СписокЕдиницИзмерения" , СписокЕИ );
РезультатЗапроса = Запрос . Выполнить (); Записи = РезультатЗапроса . Выбрать ();
Пока Записи . Следующий () Цикл
// Обход результата запроса по каждой записи в полученной выборке
КонецЦикла;
&НаСервере
Процедура ПередачаПараметраВВидеТаблицыЗначенийВЗапросе ()
// Создание отбора по материалам в соответствии с параметром в виде
// комбинированной таблицы значений: "Срок Использования" и "Производитель"
ТЗ_СрокИсп_Произв = новый ТаблицаЗначений ;
ТЗ_СрокИсп_Произв . Колонки . Добавить ( "СрокИспользования" , Новый ОписаниеТипов ( "СправочникСсылка.КлассификаторСроковПИ" ));
ТЗ_СрокИсп_Произв . Колонки . Добавить ( "Производитель" , Новый ОписаниеТипов ( "СправочникСсылка.Контрагенты" ));
// "12 месяцев" + "Гомелькабель"
СтрокаТЗ = ТЗ_СрокИсп_Произв . Добавить ();
СтрокаТЗ . СрокИспользования = Справочники . КлассификаторСроковПИ . НайтиПоНаименованию ( "12 месяцев" );
СтрокаТЗ . Производитель = Справочники . Контрагенты . НайтиПоНаименованию ( "Гомелькабель" );
// "18 месяцев" + "Гомельстекло"
СтрокаТЗ = ТЗ_СрокИсп_Произв . Добавить ();
СтрокаТЗ . СрокИспользования = Справочники . КлассификаторСроковПИ . НайтиПоНаименованию ( "18 месяцев" );
СтрокаТЗ . Производитель = Справочники . Контрагенты . НайтиПоНаименованию ( "Гомельстекло" );
Запрос = Новый Запрос ( "ВЫБРАТЬ
| Наименование,
| СрокИспользования,
| Производитель
|ИЗ
| Справочник.Материалы
|ГДЕ
| (СрокИспользования, Производитель) В (&СписокСочетаний)" );
Запрос . УстановитьПараметр ( "СписокСочетаний" , ТЗ_СрокИсп_Произв );
РезультатЗапроса = Запрос . Выполнить (); Записи = РезультатЗапроса . Выбрать ();
Пока Записи . Следующий () Цикл
// Обход результата запроса по каждой записи в полученной выборке
КонецЦикла;
&НаСервере
Процедура ИспользованиеТаблицыЗначенийПереданнойВЗапросКакПараметр ()
// Программное создание Таблицы Значений и передача её в запрос
ДрагМеталл = новый ТаблицаЗначений ;
ДрагМеталл . Колонки . Добавить ( "Название" , Новый ОписаниеТипов ( "Строка" ));
ДрагМеталл . Колонки . Добавить ( "РынЦена" , Новый ОписаниеТипов ( "Число" ));
НоваяСтрока = ДрагМеталл . Добавить ();
НоваяСтрока . Название = "Золото" ;
НоваяСтрока . РынЦена = 127.29 ;
НоваяСтрока = ДрагМеталл . Добавить ();
НоваяСтрока . Название = "Серебро" ;
НоваяСтрока . РынЦена = 1.30 ;
НоваяСтрока = ДрагМеталл . Добавить ();
НоваяСтрока . Название = "Платина" ;
НоваяСтрока . РынЦена = 62. 00 ;
НоваяСтрока = ДрагМеталл . Добавить ();
НоваяСтрока . Название = "Родий" ;
НоваяСтрока . РынЦена = 568.27 ;
// Сперва выбираем данные во временную таблицу, а потом работаем как с обычной таблицей
Запрос = Новый Запрос ( "ВЫБРАТЬ
| Название,
| РынЦена
|ПОМЕСТИТЬ
| ВременнаяТаблица
|ИЗ
| &ТаблицаДрагМеталлов КАК ДрагМеталлы
|;
|ВЫБРАТЬ
| Название,
| РынЦена
|ИЗ
| ВременнаяТаблица
|УПОРЯДОЧИТЬ ПО
| РынЦена УБЫВ" );
Запрос . УстановитьПараметр ( "ТаблицаДрагМеталлов" , ДрагМеталл );
РезультатЗапроса = Запрос . Выполнить (); Записи = РезультатЗапроса . Выбрать ();
Пока Записи . Следующий () Цикл
// Обход результата запроса по каждой записи в полученной выборке
КонецЦикла;
Читайте также: