Оператор проверки ссылочного значения

Язык запросов

Синтаксис и применение Оператор проверки ссылочного значения в платформе 1С:Предприятие. Описание и примеры кода.

Полное описание, параметры и ограничения

Оператор проверки ссылочного значения

Оператор ССЫЛКА позволяет проверить, является ли значение выражения, указанного справа от него, ссылкой на таблицу, указанную слева. Если да – результатом оператора будет ИСТИНА, иначе – ЛОЖЬ. Разыменование таблиц описано в главе Разыменование полей.

см. также: Логические выражения

Пример:

ВЫБРАТЬ
Справочник.Номенклатура.Наименование,
Справочник.Номенклатура.ЕдиницаИзмерения
ГДЕ
Справочник.Номенклатура.ЕдиницаИзмерения ССЫЛКА Справочник.ЕдиницыИзмерения

Практические примеры

ССЫЛКА: отделить тип собственного адреса от существования записи

Три собственных значения — адрес справочника, адрес документа и число 7 — объединяются только после раздельной загрузки в приватные ВТ. Два булевых признака проверяют тип, не читают объекты.

Где и как запускать

Полный серверный общий модуль УчебныйЯзык новой собственной конфигурации УчебныеСсылки85 на 8.5.1.1343. Запросы в 1С здесь не запускались; Python — только модель фиксированных данных. Прикладные объекты не читаются и не записываются.

Подготовка

  1. В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.

  2. Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.

  3. В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.

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

  5. HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.

  6. Создайте НОВУЮ отдельную пустую учебную информационную базу на платформе 8.5.1.1343, не копию рабочего приложения. Конфигурация: Имя=УчебныеСсылки85. Режим совместимости не должен включать ограничения старой версии. Не подключайте расширения и внешние обработчики; не создавайте записи прикладных объектов.

  7. Конфигуратор → Справочники → создать УчебныеАдресаты85. Иерархический=Нет; Владельцы пусты; собственные Реквизиты и Табличные части пусты; Предопределенные данные пусты. Оставьте все модули объекта/менеджера пустыми. Стандартные поля платформы не удаляются и в опыте не читаются.

  8. Конфигуратор → Документы → создать УчебнаяЗаявка85. Проведение=Запретить; собственные Реквизиты, Табличные части и Движения пусты. Все модули объекта/менеджера пусты; подписок и обработчиков нет. ПолучитьСсылку не создаёт документ-объект и не записывает его.

  9. Конфигуратор → Перечисления → создать УчебныйСтатус85 → Значения: ровно План и Готов, с такими именами, не только синонимами. Никаких иных перечислений, справочников, документов, регистров, подписок, общих реквизитов, планов, бизнес-процессов и задач в собственном стенде не создавайте.

  10. Основной код этого урока целиком заменяет модуль УчебныйЯзык: это один самостоятельный полный серверный общий модуль со всеми помощниками на его уровне. Для каждого следующего урока заменяйте этот модуль целиком; не склеивайте три экспортные процедуры с одинаковым именем.

  11. В отдельной новой внешней обработке УчебныйПускТиповСсылок85 создайте управляемую форму Форма и команду Выполнить; назначьте команде одноимённое действие и добавьте кнопку. Все остальные модули пусты. Полный отдельный модуль формы:

    &НаКлиенте
    Процедура Выполнить(Команда)
    ВыполнитьНаСервере();
    Сообщить("Собственный опыт ссылочных значений завершён без записи");
    КонецПроцедуры

    &НаСервереБезКонтекста
    Процедура ВыполнитьНаСервере()
    УчебныйЯзык.ВыполнитьПример();
    КонецПроцедуры

  12. Обновление новой собственной учебной конфигурации и ручной запуск делает читатель; здесь конфигурация, база и 1С не запускались. Guard читает только перечисленные свойства схемы и версию; он не проверяет тексты пустых модулей, расширения, предопределённые элементы или наличие записей. Это отдельные обязательные условия ручной подготовки.

Процедура ВыполнитьПример() Экспорт
    ПроверитьСвойСтендСсылок();
    UUIDАдресата = Новый УникальныйИдентификатор("11111111-1111-1111-1111-111111111111");
    UUIDЗаявки = Новый УникальныйИдентификатор("22222222-2222-2222-2222-222222222222");
    Адресат = Справочники.УчебныеАдресаты85.ПолучитьСсылку(UUIDАдресата);
    Заявка = Документы.УчебнаяЗаявка85.ПолучитьСсылку(UUIDЗаявки);
    Если ТипЗнч(Адресат) <> Тип("СправочникСсылка.УчебныеАдресаты85")
        Или ТипЗнч(Заявка) <> Тип("ДокументСсылка.УчебнаяЗаявка85") Тогда
        ВызватьИсключение "Не совпали типы двух собственных ссылочных значений";
    КонецЕсли;
    Если Адресат.УникальныйИдентификатор() <> UUIDАдресата Или Заявка.УникальныйИдентификатор() <> UUIDЗаявки Тогда
        ВызватьИсключение "Собственные ссылки не сохранили заданные идентификаторы";
    КонецЕсли;
    ПроверитьСвойВводСсылки(1, Справочники.УчебныеАдресаты85.ПустаяСсылка());
    ПроверитьСвойВводСсылки(3, 7);
    ПроверитьОтклонениеСвоегоВводаСсылки("1", Адресат);
    ПроверитьОтклонениеСвоегоВводаСсылки(0, Адресат);
    ПроверитьОтклонениеСвоегоВводаСсылки(4, Адресат);
    ПроверитьОтклонениеСвоегоВводаСсылки(1.5, Адресат);
    ПроверитьОтклонениеСвоегоВводаСсылки(1, Неопределено);
    ПроверитьОтклонениеСвоегоВводаСсылки(1, Заявка);
    ПроверитьОтклонениеСвоегоВводаСсылки(3, "7");
    ПроверитьОтклонениеСвоегоВводаСсылки(3, 8);
    ИсточникАдресат = СоздатьСвойИсточникСсылки(1, Адресат);
    ИсточникЗаявка = СоздатьСвойИсточникСсылки(2, Заявка);
    ИсточникЧисло = СоздатьСвойИсточникСсылки(3, 7);
    ОжиданиеАдресат = Новый Массив;
    ОжиданиеАдресат.Добавить(Новый Структура("Код,Значение", 1, Адресат));
    ОжиданиеЗаявка = Новый Массив;
    ОжиданиеЗаявка.Добавить(Новый Структура("Код,Значение", 2, Заявка));
    ОжиданиеЧисло = Новый Массив;
    ОжиданиеЧисло.Добавить(Новый Структура("Код,Значение", 3, 7));
    ПоляИсточника = Новый Массив;
    ПоляИсточника.Добавить("Код");
    ПоляИсточника.Добавить("Значение");
    ПроверитьСвоюПолнуюТаблицу(ИсточникАдресат, ОжиданиеАдресат, ПоляИсточника);
    ПроверитьСвоюПолнуюТаблицу(ИсточникЗаявка, ОжиданиеЗаявка, ПоляИсточника);
    ПроверитьСвоюПолнуюТаблицу(ИсточникЧисло, ОжиданиеЧисло, ПоляИсточника);
    Ожидания = Новый Массив;
    Ожидания.Добавить(Новый Структура("Код,Значение,ЭтоАдресат,ЭтоЗаявка", 1, Адресат, Истина, Ложь));
    Ожидания.Добавить(Новый Структура("Код,Значение,ЭтоАдресат,ЭтоЗаявка", 2, Заявка, Ложь, Истина));
    Ожидания.Добавить(Новый Структура("Код,Значение,ЭтоАдресат,ЭтоЗаявка", 3, 7, Ложь, Ложь));
    Поля = Новый Массив;
    Поля.Добавить("Код");
    Поля.Добавить("Значение");
    Поля.Добавить("ЭтоАдресат");
    Поля.Добавить("ЭтоЗаявка");
    Менеджер = Новый МенеджерВременныхТаблиц;
    Попытка
        ПоместитьСвойИсточникСсылки(Менеджер, ИсточникАдресат, "ВТСвояСсылкаСправочника");
        ПоместитьСвойИсточникСсылки(Менеджер, ИсточникЗаявка, "ВТСвояСсылкаДокумента");
        ПоместитьСвойИсточникСсылки(Менеджер, ИсточникЧисло, "ВТСвоёЧисло");
        Запрос = Новый Запрос;
        Запрос.МенеджерВременныхТаблиц = Менеджер;
        Запрос.Текст = "ВЫБРАТЬ
        |    Данные.Код КАК Код,
        |    Данные.Значение КАК Значение,
        |    Данные.Значение ССЫЛКА Справочник.УчебныеАдресаты85 КАК ЭтоАдресат,
        |    Данные.Значение ССЫЛКА Документ.УчебнаяЗаявка85 КАК ЭтоЗаявка
        |ИЗ (ВЫБРАТЬ Код, Значение ИЗ ВТСвояСсылкаСправочника
        |    ОБЪЕДИНИТЬ ВСЕ
        |    ВЫБРАТЬ Код, Значение ИЗ ВТСвояСсылкаДокумента
        |    ОБЪЕДИНИТЬ ВСЕ
        |    ВЫБРАТЬ Код, Значение ИЗ ВТСвоёЧисло) КАК Данные
        |УПОРЯДОЧИТЬ ПО Код ВОЗР";
        Таблица = Запрос.Выполнить().Выгрузить();
        ПроверитьСвоюПолнуюТаблицу(Таблица, Ожидания, Поля);
        ПроверитьСвоюПолнуюТаблицу(ИсточникАдресат, ОжиданиеАдресат, ПоляИсточника);
        ПроверитьСвоюПолнуюТаблицу(ИсточникЗаявка, ОжиданиеЗаявка, ПоляИсточника);
        ПроверитьСвоюПолнуюТаблицу(ИсточникЧисло, ОжиданиеЧисло, ПоляИсточника);
        Сообщить("Полные три строки: адресат Истина/Ложь, заявка Ложь/Истина, число Ложь/Ложь");
    Исключение
        Менеджер.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Менеджер.Закрыть();
КонецПроцедуры

Процедура ПроверитьСвойСтендСсылок()
    Если Метаданные.Справочники.Количество() <> 1 Или Метаданные.Документы.Количество() <> 1 Или Метаданные.Перечисления.Количество() <> 1 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен именно собственный минимальный стенд УчебныеСсылки85";
    КонецЕсли;
    МетаАдресат = Метаданные.Справочники.Найти("УчебныеАдресаты85");
    МетаЗаявка = Метаданные.Документы.Найти("УчебнаяЗаявка85");
    МетаСтатус = Метаданные.Перечисления.Найти("УчебныйСтатус85");
    Если МетаАдресат = Неопределено Или МетаЗаявка = Неопределено Или МетаСтатус = Неопределено Тогда
        ВызватьИсключение "Не найдены три собственных объекта метаданных";
    КонецЕсли;
    Если МетаАдресат.Иерархический Или МетаАдресат.Владельцы.Количество() <> 0
        Или МетаАдресат.Реквизиты.Количество() <> 0 Или МетаАдресат.ТабличныеЧасти.Количество() <> 0 Тогда
        ВызватьИсключение "Свой справочник должен быть неиерархическим, без владельцев и собственных полей";
    КонецЕсли;
    Если МетаЗаявка.Проведение <> Метаданные.СвойстваОбъектов.Проведение.Запретить
        Или МетаЗаявка.Реквизиты.Количество() <> 0 Или МетаЗаявка.ТабличныеЧасти.Количество() <> 0
        Или МетаЗаявка.Движения.Количество() <> 0 Тогда
        ВызватьИсключение "Свой документ должен быть без проведения, движений и собственных полей";
    КонецЕсли;
    Если МетаСтатус.ЗначенияПеречисления.Количество() <> 2
        Или МетаСтатус.ЗначенияПеречисления.Найти("План") = Неопределено
        Или МетаСтатус.ЗначенияПеречисления.Найти("Готов") = Неопределено Тогда
        ВызватьИсключение "Свой статус должен иметь ровно два значения План и Готов";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвоюПолнуюТаблицу(Таблица, Ожидания, Поля)
    Если Таблица.Колонки.Количество() <> Поля.Количество() Или Таблица.Количество() <> Ожидания.Количество() Тогда
        ВызватьИсключение "Не совпали все размеры собственного результата";
    КонецЕсли;
    Для Каждого ИмяПоля Из Поля Цикл
        Если Таблица.Колонки.Найти(ИмяПоля) = Неопределено Тогда
            ВызватьИсключение "Не найдена собственная ожидаемая колонка " + ИмяПоля;
        КонецЕсли;
    КонецЦикла;
    Если Ожидания.Количество() > 0 Тогда
        Для Индекс = 0 По Ожидания.Количество() - 1 Цикл
            Для Каждого ИмяПоля Из Поля Цикл
                Если Не Ожидания[Индекс].Свойство(ИмяПоля, Ожидаемое) Тогда
                    ВызватьИсключение "Не найдено собственное ожидаемое поле " + ИмяПоля;
                КонецЕсли;
                Колонка = Таблица.Колонки.Найти(ИмяПоля);
                ИндексКолонки = Таблица.Колонки.Индекс(Колонка);
                Фактическое = Таблица[Индекс].Получить(ИндексКолонки);
                Если ТипЗнч(Фактическое) <> ТипЗнч(Ожидаемое) Тогда
                    ВызватьИсключение "Не совпал точный тип поля " + ИмяПоля;
                КонецЕсли;
                Если ТипЗнч(Ожидаемое) <> Тип("Null") Тогда
                    Если Фактическое <> Ожидаемое Тогда
                        ВызватьИсключение "Не совпало собственное значение поля " + ИмяПоля;
                    КонецЕсли;
                КонецЕсли;
            КонецЦикла;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвойВводСсылки(Код, Значение)
    Если ТипЗнч(Код) <> Тип("Число") Тогда
        ВызватьИсключение "Свой код должен иметь тип Число";
    КонецЕсли;
    Если Код < 1 Или Код > 3 Или Код <> Цел(Код) Тогда
        ВызватьИсключение "Свой код должен быть целым от 1 до 3";
    КонецЕсли;
    Если Код = 1 Тогда
        Если ТипЗнч(Значение) <> Тип("СправочникСсылка.УчебныеАдресаты85") Тогда
            ВызватьИсключение "Код 1 принимает только ссылку собственного справочника";
        КонецЕсли;
    ИначеЕсли Код = 2 Тогда
        Если ТипЗнч(Значение) <> Тип("ДокументСсылка.УчебнаяЗаявка85") Тогда
            ВызватьИсключение "Код 2 принимает только ссылку собственного документа";
        КонецЕсли;
    Иначе
        Если ТипЗнч(Значение) <> Тип("Число") Тогда
            ВызватьИсключение "Код 3 принимает только собственное число 7";
        КонецЕсли;
        Если Значение <> 7 Тогда
            ВызватьИсключение "Собственное числовое значение должно равняться 7";
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьОтклонениеСвоегоВводаСсылки(Код, Значение)
    Отклонён = Ложь;
    Попытка
        ПроверитьСвойВводСсылки(Код, Значение);
    Исключение
        Отклонён = Истина;
        Сообщить("Ручной опыт: собственный неверный ввод отклонён. " + ОписаниеОшибки());
    КонецПопытки;
    Если Не Отклонён Тогда
        ВызватьИсключение "Ожидалось отклонение данного собственного ввода";
    КонецЕсли;
КонецПроцедуры

Функция СоздатьСвойИсточникСсылки(Код, Значение)
    ПроверитьСвойВводСсылки(Код, Значение);
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Код", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный)));
    Если Код = 3 Тогда
        Таблица.Колонки.Добавить("Значение", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный)));
    Иначе
        ТипыЗначения = Новый Массив;
        ТипыЗначения.Добавить(ТипЗнч(Значение));
        Таблица.Колонки.Добавить("Значение", Новый ОписаниеТипов(ТипыЗначения));
    КонецЕсли;
    СтрокаИсточника = Таблица.Добавить();
    СтрокаИсточника.Код = Код;
    СтрокаИсточника.Значение = Значение;
    Возврат Таблица;
КонецФункции

Процедура ПоместитьСвойИсточникСсылки(Менеджер, Источник, ИмяВТ)
    Если ИмяВТ <> "ВТСвояСсылкаСправочника" И ИмяВТ <> "ВТСвояСсылкаДокумента" И ИмяВТ <> "ВТСвоёЧисло" Тогда
        ВызватьИсключение "Разрешены только три собственных имени временных таблиц";
    КонецЕсли;
    Создание = Новый Запрос;
    Создание.МенеджерВременныхТаблиц = Менеджер;
    Создание.Текст = "ВЫБРАТЬ Данные.Код КАК Код, Данные.Значение КАК Значение
    |ПОМЕСТИТЬ " + ИмяВТ + "
    |ИЗ &Источник КАК Данные";
    Создание.УстановитьПараметр("Источник", Источник);
    Создание.Выполнить();
КонецПроцедуры
УчебныйПускТиповСсылок85.Форма

Новая собственная внешняя обработка УчебныйПускТиповСсылок85 → Управляемая форма Форма → Модуль

Отдельный полный модуль формы; клиент вызывает серверную процедуру без контекста, та вызывает УчебныйЯзык.ВыполнитьПример(). Не объединять с общим модулем.

&НаКлиенте
Процедура Выполнить(Команда)
    ВыполнитьНаСервере();
    Сообщить("Собственный опыт ссылочных значений завершён без записи");
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
    УчебныйЯзык.ВыполнитьПример();
КонецПроцедуры

Разбор по шагам

  1. Подготовить только новый описанный стенд и полный серверный общий модуль. Read-only guard проверяет версию, имена/количество объектов, отсутствие собственных полей и запрет проведения до формирования ссылок.

  2. Два фиксированных UUID преобразовать настоящими менеджерами ПолучитьСсылку в свои СправочникСсылка.УчебныеАдресаты85 и ДокументСсылка.УчебнаяЗаявка85. Проверить типы и UUID ссылок; ни создание объектов, ни поиск, ни чтение не выполняются.

  3. Это адресные значения собственной схемы: одинаковый UUID другого вида ссылок не заменяет нужный тип. Существование записей по адресам не утверждается.

  4. Свой валидатор принимает целые коды 1..3: код1 — только собственный справочник, код2 — только свой документ, код3 — только число7. Эти соответствия — наше правило источника, не ограничение оператора ССЫЛКА.

  5. Пустая ссылка собственного справочника допустима валидатору как ссылочное значение. Восемь отрицательных проверок проверяют неверный/граничный код, отсутствующий или иной тип и несогласованное число до добавления строки; catch только вокруг валидатора.

  6. Создать три отдельные ТаблицаЗначений с единственным конкретным типом Значение и Число(1,0) для Кода. Для числового Значения также явно задать КвалификаторыЧисла(1,0): native ОписаниеТипов запрещает хранить числа без числового квалификатора. Каждая таблица содержит одну заранее заданную строку; проверить оба поля и типы.

  7. Каждый внешний источник помещается простым запросом в отдельную ВТ одного своего менеджера. ИмяВТ проходит белый список трёх констант; данные передаются параметром, не вставляются в текст.

  8. Native INTO запрещает объединение и соединение при создании ВТ из внешнего источника. Здесь ОБЪЕДИНИТЬ ВСЕ используется лишь над тремя уже существующими ВТ внутри производной таблицы.

  9. Нативная грамматика: <Выражение> ССЫЛКА <Имя таблицы>. Слева своё значение, справа Справочник.УчебныеАдресаты85 или Документ.УчебнаяЗаявка85. Поле выбирается целиком без разыменования.

  10. Объединение даёт составной столбец Значение, а две проверки типа создают флаги ЭтоАдресат и ЭтоЗаявка. Число7 не является ни одним из двух видов ссылок и даёт Ложь/Ложь.

  11. Явное УПОРЯДОЧИТЬ ПО Код ВОЗР фиксирует 1,2,3. Проверить имена/число четырёх колонок и все значения/типы трёх строк, включая два точных Булево, не только количество.

  12. Повторно проверить все исходные таблицы по отдельным неизменённым ожиданиям. Менеджер закрывается и при успехе, и перед повторным возбуждением неожиданной ошибки.

  13. Модуль формы запуска дан полностью отдельно от серверного модуля. Здесь не выполнялись запросы и не подтверждалось наличие адресованных объектов.

Как проверить результат

  1. Полный результат: (1,собственный адрес справочника 11111111-1111-1111-1111-111111111111,Истина,Ложь); (2,собственный адрес документа 22222222-2222-2222-2222-222222222222,Ложь,Истина); (3,Число7,Ложь,Ложь).

  2. Каждый Код имеет тип Число; значения — конкретный собственный ссылочный тип либо Число; каждый флаг строго Булево. Все четырёхполевые строки сверяются полностью.

  3. Три однотипных источника сохраняют оба поля и типы после запроса. Менеджер освобождает только собственные ВТ.

  4. Две положительные границы и восемь плохих входов проверяют собственный валидатор в будущем ручном опыте; ошибка запроса не считается успешной проверкой результата.

Ожидаемый результат

Оператор ССЫЛКА проверен на конкретных ссылочных типах и нессылочном значении полностью заданного источника, без проверки существования записей.

На что обратить внимание

  1. В тексте страницы REFS слова справа/слева переставлены. Её пример и нативная грамматика condition_expressions.html согласованы: значение ССЫЛКА таблица. Урок использует именно эту грамматику, не исправляет оригинал.

  2. ССЫЛКА — не ПолучитьОбъект, не запрос существования и не разрешение читать реквизиты. Таблицы Справочник/Документ справа — указания типа; в ИЗ только собственные ВТ.

  3. Не прикрепляем урок к REFPRESENTATION: представление несуществующего адреса здесь не обещается.

  4. Python моделирует только фиксированные данные и полный ожидаемый состав. Сверка установленного HBK подтверждает текст контрактов, не исполнение BSL или запроса в 1С.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.