Что такое ссылка в 1с
Про реквизит Ссылка
Введение
При изучении запросов ученики часто спрашивают про реквизит Ссылка, который есть, например, у справочников и документов.
Давайте зайдём в базу Гастроном и откроем данные справочника Цвета:
Здесь нажмём на кнопку "Стандартные реквизиты":
Вот она наша Ссылка. Это стандартный реквизит и он есть у многих прикладных типов данных.
Вот примеры его значений:
0xA9BA005056C0000811EAA968D227F09E
0xA9BA005056C0000811EAA968D8B6ACBD
0xA9BA005056C0000811EAA968D8B6ACBE
0xA9BA005056C0000811EAA96D0BC160C1
Вся прелесть этого реквизита в том, что его значение формируется платформой 1С автоматически в момент записи нового объекта в базу данных и является уникальным в пределах прикладного типа, к которому этот реквизит относится.
То есть, например, в справочнике Цвета не может быть двух элементов с одинаковым значением реквизита Ссылка.
А раз так, то значение реквизит Ссылка может использоваться для того, чтобы ссылаться на объект, которому оно принадлежит.
Пример
Представим, что мы создали новый элемент справочника Цвета со следующими значениями реквизитов:
Реквизит | Значение | Пояснение |
---|---|---|
Наименование | Красный | значение этого реквизита указали мы сами при создании элемента |
Ссылка | 0xA9BA005056C0000811EAA968D227F09C | значение этого реквизита платформа сформировала сама при записи нового элемента в базу данных |
А далее мы создали новый элемент справочника Клиенты со следующими реквизитами:
Реквизит | Значение | Пояснение |
---|---|---|
Наименование | Андрей | значение этого реквизита указали мы сами при создании элемента |
Пол | Мужской | значение этого реквизита указали мы сами при создании элемента |
Ссылка | 0xA9BA005056C0000811EAA96D0BC160C0 | значение этого реквизита платформа сформировала сама при записи нового элемента в базу данных |
А теперь самое интересное. У элемента справочника Клиенты есть реквизит ЛюбимыйЦвет, который указывает (ссылается) на элемент справочника Цвета.
Как вы думаете, какое именно значение мы должны записать в реквизит ЛюбимыйЦвет, чтобы он указывал на созданный нами ранее элемент справочника Цвета с наименованием "Красный"?
Верно, в этот реквизит мы должны записать значение реквизита Ссылка этого самого элемента (с наименованием "Красный").
То есть будет вот так:
Реквизит | Значение | Пояснение |
---|---|---|
ЛюбимыйЦвет | 0xA9BA005056C0000811EAA968D227F09C |
Примеры использования в запросах
Пример 1
Как мы уже выяснили, значение поля Ссылка уникально в пределах прикладного типа, к которому оно относится.
А значит мы можем использовать эту особенность, например, для подсчёта количества элементов в справочнике:
Пример 2
Давайте напишем очень глупый запрос, который тем не менее продемонстрирует нам, что в реквизит ЛюбимыйЦвет записывается именно значение реквизита Ссылка элемента, на который он ссылается:
Обратите внимание, как выглядит строковое значение реквизита ЛюбимыйЦвет и Ссылка.
Платформа 1С не вывела нам его настоящее значение (например, 0xA9BA005056C0000811EAA968D227F09C).
Вместо этого она определила, что это значение указывает на элемент справочника "Цвета" с наименованием "Красный" и вывела нам слово "Красный" в качестве представления этого элемента.
Это стандартное поведение платформы, просто так мы никогда и нигде не увидим "сырое" представление реквизита Ссылка.
Пример 3
Наконец, значение поля Ссылка можно использовать для так называемого разыменования через точку для получения значений реквизитов объекта, которому принадлежит поле Ссылка.
К примеру, если мы знаем, что реквизит ЛюбимыйЦвет указывает на элемент справочника Цвета, то мы можем путём разыменования через точку получить любой другой реквизит этого элемента.
Вот пример запроса, в котором мы для каждого элемента справочника Клиенты выводим значение реквизита Код элемента справочника Цвета, на который указывает реквизит ЛюбимыйЦвет.
В других языках с данными, полученными из базы данных обычно работают «как с таблицей». В 1С такое тоже возможно – выполнить запрос, получить «в ответ» таблицу и работать с ней.
Работа с объектом 1С ведется тогда, когда требуется создать объект 1С или изменить существующий. В остальных случаях (например поиск объекта 1С, использование его в другом объекте 1С) – используется ссылка 1С на объект 1С.
Создание объектов 1С
Объект 1С можно создать с помощью оператора Новый, при этом вызывается конструктор данного типа, если у типа несколько конструкторов – он выбирается по указанным параметрам:
Переменная1 = Новый СписокЗначений();
Менеджеры для получения объектов 1С из базы данных
Если требуется создать объект 1С, связанный с данными в базе данных (то есть фактически получить его из базы данных), вместо использования оператора Новый, используются менеджеры.
Почти для каждого вида метаданных (отображенного в дереве метаданных в окне конфигурации, см. выше) доступен одноименный менеджер, который позволяет получить значение из базы данных по признаку или создать новое для записи в базу данных.
Например:
Переменная1 = Справочники.ИмяСправочника.СоздатьЭлемент();
Переменная1 = Справочники.ИмяСправочника.НайтиПоНаименованию("Наименование");
Ссылки 1С и объекты 1С
Работа с объектами 1С, связанными с данными в базе данных может вестись двумя способами – с помощи «ссылки 1С на данные» и объекта 1С.
Ссылка 1С – это данные, доступные только для чтения. Объект 1С – это данные, доступные для чтения, изменения и записи. Работа со ссылкой 1С производится гораздо быстрее, чем с объектом 1С.
Ссылка 1С на данные получается с помощью функций вида:
СправочникСсылка = Справочники.ИмяСправочника.НайтиПоНаименованию()
Объект 1С можно получить из ссылки 1С или создать с нуля:
СправочникОбъект = СправочникСсылка.ПолучитьОбъект();
СправочникОбъект = Справочники.ИмяСправочника.СоздатьЭлемент();
Пустая ссылка 1С
Ссылка может быть пустой, это значит, что создан «пустой» экземпляр объекта 1С, который не связан с данными.
СправочникСсылкаПустая = Справочники.ИмяСправочника.ПустаяСсылка();
Также ссылку 1С можно проверить на заполненность:
Если СправочникСсылка.Пустая() Тогда
//…
КонецЕсли
Уникальный идентификатор (GUID)
Узнать идентификатор можно с помощью универсального метода любого объекта 1С ссылочного типа:
СправочникСсылка = Справочники.ИмяСправочника.НайтиПоНаименованию("Наименование");
GUID = СправочникСсылка.УникальныйИдентификатор();
Возвращаемое значение данного метода имеет специальный тип. Если необходимо сравнивать значение со строкой, не забудьте преобразовать его к строке с помощью Строка(Параметр).
GUID назначается в момент первой записи объекта 1С. Уже до записи можно узнать GUID, который будет назначен объекту 1С при записи:
Также перед записью можно назначить свой GUID. Это бывает полезным, например, при обмене данными:
При работе со значениями, возможно столкнуться со следующими способами хранения и доступа к данным:
- Переменная – созданная в модуле программистом, нетипизированная
- Реквизит объекта 1С (справочника, документа), добавленный в конфигураторе – хранится в базе данных, строго типизирован
- Реквизит формы – поле на форме, строго типизирован.
Поле на форме показывает «какие-то данные». Данные могут быть напрямую связаны с реквизитом объекта 1С (указаны в свойстве поля формы ПутьКДанным).
Также форма может иметь свои реквизиты, они не записываются в базу данных, их устанавливает программист в процедурах и функциях модуля формы (обычно в процедуре обработчике ПриОткрытии формы).
Доступ к значениям именованных свойств объектов 1С
У многих объектов 1С есть свойства, которые имеют наименования.
Например:
- элемент справочника имеет реквизиты с наименованиями
- форма имеет реквизиты с наименованиями
- у таблицы есть колонки с наименованиями
- у строки таблицы есть поля с такими же наименованиями, как колонки у таблицы.
Если у объекта 1С есть свойства (реквизиты, колонки и т.п.), у которых есть наименования, то к ним можно обращаться двумя способами.
Если в наличии имеются два объекта 1С с именованными свойствами и нужно скопировать их значения, удобно использовать процедуру
ЗаполнитьЗначенияСвойств(КудаКопировать, ОткудаКопировать)
которая копирует значения всех свойств, имена которых совпадают, пример:
Войдите как ученик, чтобы получить доступ к материалам школы
Язык запросов 1С 8.3 для начинающих программистов: функции и операторы для работы с типами (ТИПЗНАЧЕНИЯ, ТИП, ССЫЛКА, ЕСТЬNULL, ВЫРАЗИТЬ)
Автор уроков и преподаватель школы: Владимир Милькин
Давайте вспомним, что каждый реквизит (свойство, поле) справочника, документа или любого другого прикладного объекта имеет свой тип . И этот тип мы можем посмотреть в конфигураторе:
В языке запросов существует целый класс функций и операторов для работы с типами реквизитов. Давайте рассмотрим их.
Функция ТИПЗНАЧЕНИЯ
Эта функция принимает один параметр (значение) и возвращает его тип. Для описанного на картинке (выше) реквизита Вкус справочника Еда вернётся следующее:
Если мы запросим тип поля Наименование, то, как и ожидается, получим Строка:
А теперь давайте рассмотрим реквизит ОтличительныйПризнак у справочника Города:
Вы видите, что этот реквизит может иметь один из нескольких типов: Строка, Справочник.Вкусы, Справочник.Цвета. Такой тип реквизитов называется СОСТАВНЫМ .
Если мы попытаемся заполнить значение такого реквизита в режиме 1С:Предприятие, то система спросит нас, какого типа будет вводимое значение:
И только после нашего выбора позволит ввести значение выбранного типа.
Таким образом, элементы справочника одного вида (Справочник.Города) смогут хранить в одном и том же реквизите (ОтличительныйПризнак) значения разных типов (Строка, Цвета или Вкусы).
Вы можете убедиться в этом сами пощёлкав по элементам справочника Города в режиме 1С:Предприятие. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Здесь значение отличительного признака является элементом справочника Вкусы:
А здесь вообще элементом справочника Цвета:
Вот какие возможности открывает перед нами составной тип данных!
Интересно, как поведёт себя функция ТИПЗНАЧЕНИЯ на реквизите ОтличительныйПризнак, имеющий составной тип данных:
Это уже очень интересно. Давайте разбираться с каждой строкой в отдельности.
Тип значения отличительного признака для элемента Россия равен NULL. Мы впервые сталкиваемся с этим типом. Значения данного типа используются исключительно для определения отсутствующего значения при работе с базой данных.
Так и есть, ведь элемент Россия является группой, а не обычным элементом справочника Города, поэтому у него отсутствует поле ОтличительныйПризнак. А тип у отсутствующего значения, как мы прочитали выше, всегда равен NULL.
Тип значения отличительного признака для Перми равен Вкусы. Так и есть, ведь значение отличительного признака забитое в базе для города Пермь является ссылкой на элемент справочника Вкусы.
Для Красноярска тип признака равен Цвета, потому что значение выбранное в базе является ссылкой на элемент справочника Цвета.
Для Воронежа тип признака равен Строка, потому что значение введенное в базе является обычной строкой.
Индия снова группа, поэтому значение отсутствует. А тип у отсутствующего значения, как мы помним, равен NULL.
Далее всё аналогично, кроме Сан-Паулу. Это не группа, а обычный элемент справочника (город), но тип его значения пустой. Как так?
А дело вот в чём. Если вы зайдёте в элемент справочника Города с наименованием Сан-Паулу, то увидите, что поле ОтличительныйПризнак совершенно никак не заполнено. Оно пустое. А все незаполненные поля составного типа имеют специальное значение НЕОПРЕДЕЛЕНО .
С НЕОПРЕДЕЛЕНО мы также сталкиваемся впервые.
Значение НЕОПРЕДЕЛЕНО применяется, когда необходимо использовать пустое значение, не принадлежащее ни к одному другому типу. Это как раз наша ситуация.
А тип для значения, которое не принадлежит ни к одному из типов, как вы уже наверное догадались отсутствует.
Функция ТИП
Она принимает всего один параметр - имя примитивного типа (СТРОКА, ЧИСЛО, ДАТА, БУЛЕВО), либо имя таблицы, тип ссылки которой нужно получить.
Результатом данной конструкции будет значение типа Тип для указанного типа.
Звучит туманно, не правда ли?
Давайте рассмотрим применение данной конструкции и всё сразу станет на свои места.
Пусть нам требуется отобрать все записи справочника Города, у которых составной реквизит ОтличительныйПризнак имеет значение типа СТРОКА:
Теперь давайте отберём все записи, у которых значения реквизита ОтличительныйПризнак являются ссылками на элементы справочника Цвета (таблица Справочник.Цвета):
Отступление
Как вы помните, некоторые элементы справочника Города не имеют реквизита ОтличительныйПризнак. Функция ТИПЗНАЧЕНИЯ для таких элементов выдаёт NULL.
Как можно сделать отбор таких элементов в запросе? Для этого предусмотрен специальный логический оператор ЕСТЬ NULL (не путать с функцией ЕСТЬNULL, которую мы рассмотрим ниже). Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Вот пример его использования:
Но есть и такие элементы (Сан-Паулу), у которых реквизит ОтличительныйПризнак (составного типа) просто не заполнен и равен специальному значению НЕОПРЕДЕЛЕНО.
Чтобы отобрать такие записи следует использовать другую конструкцию:
Но сравнение с НЕОПРЕДЕЛЕНО для определения пустых (не заполненных) реквизитов будет работать только для составных типов.
Кстати, у логического оператора ЕСТЬ NULL форма отрицания выглядит следующим образом:
Логический оператор ССЫЛКА
Оператор ССЫЛКА позволяет проверить, является ли значение выражения, указанного слева от него, ссылкой на таблицу , указанную справа.
К примеру, давайте выберем из справочника Города только те записи, у которых значение составного реквизита ОтличительныйПризнак являются ссылкой на элемент справочника Вкусы:
Как вы помните, эту же задачу мы могли бы решить используя ТИПЗНАЧЕНИЯ и ТИП:
Функция ЕСТЬNULL
Функция предназначена для замены значения NULL на другое значение.
Мы помним, что значение NULL возвращается в том случае, если запрашиваемый реквизит (поле, свойство) не существует.
Как например, реквизит ОтличительныйПризнак для групп справочника Города:
Функция ЕСТЬNULL поможет нам вывести другое значение в том случае, если это значение равно NULL. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Пусть в данном случае это будет строка "Такого реквизита нет!":
Получается, что если первый параметр функции ЕСТЬNULL не равен NULL, то возвращается он. Если же он равен NULL, то возвращается второй параметр.
Функция ВЫРАЗИТЬ
Эта функция предназначена только для полей , имеющих составной тип . Отличным примером такого поля является свойство ОтличительныйПризнак у элементов справочника Города.
Как мы помним, составные поля могут быть одного из нескольких типов, указанных в конфигураторе.
Для поля ОтличительныйПризнак такими допустимыми типами являются СТРОКА, Справочник.Цвета и Справочник.Вкусы.
Иногда возникает необходимость привести значения составного поля к какому-либо определенному типу.
Давайте приведём все значения поля ОтличительныйПризнак к типу Справочник.Цвета:
В результате, все значения элементов, которые имели тип Справочник.Цвета, остались заполненными и оказались приведенными к указанному типу. Все значения других типов (СТРОКА, Справочник.Вкусы) теперь стали равны NULL. В этом состоит особенность приведения типа при помощи функции ВЫРАЗИТЬ.
Приводить тип можно или к примитивному типу (БУЛЕВО, ЧИСЛО, СТРОКА, ДАТА) или к ссылочному типу. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Но тип, к которому делается приведение, обязательно должен входить в список типов для данного составного поля, иначе система выдаст ошибку.
Войдите как ученик, чтобы получить доступ к материалам школы
Язык запросов 1С 8.3 для начинающих программистов: соединения
Автор уроков и преподаватель школы: Владимир Милькин
Соединения в запросах
Соединение - одна из самых важных и нужных операций, выполняемых реляционными системами управления базами данных.
Соединения используются для того, чтобы сопоставить строки одной таблицы строкам другой таблицы.
Для того, чтобы осознать необходимость соединений давайте решим следующую задачу.
У нас в базе есть справочник Клиенты:
И справочник Ассоциации:
Наша задача вывести любимые ассоциации клиентов, основываясь на цвете.
Таким образом для Наташи любимой ассоциацией будет трава, так как её любимый цвет зелёный. А для Петра - солнце. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
Для Андрея вообще нет подходящей ассоциации, так его любимый цвет красный, а ассоциаций красного цвета в базе нет.
Будем решать задачу постепенно.
Сначала запросим всех клиентов и их любимые цвета :
Затем запросим все ассоциации и их цвета :
Теперь нам каким-то образом следует совместить первую и вторую таблицу. Чтобы это сделать запросим информацию сразу из двух таблиц. Для этого перечислим обе таблицы в секции ИЗ через запятую. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. А в секции ВЫБРАТЬ укажем поля из обеих таблиц:
Если мы попробуем выполнить этот запрос, то получим ошибку:
Причина ошибки в том, что поле Наименование присутствует сразу в обеих таблицах (Клиенты и Ассоциации) и система просто не знает поле из какой именно таблицы имеется в виду.
Чтобы устранять подобные неоднозначности при выборке из более чем одной таблицы принято указывать полные названия полей. Полное название поля включает в себя полное имя таблицы (например, Справочник.Клиенты) и имя самого поля (например, Наименование).
Таким образом полное название поля Наименование из таблицы Клиенты будет Справочник.Клиенты.Наименование.
А полное названия поля Наименование из таблицы Ассоциации будет Справочник.Ассоциации.Наименование.
Перекрёстное соединение
Перепишем предыдущий запрос с полными именами полей:
Только что мы произвели перекрёстное соединение двух таблиц. Обратите внимание на то, каким образом сформировался результат:
Внутреннее соединение
Очевидно, что результат перекрестного соединения двух таблиц не есть решение нашей задачи. Нам нужны не все записи из перекрёстного соединения, а только те у которых поля ЛюбимыйЦвет и Цвет имеют одинаковое значение:
Чтобы получить эти записи добавим к предыдущему запросу секцию ГДЕ:
Это то, что нужно - мы решили, поставленную задачу!
В последнем запросе мы использовали перекрёстное соединение с дополнительным условием (в секции ГДЕ). Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Такое соединение называется внутренним .
Есть ещё один вариант написания того же самого внутреннего соединения :
Сравните этот и предыдущий запрос. Они совершенно одинаковы с точки зрения платформы, просто имеют разный синтаксис. И этот и предыдущий запросы содержат внутреннее соединение таблицы Клиенты с таблицей Ассоциации по полям ЛюбимыйЦвет и Цвет соответственно.
Левое внешнее соединение
Обратите внимание на то, что в результат внутреннего соединения не попал Андрей. А всё потому, что его любимый цвет красный, а красных ассоциаций у нас в базе нет вовсе.
Получается, что для Андрея с его красным цветом просто не нашлось пары из таблицы ассоциаций.
Перепишем запрос так, чтобы в результат попадали в том числе те записи из первой таблицы, для которых не нашлось ни одной пары из второй таблицы (в данном случае Андрей):
Такое соединение называется левым внешним соединением (слово внешнее можно опускать для простоты).
Р езультат левого внешнего соединения представляет из себя: все записи из внутреннего соединения ПЛЮС все записи из первой таблицы , не попавшие во внутреннее соединение (для которых не нашлось пары).
Правое внешнее соединение
Но давайте снова вернёмся к внутреннему соединению:
Обратите внимание на то, что результат внутреннего соединения не содержит ассоциацию белый снег, так как не нашлось ни одного клиента, у которого любимым цветом был бы белый.
Перепишем запрос так, чтобы в результат попадали в том числе те записи из второй таблицы, для которых не нашлась ни одной пары из первой таблицы (в данном случае белый снег):
Такое соединение называется правым внешним соединением (слово внешнее можно опускать для простоты).
Результат правого внешнего соединения представляет из себя: все записи из внутреннего соединения ПЛЮС все записи из второй таблицы , не попавшие во внутреннее соединение (для которых не нашлось пары).
Полное соединение
А что если нам нужно, чтобы в результат запроса попадали помимо внутреннего соединения Андрей и Снег одновременно?
Для этого потребуется совместить результаты левого и правого соединений. Такой вид соединения уже придуман и называется полным соединением:
Результат полного соединения представляет из себя: все записи из внутреннего соединения ПЛЮС все записи из первой таблицы, не попавшие во внутреннее соединение (для которых не нашлось пары) ПЛЮС все записи из второй таблицы, не попавшие во внутреннее соединение (для которых не нашлось пары).
Псевдонимы таблиц
Согласитесь, что все запросы, которые мы писали в этом уроке выглядят довольно громоздко. Это связано с тем, что мы вынуждены указывать полные имена полей, чтобы избежать возникновение неоднозначности.
Чтобы сократить полное написание имени таблицы (например, Справочник.Клиенты) допустимо (как и для самих полей) использовать псевдонимы .
Давайте перепишем последний запрос так, чтобы при формировании полных имён полей вместо Справочник.Клиенты можно было использовать псевдоним К, а вместо Справочник.Ассоциации - псевдоним А:
А чтобы результат запроса был ещё нагляднее добавим псевдонимы полей, которые мы уже рассматривали на одном из прошлых уроков:
Обработка NULL
Присмотритесь к результатам последнего запроса (как впрочем и многих предыдущих на этом уроке).
Чему равны значения полей Ассоциация и ЕёЦвет для первой строчки? А что вы скажете насчет полей Клиент и ЕгоЦвет для последней строки?
Они равны NULL, которое как мы уже знаем означает отсутствие какого либо значения:
А так как NULL означает отсутствие значения, то любая попытка выполнить с ним какую-либо операцию (сравнение, сложение . ) вызовет неопределенное поведение базы данных, непредсказуемую ошибку.
Поэтому обязательной считается обработка значений NULL всегда, когда они могут возникнуть.
Под обработкой подразумевается то, что мы должны сказать в нашем запросе, что если одно из полей будет равно NULL, то в это поле следует подставить какое-то другое значение.
В данном случае для полей Клиент и Ассоциация в случае обнаружения NULL мы будем подставлять пустую строку "".
А вот поля ЕгоЦвет и ЕёЦвет являются ссылками на элементы справочника Цвета, поэтому в них можно подставлять только значения являющиеся ссылками указанных типов. Каждый ссылочный тип (например, Справочник или Документ) имеет предопределенный элемент ПустаяСсылка. Чтобы указать его значение в запросе воспользуемся функцией ЗНАЧЕНИЕ.
Для определения того, что в поле попало NULL будем использовать уже знакомую нам по прошлым урокам функцию ЕСТЬNULL:
С виду (из консоли запросов) результат не изменился. Мы по-прежнему видим пустые поля. Но это только потому, что строковые представления у NULL и у пустых полей всех типов совпадают и равны пустой строке.
На самом же деле эти пустые поля уже не есть NULL (отсутствие значения), теперь в них появились значения (пустые), с которыми уже можно работать (совершать операции).
Запомните пустое значение и отсутствие значение - это две большие разницы.
Соединение более двух таблиц
Можно последовательно соединять сколько угодно таблиц.
Предположим нужно решить следующую задачу. Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь. Вывести все возможные варианты клиентов и их любимых ассоциаций и их любимых продуктов исходя из их любимого цвета.
Для этого последовательно соединим по цвету таблицу Клиенты с таблицей Ассоциации, а затем (получившийся результат) с таблицей Еда:
Читайте также: