Три собственные строки имеют единственный тип статуса. ЗНАЧЕНИЕ(Перечисление.УчебныйСтатус85.План) выбирает две, а ЗНАЧЕНИЕ(Справочник.УчебныеАдресаты85.ПустаяСсылка) возвращает типизированный пустой адрес.
Где и как запускать
Полный серверный общий модуль УчебныйЯзык новой собственной конфигурации УчебныеСсылки85 на 8.5.1.1343. Запросы в 1С здесь не запускались; Python — только модель фиксированных данных. Прикладные объекты не читаются и не записываются.
Подготовка
В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.
Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.
В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.
Все товары, количества и строки придуманы в этом модуле. Запись документов, подключение к чужой базе, файлы, сеть и печать не используются. В рабочие общие модули текст не вставляйте.
HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.
Создайте НОВУЮ отдельную пустую учебную информационную базу на платформе 8.5.1.1343, не копию рабочего приложения. Конфигурация: Имя=УчебныеСсылки85. Режим совместимости не должен включать ограничения старой версии. Не подключайте расширения и внешние обработчики; не создавайте записи прикладных объектов.
Конфигуратор → Справочники → создать УчебныеАдресаты85. Иерархический=Нет; Владельцы пусты; собственные Реквизиты и Табличные части пусты; Предопределенные данные пусты. Оставьте все модули объекта/менеджера пустыми. Стандартные поля платформы не удаляются и в опыте не читаются.
Конфигуратор → Документы → создать УчебнаяЗаявка85. Проведение=Запретить; собственные Реквизиты, Табличные части и Движения пусты. Все модули объекта/менеджера пусты; подписок и обработчиков нет. ПолучитьСсылку не создаёт документ-объект и не записывает его.
Конфигуратор → Перечисления → создать УчебныйСтатус85 → Значения: ровно План и Готов, с такими именами, не только синонимами. Никаких иных перечислений, справочников, документов, регистров, подписок, общих реквизитов, планов, бизнес-процессов и задач в собственном стенде не создавайте.
Основной код этого урока целиком заменяет модуль УчебныйЯзык: это один самостоятельный полный серверный общий модуль со всеми помощниками на его уровне. Для каждого следующего урока заменяйте этот модуль целиком; не склеивайте три экспортные процедуры с одинаковым именем.
В отдельной новой внешней обработке УчебныйПускЗначения85 создайте управляемую форму Форма и команду Выполнить; назначьте команде одноимённое действие и добавьте кнопку. Все остальные модули пусты. Полный отдельный модуль формы:
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Собственный опыт ссылочных значений завершён без записи");
КонецПроцедуры&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныйЯзык.ВыполнитьПример();
КонецПроцедурыОбновление новой собственной учебной конфигурации и ручной запуск делает читатель; здесь конфигурация, база и 1С не запускались. Guard читает только перечисленные свойства схемы и версию; он не проверяет тексты пустых модулей, расширения, предопределённые элементы или наличие записей. Это отдельные обязательные условия ручной подготовки.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойСтендСсылок();
План = Перечисления.УчебныйСтатус85.План;
Готов = Перечисления.УчебныйСтатус85.Готов;
ПустойАдресат = Справочники.УчебныеАдресаты85.ПустаяСсылка();
Если ТипЗнч(План) <> Тип("ПеречислениеСсылка.УчебныйСтатус85")
Или ТипЗнч(Готов) <> Тип("ПеречислениеСсылка.УчебныйСтатус85")
Или ТипЗнч(ПустойАдресат) <> Тип("СправочникСсылка.УчебныеАдресаты85") Тогда
ВызватьИсключение "Не совпали собственные типы статусов и пустого адреса";
КонецЕсли;
ПроверитьСвойВводСтатуса(1, План, 0);
ПроверитьСвойВводСтатуса(3, Готов, 9999);
ПроверитьОтклонениеСвоегоВводаСтатуса(1, Неопределено, 2);
ПроверитьОтклонениеСвоегоВводаСтатуса(1, "План", 2);
ПроверитьОтклонениеСвоегоВводаСтатуса(1, Перечисления.УчебныйСтатус85.ПустаяСсылка(), 2);
ПроверитьОтклонениеСвоегоВводаСтатуса("1", План, 2);
ПроверитьОтклонениеСвоегоВводаСтатуса(0, План, 2);
ПроверитьОтклонениеСвоегоВводаСтатуса(4, План, 2);
ПроверитьОтклонениеСвоегоВводаСтатуса(1, План, "2");
ПроверитьОтклонениеСвоегоВводаСтатуса(1, План, -1);
ПроверитьОтклонениеСвоегоВводаСтатуса(1, План, 10000);
ПроверитьОтклонениеСвоегоВводаСтатуса(1, План, 2.5);
Источник = Новый ТаблицаЗначений;
Источник.Колонки.Добавить("Код", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный)));
Источник.Колонки.Добавить("Статус", Новый ОписаниеТипов("ПеречислениеСсылка.УчебныйСтатус85"));
Источник.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(4, 0, ДопустимыйЗнак.Неотрицательный)));
ДобавитьСвойСтатус(Источник, 1, План, 2);
ДобавитьСвойСтатус(Источник, 2, Готов, 3);
ДобавитьСвойСтатус(Источник, 3, План, 4);
ОжиданияИсточника = Новый Массив;
ОжиданияИсточника.Добавить(Новый Структура("Код,Статус,Количество", 1, План, 2));
ОжиданияИсточника.Добавить(Новый Структура("Код,Статус,Количество", 2, Готов, 3));
ОжиданияИсточника.Добавить(Новый Структура("Код,Статус,Количество", 3, План, 4));
ПоляИсточника = Новый Массив;
ПоляИсточника.Добавить("Код");
ПоляИсточника.Добавить("Статус");
ПоляИсточника.Добавить("Количество");
ПроверитьСвоюПолнуюТаблицу(Источник, ОжиданияИсточника, ПоляИсточника);
Ожидания = Новый Массив;
Ожидания.Добавить(Новый Структура("Код,Статус,Количество,ПустойАдресат", 1, План, 2, ПустойАдресат));
Ожидания.Добавить(Новый Структура("Код,Статус,Количество,ПустойАдресат", 3, План, 4, ПустойАдресат));
Поля = Новый Массив;
Поля.Добавить("Код");
Поля.Добавить("Статус");
Поля.Добавить("Количество");
Поля.Добавить("ПустойАдресат");
Менеджер = Новый МенеджерВременныхТаблиц;
Попытка
Создание = Новый Запрос;
Создание.МенеджерВременныхТаблиц = Менеджер;
Создание.Текст = "ВЫБРАТЬ Данные.Код КАК Код, Данные.Статус КАК Статус, Данные.Количество КАК Количество
|ПОМЕСТИТЬ ВТСвоиСтатусы
|ИЗ &Источник КАК Данные";
Создание.УстановитьПараметр("Источник", Источник);
Создание.Выполнить();
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Менеджер;
Запрос.Текст = "ВЫБРАТЬ
| Данные.Код КАК Код,
| Данные.Статус КАК Статус,
| Данные.Количество КАК Количество,
| ЗНАЧЕНИЕ(Справочник.УчебныеАдресаты85.ПустаяСсылка) КАК ПустойАдресат
|ИЗ ВТСвоиСтатусы КАК Данные
|ГДЕ Данные.Статус = ЗНАЧЕНИЕ(Перечисление.УчебныйСтатус85.План)
|УПОРЯДОЧИТЬ ПО Код ВОЗР";
Таблица = Запрос.Выполнить().Выгрузить();
ПроверитьСвоюПолнуюТаблицу(Таблица, Ожидания, Поля);
ПроверитьСвоюПолнуюТаблицу(Источник, ОжиданияИсточника, ПоляИсточника);
Сообщить("Полный отбор собственного Плана: код1/количество2 и код3/количество4, в обеих строках своя пустая ссылка");
Исключение
Менеджер.Закрыть();
ВызватьИсключение;
КонецПопытки;
Менеджер.Закрыть();
КонецПроцедуры
Процедура ПроверитьСвойСтендСсылок()
Если Метаданные.Справочники.Количество() <> 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";
КонецЕсли;
Если ТипЗнч(Статус) <> Тип("ПеречислениеСсылка.УчебныйСтатус85") Тогда
ВызватьИсключение "Нужен только собственный тип статуса";
КонецЕсли;
Если Статус <> Перечисления.УчебныйСтатус85.План И Статус <> Перечисления.УчебныйСтатус85.Готов Тогда
ВызватьИсключение "Нужен заполненный собственный статус План или Готов";
КонецЕсли;
Если ТипЗнч(Количество) <> Тип("Число") Тогда
ВызватьИсключение "Своё количество должно иметь тип Число";
КонецЕсли;
Если Количество < 0 Или Количество > 9999 Или Количество <> Цел(Количество) Тогда
ВызватьИсключение "Своё количество должно быть целым от 0 до 9999";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьОтклонениеСвоегоВводаСтатуса(Код, Статус, Количество)
Отклонён = Ложь;
Попытка
ПроверитьСвойВводСтатуса(Код, Статус, Количество);
Исключение
Отклонён = Истина;
Сообщить("Ручной опыт: свой неверный статус или количество отклонены. " + ОписаниеОшибки());
КонецПопытки;
Если Не Отклонён Тогда
ВызватьИсключение "Ожидалось отклонение данного собственного ввода статуса";
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьСвойСтатус(Таблица, Код, Статус, Количество)
ПроверитьСвойВводСтатуса(Код, Статус, Количество);
СтрокаИсточника = Таблица.Добавить();
СтрокаИсточника.Код = Код;
СтрокаИсточника.Статус = Статус;
СтрокаИсточника.Количество = Количество;
КонецПроцедурыУчебныйПускЗначения85.Форма
Новая собственная внешняя обработка УчебныйПускЗначения85 → Управляемая форма Форма → Модуль
Отдельный полный модуль формы; клиент вызывает серверную процедуру без контекста, та вызывает УчебныйЯзык.ВыполнитьПример(). Не объединять с общим модулем.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Собственный опыт ссылочных значений завершён без записи");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныйЯзык.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
В новой пустой конфигурации создать именно УчебныйСтатус85 со значениями План и Готов и свой неиерархический справочник. Read-only guard проверяет имена/количество и перечисленные свойства до получения значений.
Значения менеджера перечисления доступны по именам настроенных значений и только для чтения. Получить План и Готов, проверить собственный ПеречислениеСсылка.УчебныйСтатус85; строка "План" не заменяет перечисление.
Получить пустую ссылку своего справочника нативным ПустаяСсылка и проверить конкретный тип. Она служит заранее заданным ожиданием для литерала запроса, не адресует существующий элемент.
Собственный валидатор проверяет типы перед диапазонами и до добавления: код целый1..3, статус только План/Готов, количество целое0..9999. Отдельно отклонить пустую ссылку перечисления — это наша политика заполненности, не ошибка типа.
Две положительные границы 0 и9999 и десять отрицательных примеров проверяют отсутствующий, строковый и пустой статус, плохие коды и строковое/отрицательное/слишком большое/дробное количество. Catch охватывает только валидатор.
Создать явно типизированные колонки: Код Число(1,0), Статус единственный ПеречислениеСсылка.УчебныйСтатус85, Количество Число(4,0), числа неотрицательные. Полный источник: 1/План/2,2/Готов/3,3/План/4.
Перед запросом сверить весь источник с тремя независимыми структурами ожидания. Каждая добавляемая строка заранее проверяется; не надеяться на автоматическое приведение в ТаблицаЗначений.
Простой запрос помещает источник в одну ВТСвоиСтатусы приватного менеджера без объединений, соединений и разыменования внешнего источника.
Литерал ЗНАЧЕНИЕ имеет форму ТипПредопределенногоЗначения.ИмяОбъектаМетаданных.Значение. Здесь имена именно конфигуратора: Перечисление.УчебныйСтатус85.План, не синонимы, не строки и не переменные BSL.
ГДЕ сравнивает собственный типизированный Статус со значением План. Строка Готов не проходит. В выбранную строку добавляется собственная пустая ссылка через ЗНАЧЕНИЕ(Справочник.УчебныеАдресаты85.ПустаяСсылка).
Явное Код ВОЗР фиксирует результат 1,3. Проверить все четыре поля обеих строк: Код1/План/Количество2/пустой адрес и Код3/План/Количество4/тот же пустой адрес, с точными типами.
Повторно проверить три исходные строки. Закрыть свой менеджер при успехе или перед повторным возбуждением неожиданной ошибки; все другие модули стенда остаются пустыми.
Полный отдельный модуль формы дан в preparation/supportingModules. Он не является частью исполняемого текста серверного общего модуля.
Как проверить результат
Полные строки результата: (1,Перечисления.УчебныйСтатус85.План,2,Справочники.УчебныеАдресаты85.ПустаяСсылка()) и (3,тот же План,4,та же пустая ссылка). Строка2/Готов/3 отсутствует.
Код и Количество строго Число, Статус строго ПеречислениеСсылка.УчебныйСтатус85, ПустойАдресат строго СправочникСсылка.УчебныеАдресаты85 и равен собственному пустому адресу.
Источник сохраняет все три строки/три поля и типы. Менеджер закрывается на обеих ветвях; запрос не пишет прикладные объекты.
Две границы принимаются, десять плохих входов должны отклониться собственным валидатором при будущем ручном запуске до добавления данных.
Ожидаемый результат
Два литерала ЗНАЧЕНИЕ показаны в реальном собственном отборе и выборе пустого адреса; все поля двух результатов проверяются, не только количество.
На что обратить внимание
Допустимые нативные типы предопределённых значений: Справочник, ПланВидовХарактеристик, ПланСчетов, ПланВидовРасчета и Перечисление. Документ в этом списке не указан, поэтому урок не обещает ЗНАЧЕНИЕ(Документ.ПустаяСсылка).
Системные перечисления в запросе ограничены тремя названными native: ВидДвиженияНакопления, ВидСчета и ВидДвиженияБухгалтерии. Это не разрешение подставлять любое системное перечисление BSL.
Для собственного перечисления используется имя значения метаданных; для других перечисленных типов — имя предопределённого элемента либо ПустаяСсылка. Мы не создаём предопределённый элемент и не утверждаем наличие записей.
Готов — типизированное значение собственного перечисления, не статус рабочего документа. Таблицы конфигурации не используются как источник.
Python моделирует только фиксированные данные и полный отбор собственных ожиданий. Прямое чтение установленной справки — доказательство текста контракта, не выполнения запроса в 1С.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.