Выразить как документ в запросе 1с 8.3. Преобразование составного типа к одиночному

Функцию ВЫРАЗИТЬ в языке запросов 1С 8 многие интерпретируют как преобразователь типов, но она предназначена совершенно не для этих целей. Подробности под катом...

Итак, многие ошибочно полагают, что смогут преобразовать поле с типом Строка в поле с типом Число или ссылку в строку. На самом деле оператор ВЫРАЗИТЬ может преобразовать:

  • настройки примитивного типа;
  • поле составного типа в поле одиночного типа;

Рассмотрим эти ситуации более подробно...

Преобразование настроек примитивного типа

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

ВЫБРАТЬ
ВЫРАЗИТЬ(Приходная.Комментарий КАК СТРОКА(300)) КАК Комментарий,
КОЛИЧЕСТВО(Приходная.Ссылка) КАК Ссылка
ИЗ
Документ.Приходная КАК Приходная

СГРУППИРОВАТЬ ПО
ВЫРАЗИТЬ(Приходная.Комментарий КАК СТРОКА(300))

Еще ситуация когда в запросе используются расчеты, на выходе мы можем получить число с большим количество знаков после запятой (1100,001568794) . Чтобы не обрабатывать это число полсе выполнения запроса его сразу можно обрезать до нужной длины, но важно понимать что число именно обрезается, а не округляется. Пример:

ВЫБРАТЬ
Продажи.Товар,
ВЫРАЗИТЬ(Продажи.Количество * Продажи.Цена КАК ЧИСЛО(15, 2)) КАК Сумма
ИЗ

Преобразование составного типа к одиночному

Регистратор у регистров часто имеет составной тип, чтобы преобразовать его к одиночному типу используйте конструкцию ВЫРАЗИТЬ правда если на этапе выборки вы попытаетесь преобразовать документ реализацию в документ поступление, то запрос обязательно вылетит с ошибкой, поэтому перед преобразованием следует проверить тип ссылки. Вот такая вот белиберда))) Зачем все это нужно спросите вы. Отвечаю, это один из моментов неявной оптимизации запроса в ущерб краткости написания. Рассмотрим приминение этого момента на примере.

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

ВЫБРАТЬ РАЗЛИЧНЫЕ
Продажи.Регистратор.Номер
ИЗ
РегистрНакопления.Продажи КАК Продажи

Собственно, ничего не может быть проще. Вот только 1С на этапе выполнения преобразует этот запрос без каких либо соединений в запрос с таким количество левых соединений сколько у нас возможных регистраторов. Т.е. если пишут в этот регистр 20 документов, то получим SQL запрос с 20 левыми соединениями. Почему так происходит? Потому что встроенный 1С оптимизатор не совсем хорошо обрабатывает поля получаемые через точку, в данном случае это реквизит Номер. Вот такие пироги, если мы часто захотим получать номер документа, то разумнее всего включить его в реквизиты регистра или же использовать оператор ВЫРАЗИТЬ, но в ущерб краткости:

ВЫБРАТЬ РАЗЛИЧНЫЕ
Продажи.Регистратор.Номер,
ВЫБОР
КОГДА Продажи.Регистратор ССЫЛКА Документ.Расходная
ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.Расходная)
ИНАЧЕ ВЫБОР
КОГДА Продажи.Регистратор ССЫЛКА Документ.Реализация
ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.Реализация)
КОНЕЦ
...
КОНЕЦ КАК Номер
ИЗ
РегистрНакопления.Продажи КАК Продажи

Теперь в левом соединении будет участвовать одна конкретная таблица.

В общем случае, стоит внимательно обращаться к данным через точку, т.к. 1С в этом случае использует левое соединение в запросе SQL, что может существенно отразиться на производительности. Это один из моментов оптимизации.

Несовместимые типы «ВЫРАЗИТЬ» — такое сообщение появляется, когда программист 1С 8.2 или 8.3 в пытается сравнить два различных типа.

Функция Выразить() позволяет привести значение поля запроса 1С к определенному типу. Это может понадобиться в двух случаях:

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

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

Например:

ВЫРАЗИТЬ(Номенклатура.Комментарий КАК СТРОКА(300))
ВЫРАЗИТЬ(Номенклатура.Цена КАК ЧИСЛО(15, 2)) КАК Сумма

2. Преобразовать поле составного типа в поле с одним типом. Это может понадобиться в целях . Если в типизированное поле попадёт значение другого типа, то система вернёт NULL, поэтому всегда необходимо дополнительно устанавливать условие в секции «ГДЕ», ограничивая его оператором ССЫЛКА.

Например:

ВЫБРАТЬ

ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.Реализация)

ИЗ

ГДЕ Продажи.Регистратор ССЫЛКА Документ.Реализация

Как избежать ошибок

Ошибки типа «Несовместимые типы ВЫРАЗИТЬ …» могут возникать при неправильном использования синтаксиса.

К примеру, конструкция «ВЫРАЗИТЬ(«123″ КАК ЧИСЛО(5, 2)) КАК Сумма» считается ошибочной, так как в запросе нельзя штатными способами преобразовывать из одного типа в другой.

Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте

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

Войдите на сайт как ученик

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

Язык запросов 1С 8.3 для начинающих программистов: функции и операторы для работы с типами (ТИПЗНАЧЕНИЯ, ТИП, ССЫЛКА, ЕСТЬNULL, ВЫРАЗИТЬ)

Давайте вспомним, что каждый реквизит (свойство, поле) справочника, документа или любого другого прикладного объекта имеет свой тип . И этот тип мы можем посмотреть в конфигураторе:

В языке запросов существует целый класс функций и операторов для работы с типами реквизитов. Давайте рассмотрим их.

Функция ТИПЗНАЧЕНИЯ

Эта функция принимает один параметр (значение) и возвращает его тип. Для описанного на картинке (выше) реквизита Вкус справочника Еда вернётся следующее:

А теперь давайте рассмотрим реквизит ОтличительныйПризнак у справочника Города :

Вы видите, что этот реквизит может иметь один из нескольких типов: Строка , Справочник.Вкусы , Справочник.Цвета . Такой тип реквизитов называется СОСТАВНЫМ .

Если мы попытаемся заполнить значение такого реквизита в режиме 1С:Предприятие, то система спросит нас, какого типа будет вводимое значение:

И только после нашего выбора позволит ввести значение выбранного типа.

Таким образом, элементы справочника одного вида (Справочник.Города ) смогут хранить в одном и том же реквизите (ОтличительныйПризнак ) значения разных типов (Строка, Цвета или Вкусы).

Вы можете убедиться в этом сами пощёлкав по элементам справочника Города в режиме 1С:Предприятие. Вы читаете ознакомительную версию урока, полноценные уроки находятся .

Здесь значение отличительного признака является элементом справочника Вкусы :

Здесь строкой:

А здесь вообще элементом справочника Цвета :

Вот какие возможности открывает перед нами составной тип данных!

Интересно, как поведёт себя функция ТИПЗНАЧЕНИЯ на реквизите ОтличительныйЭлемент , имеющий составной тип данных:

Это уже очень интересно. Давайте разбираться с каждой строкой в отдельности.

Тип значения отличительного признака для элемента Россия равен NULL . Мы впервые сталкиваемся с этим типом. Значения данного типа используются исключительно для определения отсутствующего значения при работе с базой данных.

Так и есть, ведь элемент Россия является группой, а не обычным элементом справочника Города , поэтому у него отсутствует поле ОтличительныйПризнак . А тип у отсутствующего значения, как мы прочитали выше, всегда равен NULL .

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

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

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

Индия снова группа, поэтому значение отсутствует. А тип у отсутствующего значения, как мы помним, равен NULL .

А дело вот в чём. Если вы зайдёте в элемент справочника Города с наименованием Сан-Паулу , то увидите, что поле ОтличительныйПризнак совершенно никак не заполнено. Оно пустое. А все незаполненные поля составного типа имеют специальное значение НЕОПРЕДЕЛЕНО .

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

Функция ТИП

Она принимает всего один параметр - имя примитивного типа (СТРОКА , ЧИСЛО , ДАТА , БУЛЕВО ), либо имя таблицы, тип ссылки которой нужно получить.

Результатом данной конструкции будет значение типа Тип для указанного типа.

Звучит туманно, не правда ли?

Давайте рассмотрим применение данной конструкции и всё сразу станет на свои места.

Пусть нам требуется отобрать все записи справочника Города , у которых составной реквизит ОтличительныйПризнак имеет значение типа СТРОКА :

Теперь давайте отберём все записи, у которых значения реквизита ОтличительныйПризнак являются ссылками на элементы справочника Цвета (таблица Справочник.Цвета ):

Отступление

Как вы помните, некоторые элементы справочника Города не имеют реквизита ОтличительныйПризнак . Функция ТИПЗНАЧЕНИЯ для таких элементов выдаёт NULL .

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

Вот пример его использования:

Отлично. Но вы заметили, что здесь нет элемента Сан-Паулу, тип значения реквизита ОтличительныйПризнак которого также выдавал NULL . Почему так произошло?

А всё дело в том, что ситуация для групп (Россия, Индия, Бразилия), для которых заполнение реквизита ОтличительныйПризнак невозможно в принципе, так как его у них нет вовсе, отличается от ситуации для элемента Сан-Паулу, для которого заполнение реквизита возможно, но оно просто не заполнено и равно, как мы помним, специальному значению НЕОПРЕДЕЛЕНО .

Чтобы отобрать все записи, у которых реквизит ОтличительныйПризнак присутствует, но не заполнен следует использовать другую конструкцию:

Но сравнение с НЕОПРЕДЕЛЕНО для определения пустых (не заполненных) реквизитов будет работать только для составных типов.

Кстати, у логического оператора ЕСТЬ NULL форма отрицания выглядит следующим образом:

Логический оператор ССЫЛКА

К примеру, давайте выберем из справочника Города только те записи, у которых значение составного реквизита ОтличительныйПризнак являются ссылкой на элемент справочника Вкусы :

Как вы помните, эту же задачу мы могли бы решить используя ТИПЗНАЧЕНИЯ и ТИП :

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

Функция предназначена для замены значения NULL на другое значение.

Мы помним, что значение NULL возвращается в том случае, если запрашиваемый реквизит (поле, свойство) не существует.

Как например, реквизит ОтличительныйПризнак для групп справочника Города :

Функция ЕСТЬNULL поможет нам вывести другое значение в том случае, если это значение равно NULL . Вы читаете ознакомительную версию урока, полноценные уроки находятся . Пусть в данном случае это будет строка "Такого реквизита нет!":

Получается, что если первый параметр функции ЕСТЬNULL не равен NULL , то возвращается он. Если же он равен NULL, то возвращается второй параметр.

Функция ВЫРАЗИТЬ

Эта функция предназначена только для полей , имеющих составной тип . Отличным примером такого поля является свойство ОтличительныйПризнак у элементов справочника Города .

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

Для поля ОтличительныйПризнак такими допустимыми типами являются СТРОКА , Справочник.Цвета и Справочник.Вкусы .

Иногда возникает необходимость привести значения составного поля к какому-либо определенному типу.

Давайте приведём все значения поля ОтличительныйПризнак к типу Справочник.Цвета:

В результате, все значения элементов, которые имели тип Справочник.Цвета, остались заполненными и оказались приведенными к указанному типу. Все значения других типов (СТРОКА , Справочник.Вкусы ) теперь стали равны NULL . В этом состоит особенность приведения типа при помощи функции ВЫРАЗИТЬ .

Приводить тип можно или к примитивному типу (БУЛЕВО , ЧИСЛО , СТРОКА , ДАТА ) или к ссылочному типу. Вы читаете ознакомительную версию урока, полноценные уроки находятся . Но тип, к которому делается приведение, обязательно должен входить в список типов для данного составного поля, иначе система выдаст ошибку.

Пройдите тест

Начать тест

1. Выберите наиболее верное утверждение

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

3. Для определения типа значения реквизита подойдёт функция

4. Незаполненные реквизиты составного типа имеют значение

В этой статье разберем возможности приведения типов в языке запросов 1С, которые предоставляет функция «Выразить».
Рассмотрим несколько вариантов применения этой функции.
И первый вариант – округление чисел.

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

Выразить(<Число> как Число(<ДлинаЧисла>,<Точность>))

Где:
Число — поле, параметр которое нужно округлить
ДлинаЧисла — максимальная длина числа
Точность — точность округления числа

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

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

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

Выразить(<Строка> как Строка(<ДлинаСтроки>)

Где
ДлинаСтроки – максимальная длина, к которой будет приведена строка.
Переделаем запрос: будем в условии приводить неограниченную строку к строке с определенной длинной. Тогда ни каких ошибок не будет.

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

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

Выразить(<Документ> как Документ.<ИмяТаблицы>)
Выразить(<Справочник> как Справочник.< ИмяТаблицы >)
.

Где
ИмяТаблицы — название объекта в .

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

Если Вы всё еще «плаваете» в конструкциях языка запросов, и у Вас вызывают трудности даже самые простые запросы, то рекомендую вам мой курс «Запросы в 1С от новичка до профи» . Где эти и многие другие вопросы рассматриваются более подробно.

В чем особенность этого курса:
Курс рассчитан на тех, кто не знаком с языком запросов в 1С;
Учебный материал грамотно скомпонован и прост в освоении;
Несколько десятков уроков;
Полезные практические примеры;
Все уроки изложены понятным и простым языком

Для моих читателей, купон на скидку 25%: hrW0rl9Nnx

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

Можете перечислить любую сумму напрямую:
Яндекс.Деньги — 410012882996301
Web Money — R955262494655

Вступайте в мои группы.