Равно не равно в 1с
Для работы с типами в запроса для сравнения и отборов существует две функции: ТИП() и ТИПЗНАЧЕНИЯ(), а также конструкция <Значение> ССЫЛКА <Тип> для ссылочных типов. В общем случае тип значения применяется для работы с составными полями, так как в других случаях тип значения известен заранее или не меняется.
Примеры проверки типа в запросах:
Получить тип в полях выборки:
ВЫБРАТЬ ТИП(Строка), ТИП(Справочник.Контрагенты)
Получить совпадение типа в выборке
Выбрать ТИПЗНАЧЕНИЯ(Ссылка) = ТИП(Справочник.Контрагенты)
Отбор по типу значения:
ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ ТИПЗНАЧЕНИЯ(ОсновнойМенеджер) = ТИП(Справочник.ФизическиеЛица)
Использование конструкции ССЫЛКА:
ВЫБРАТЬ ИНН ИЗ Справочник.Контрагенты ГДЕ ОсновнойМенеджер ССЫЛКА Справочник.ФизическиеЛица
Последние две конструкции идентичны по результату исполнения, но последняя применима только к ссылочным типам, что не всегда так, но более компактна.
Допустимо использование данных конструкций и в качестве условия для соединения таблиц.
На тип значения можно проверять не только поля из выборки запроса, но и параметры:
ВЫБРАТЬ * из Справочник.Контрагенты ГДЕ ТИПЗНАЧЕНИЯ(&Параметр) = ТИП(Справочник.Контрагенты)
Параметром функции ТИПЗНАЧЕНИЯ могут выступать:
СТРОКА, ЧИСЛО, ДАТА, а также все ссылочные типы.
Чтобы проверить на несколько значений применяется условие ИЛИ или множество В()
ВЫБРАТЬ Ссылка ИЗ Справочник.Пользователи ГДЕ ФизЛицо ССЫЛКА Справочник.ФизическиеЛица ИЛИ Физлицо ССЫЛКА Справочник.Пользователи
ВЫБРАТЬ Ссылка ИЗ Справочник.Пользователи ГДЕ ТИПЗНАЧЕНИЯ(Физлицо) В (ТИП(Справочник.ФизическиеЛица),ТИП(Справочник.Пользователи))
При сравнении ссылочных типов пустые ссылки, также дают совпадение, то есть для проверки на заполненность они применимы только как вспомогательные функции
Выбрать * ИЗ Справочник.Пользователи ГДЕ ТИПЗНАЧЕНИЯ(Физлицо) <> ТИП(Неопределено) И ТИПЗНАЧЕНИЯ(Физлицо) <> ТИП(NULL) И НЕ Физлицо = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
Легче сочинить 10 правильных сонетов, чем хорошее рекламное объявление.
— Олдос Хаксли
Войдите как ученик, чтобы получить доступ к материалам школы
Внутренний язык программирования 1С 8.3 для начинающих программистов: простые логические выражения в 1С
Автор уроков и преподаватель школы: Владимир Милькин
На прошлом занятии мы научились давать имена и вводить их значения от пользователя.
Наберитесь сил и терпения. Занятия №5 и №6 будут трудными, но очень важными для дальнейшего понимания программирования в 1С. Поэтому, если хоть что-то останется непонятным или нераскрытым - перечитывайте, вдумывайтесь, задавайте вопросы.
Простые логические выражения
Сегодня, к уже изученным типам данных (строка, число и дата) добавим ещё один - логический тип. Он может принимать всего два значения: Истина или Ложь.
Значение логического типа (Истина или Ложь) является результатом некоторого логического выражения.
Логическое выражение - это выражение, составленное при помощи операций сравнения. Сравнивать можно числа, даты, строки и другие данные. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. О логическом выражении можно сказать, верно оно (Истина) или неверно (Ложь).
Операции сравнения бывают следующие:
Операция | Обозначение в языке 1С |
---|---|
Равно | = |
Не равно | <> |
Больше | > |
Меньше | < |
Больше или равно | >= |
Меньше или равно | <= |
Думаю, интуитивно понятно, что обозначает каждая из операций.
Читается, например, так:
- 1 = 1 ("один равен одному").
- 4 <> 5 ("четыре не равно пяти")
- 3 > 1 ("три больше одного").
Обращаю ваше внимание, что перечисленные три примера логических выражений принимают значение Истина, так как все они верны.
Разберем на примере:
Пример логического выражения | Результат | Объяснение |
---|---|---|
1 = 2 | Ложь | неверно, единица на самом деле не равна двойке |
1 = 1 | Истина | верно, единица равна единице |
выражение "Земля" <> "Луна" | Истина | верно, строка "Земля" не равна строке "Луна" |
'18610101' <> '18610101' | Ложь | неверно, дата 01.01.1861 на самом деле равна дате 01.01.1861 |
100 > 50 | Истина | верно, сто действительно больше пятидесяти |
10 < 0 | Ложь | неверно, на самом деле десять больше нуля |
Задание №14. Укажите для каждого логического выражения его результат - Истина или Ложь.
- "Венера" = "Юпитер"
- "Венера" <> "Юпитер"
- 123 = 321
- 123 < 321
- 123 <= 321
- 123 <= 123
- '20000101' <> '20140101'
- '20000101' = '20000101'
- '20140101' > '20120101'
- 25 + 25 = 50
- 2 * (10 + 10) > 50
- "Юрий" + " Гагарин" = "Юрий Гагарин"
Попытайтесь ответить на все вопросы самостоятельно. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Затем посмотрите ответы ниже и попытайтесь разобраться, если где-то ошиблись.
- "Венера" = "Юпитер" (Ложь, строки не равны между собой, а в выражении утверждается, что равны).
- "Венера" <> "Юпитер" (Истина, строки не равны между собой, как и утверждается в выражении).
- 123 = 321 (Ложь, так как числа не равны между собой, а в выражении утверждается, что равны).
- 123 < 321 (Истина, так как 123 меньше 321, как и утверждается в выражении).
- 123 <= 321 (Истина, так как 123 меньше 321, а данное утверждение истинно, если левое число меньше или равно правому).
- 123 <= 123 (Истина, так как 123 равно 123, а данное утверждение истинно, если левое число меньше или равно правому).
- '20000101' <> '20140101' (Истина, так как левая дата 01.01.2000 не равна 01.01.2014, как и утверждается в выражении).
- '20000101' = '20000101' (Истина, так как левая дата 01.01.2000 равна 01.01.2000, как и утверждается в выражении).
- '20140101' > '20120101' (Истина, так как первое января 2014 года больше первого января 2012 года, как и утверждается в выражении).
- 25 + 25 = 50 (Истина, так как 25 плюс 25 действительно равно пятидесяти, как и утверждается в выражении).
- 2 * (10 + 10) > 50 (Ложь, так как результат левого выражения равен 40, а 40 меньше 50, хотя в утверждении говорится обратное).
- "Юрий" + " Гагарин" = "Юрий Гагарин" (Истина, так как сумма строк "Юрий" и " Гагарин" образует одну строку "Юрий Гагарин", которая равна строке справа, как и утверждается в выражении).
Заставим считать компьютер
Но, что же мы сами-то считаем "верно" или "неверно ". Ведь у нас под рукой компьютер! Давайте возложим эту задачу на него, а заодно и проверим себя.
К примеру, проверим выражение 2 * (10 + 10) > 50.
Для этого напишем такую программу:
Если мы запустим её, то компьютер выдаст "Нет", что означает - результат равен Ложь.
Как он посчитал это выражение?
- Компьютер увидел команду Сообщить.
- Посмотрел, что за параметр мы передаем этой команде.
- Увидел, что в качестве параметра указано логическое выражение 2 * (10 + 10) > 50.
- Стал вычислять результат логического выражения.
- Увидел, что выражение состоит из левой части 2 * (10 + 10), правой части 50 и знака больше между ними.
- Посчитал результат левой части и выяснил, что он равен сорока.
- Снова взглянул на выражение, только в уже упрощенном виде 40 > 50, а так как 40, конечно же, меньше 50, то он вывел "Нет".
Задание №15. Вычислите все примеры логических выражений из предыдущего задания на компьютере.
Например, выражение "Венера" = "Юпитер", значение которого, как мы выяснили, равно Ложь.
Компьютер при запуске выводит значение "Нет", что означает: результат действительно равен Ложь и мы совершенно верно вычислили его сами.
Войдите как ученик, чтобы получить доступ к материалам школы
Язык запросов 1С 8.3 для начинающих программистов: функции и операторы для работы с типами (ТИПЗНАЧЕНИЯ, ТИП, ССЫЛКА, ЕСТЬNULL, ВЫРАЗИТЬ)
Автор уроков и преподаватель школы: Владимир Милькин
Давайте вспомним, что каждый реквизит (свойство, поле) справочника, документа или любого другого прикладного объекта имеет свой тип . И этот тип мы можем посмотреть в конфигураторе:
В языке запросов существует целый класс функций и операторов для работы с типами реквизитов. Давайте рассмотрим их.
Функция ТИПЗНАЧЕНИЯ
Эта функция принимает один параметр (значение) и возвращает его тип. Для описанного на картинке (выше) реквизита Вкус справочника Еда вернётся следующее:
Если мы запросим тип поля Наименование, то, как и ожидается, получим Строка:
А теперь давайте рассмотрим реквизит ОтличительныйПризнак у справочника Города:
Вы видите, что этот реквизит может иметь один из нескольких типов: Строка, Справочник.Вкусы, Справочник.Цвета. Такой тип реквизитов называется СОСТАВНЫМ .
Если мы попытаемся заполнить значение такого реквизита в режиме 1С:Предприятие, то система спросит нас, какого типа будет вводимое значение:
И только после нашего выбора позволит ввести значение выбранного типа.
Таким образом, элементы справочника одного вида (Справочник.Города) смогут хранить в одном и том же реквизите (ОтличительныйПризнак) значения разных типов (Строка, Цвета или Вкусы).
Вы можете убедиться в этом сами пощёлкав по элементам справочника Города в режиме 1С:Предприятие. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Здесь значение отличительного признака является элементом справочника Вкусы:
А здесь вообще элементом справочника Цвета:
Вот какие возможности открывает перед нами составной тип данных!
Интересно, как поведёт себя функция ТИПЗНАЧЕНИЯ на реквизите ОтличительныйПризнак, имеющий составной тип данных:
Это уже очень интересно. Давайте разбираться с каждой строкой в отдельности.
Тип значения отличительного признака для элемента Россия равен NULL. Мы впервые сталкиваемся с этим типом. Значения данного типа используются исключительно для определения отсутствующего значения при работе с базой данных.
Так и есть, ведь элемент Россия является группой, а не обычным элементом справочника Города, поэтому у него отсутствует поле ОтличительныйПризнак. А тип у отсутствующего значения, как мы прочитали выше, всегда равен NULL.
Тип значения отличительного признака для Перми равен Вкусы. Так и есть, ведь значение отличительного признака забитое в базе для города Пермь является ссылкой на элемент справочника Вкусы.
Для Красноярска тип признака равен Цвета, потому что значение выбранное в базе является ссылкой на элемент справочника Цвета.
Для Воронежа тип признака равен Строка, потому что значение введенное в базе является обычной строкой.
Индия снова группа, поэтому значение отсутствует. А тип у отсутствующего значения, как мы помним, равен NULL.
Далее всё аналогично, кроме Сан-Паулу. Это не группа, а обычный элемент справочника (город), но тип его значения пустой. Как так?
А дело вот в чём. Если вы зайдёте в элемент справочника Города с наименованием Сан-Паулу, то увидите, что поле ОтличительныйПризнак совершенно никак не заполнено. Оно пустое. А все незаполненные поля составного типа имеют специальное значение НЕОПРЕДЕЛЕНО .
С НЕОПРЕДЕЛЕНО мы также сталкиваемся впервые.
Значение НЕОПРЕДЕЛЕНО применяется, когда необходимо использовать пустое значение, не принадлежащее ни к одному другому типу. Это как раз наша ситуация.
А тип для значения, которое не принадлежит ни к одному из типов, как вы уже наверное догадались отсутствует.
Функция ТИП
Она принимает всего один параметр - имя примитивного типа (СТРОКА, ЧИСЛО, ДАТА, БУЛЕВО), либо имя таблицы, тип ссылки которой нужно получить.
Результатом данной конструкции будет значение типа Тип для указанного типа.
Звучит туманно, не правда ли?
Давайте рассмотрим применение данной конструкции и всё сразу станет на свои места.
Пусть нам требуется отобрать все записи справочника Города, у которых составной реквизит ОтличительныйПризнак имеет значение типа СТРОКА:
Теперь давайте отберём все записи, у которых значения реквизита ОтличительныйПризнак являются ссылками на элементы справочника Цвета (таблица Справочник.Цвета):
Отступление
Как вы помните, некоторые элементы справочника Города не имеют реквизита ОтличительныйПризнак. Функция ТИПЗНАЧЕНИЯ для таких элементов выдаёт NULL.
Как можно сделать отбор таких элементов в запросе? Для этого предусмотрен специальный логический оператор ЕСТЬ NULL (не путать с функцией ЕСТЬNULL, которую мы рассмотрим ниже). Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Вот пример его использования:
Но есть и такие элементы (Сан-Паулу), у которых реквизит ОтличительныйПризнак (составного типа) просто не заполнен и равен специальному значению НЕОПРЕДЕЛЕНО.
Чтобы отобрать такие записи следует использовать другую конструкцию:
Но сравнение с НЕОПРЕДЕЛЕНО для определения пустых (не заполненных) реквизитов будет работать только для составных типов.
Кстати, у логического оператора ЕСТЬ NULL форма отрицания выглядит следующим образом:
Логический оператор ССЫЛКА
Оператор ССЫЛКА позволяет проверить, является ли значение выражения, указанного слева от него, ссылкой на таблицу , указанную справа.
К примеру, давайте выберем из справочника Города только те записи, у которых значение составного реквизита ОтличительныйПризнак являются ссылкой на элемент справочника Вкусы:
Как вы помните, эту же задачу мы могли бы решить используя ТИПЗНАЧЕНИЯ и ТИП:
Функция ЕСТЬNULL
Функция предназначена для замены значения NULL на другое значение.
Мы помним, что значение NULL возвращается в том случае, если запрашиваемый реквизит (поле, свойство) не существует.
Как например, реквизит ОтличительныйПризнак для групп справочника Города:
Функция ЕСТЬNULL поможет нам вывести другое значение в том случае, если это значение равно NULL. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Пусть в данном случае это будет строка "Такого реквизита нет!":
Получается, что если первый параметр функции ЕСТЬNULL не равен NULL, то возвращается он. Если же он равен NULL, то возвращается второй параметр.
Функция ВЫРАЗИТЬ
Эта функция предназначена только для полей , имеющих составной тип . Отличным примером такого поля является свойство ОтличительныйПризнак у элементов справочника Города.
Как мы помним, составные поля могут быть одного из нескольких типов, указанных в конфигураторе.
Для поля ОтличительныйПризнак такими допустимыми типами являются СТРОКА, Справочник.Цвета и Справочник.Вкусы.
Иногда возникает необходимость привести значения составного поля к какому-либо определенному типу.
Давайте приведём все значения поля ОтличительныйПризнак к типу Справочник.Цвета:
В результате, все значения элементов, которые имели тип Справочник.Цвета, остались заполненными и оказались приведенными к указанному типу. Все значения других типов (СТРОКА, Справочник.Вкусы) теперь стали равны NULL. В этом состоит особенность приведения типа при помощи функции ВЫРАЗИТЬ.
Приводить тип можно или к примитивному типу (БУЛЕВО, ЧИСЛО, СТРОКА, ДАТА) или к ссылочному типу. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Но тип, к которому делается приведение, обязательно должен входить в список типов для данного составного поля, иначе система выдаст ошибку.
// Формирование строки индекса (для оптимизации поиска по ТЗ)
СтрокаИндексаТЗ1 = "" ;
Для каждого КолонкаТЗn1 Из ТЗn1 . Колонки Цикл
Если СтрокаИндексаТЗ1 = "" Тогда
СтрокаИндексаТЗ1 = КолонкаТЗn1 . Имя ;
Иначе
СтрокаИндексаТЗ1 = СтрокаИндексаТЗ1 + "," + КолонкаТЗn1 . Имя ;
КонецЕсли;
КонецЦикла;
// Вставка индекса
ТЗn2 . Индексы . Добавить ( СтрокаИндексаТЗ1 );
// Сравнения имён колонок ТЗ (необязательно если заведомо различны, можно закомментировать)
//Для Каждого СтрокаТаблицы1 Из ТЗn1 Цикл
// Для Каждого КолонкаТаблицы Из ТЗn1.Колонки Цикл
// Для Каждого СтрокаТаблицы2 Из ТЗn2 Цикл
// Если СтрокаТаблицы2[КолонкаТаблицы.Имя] <> СтрокаТаблицы1[КолонкаТаблицы.Имя] Тогда
// Сообщить("Имя колонки ТЗ N1 не совпадает с именем колонки ТЗ N2");
// Возврат Ложь;
// КонецЕсли;
// КонецЦикла;
// КонецЦикла;
//КонецЦикла;
// Проверка записей
Для Каждого СтрокаТаблицы1 Из ТЗn1 Цикл
СтруктураПоиска1 = Новый Структура ;
Для Каждого Колонка Из ТЗn1 . Колонки Цикл
СтруктураПоиска1 . Вставить ( Колонка . Имя , СтрокаТаблицы1 [ Колонка . Имя ]);
КонецЦикла;
СтрокиТаблицы2 = ТЗn2 . НайтиСтроки ( СтруктураПоиска1 );
Если СтрокиТаблицы2 . Количество () <> 1 Тогда
Возврат Ложь;
КонецЕсли;
// Формирование строки индекса (для оптимизации поиска по ТЗ)
СтрокаИндексаТЗ2 = "" ;
Для Каждого КолонкаТЗn2 Из ТЗn2 . Колонки Цикл
Если СтрокаИндексаТЗ2 = "" Тогда
СтрокаИндексаТЗ2 = КолонкаТЗn2 . Имя ;
Иначе
СтрокаИндексаТЗ2 = СтрокаИндексаТЗ2 + "," + КолонкаТЗn2 . Имя ;
КонецЕсли;
КонецЦикла;
// Вставка индекса
ТЗn1 . Индексы . Добавить ( СтрокаИндексаТЗ2 );
Для Каждого СтрокаТаблицы2 Из ТЗn2 Цикл
СтруктураПоиска2 = Новый Структура ;
Для Каждого Колонка Из ТЗn2 . Колонки Цикл
СтруктураПоиска2 . Вставить ( Колонка . Имя , СтрокаТаблицы2 [ Колонка . Имя ]);
КонецЦикла;
СтрокиТаблицы1 = ТЗn1 . НайтиСтроки ( СтруктураПоиска2 );
Если СтрокиТаблицы1 . Количество () <> 1 Тогда
Возврат Ложь;
КонецЕсли;
Эти операторы возможно использовать во всех 4 ситуациях, но контекст (окружаемые переменные у них отличаются).
В первых двух случаях условия накладываются на поля выборки, например:
ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты КАК СпрКонтрагенты ГДЕ СпрКонтрагенты.ИНН<>""
Обращение идет через имя таблицы (в простых запросах может опускаться, но в сложных может вызывать неоднозначность поля).
Данное условие вызывает ограничение выборки (обычно уменьшает ее)
В конструкторе запроса находятся на вкладке условия:
В произвольном варианте пишется текстом, в обычном выбирается поле, оператор сравнения и значение:
ВЫБОР КОГДА
Этот условный оператор используется для преобразования значения, ограничивает же выборку только когда расположен после служебного слова ГДЕ.
Допустимо несколько подчиненных условий. Может находится в полях выборки, полях условий ГДЕ, группировок, итогов (универсальный оператор для сложных условий)
Например, так выглядит вариант преобразования:
ВЫБРАТЬ
ВЫБОР
КОГДА 1 = 2
ТОГДА "Никогда не будет истиной"
КОГДА 1 = 1
ТОГДА "Всегда будет истиной"
ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
КОНЕЦ КАК ПолеПредставленияЗначения
Вариант использования в условии ГДЕ, результат выборки должен возвращать булево значение либо сравниваться с чем-то еще
Пример № 1
ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты КАК К ГДЕ ВЫБОР КОГДА К.ИНН = "" ТОГДА ЛОЖЬ ИНАЧЕ ИСТИНА КОНЕЦ
Пример № 2:
ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты КАК К ГДЕ ВЫБОР КОГДА К.ИНН = "" ТОГДА "" ИНАЧЕ "Заполнено" КОНЕЦ = "Заполнено"
Параметры виртуальных таблиц
В данном случае оперирование идет с полями таблиц, например ресурсами, измерениями, реквизитами. В этих условиях обращение идет без точки (контекст этого не требует).
ВЫБРАТЬ * ИЗ РегистрСведений.КурсыВалют.СрезПоследних(, Валюта.Код = "RUR")
В конструкторе запроса они находятся вот здесь:
Стоит отметить, что обычно используется ограничение над измерениями, так как иначе условие отнесется к выборке для получения, а не на сам результат (на ресурсы ограничения следует наложить в операторе ГДЕ, чтобы получить ожидаемый результат).
Накладывание условия в запросе на измерения, если нет обращения через точку (как в примере выше), ускоряет выборку: на больших таблицах, это будет визуально заметно; на небольших можно использовать как удобно.
ИМЕЮЩИЕ
ВЫБРАТЬ
Контрагенты.ИНН,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Контрагенты.Ссылка) КАК Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты
СГРУППИРОВАТЬ ПО
Контрагенты.ИНН
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Контрагенты.Ссылка) > 1 И
Контрагенты.ИНН <> ""
В данную выборку попадут дубли ИНН, когда оно вообще заполнено.
В конструкторе запроса также находится на вкладке условия
Читайте также: