Два полных текста RU/EN вычисляют суффикс/год, отбирают2026и количество≥5, явно сортируют и отдельно проверяют все поля двух результатов. Третий/четвёртый исходы показывают разные причины отбора.
Где и как запускать
Полный серверный общий модуль УчебныйЯзык только нового собственного стенда УчебныеИерархическиеИтоги85 на 8.5.1.1343. BSL, запросы и транзакции здесь не исполнялись.
Подготовка
В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.
Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.
В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.
HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.
Создайте НОВУЮ отдельную пустую учебную базу, не копию приложения, на точной 8.5.1.1343. Конфигурация УчебныеИерархическиеИтоги85; совместимость отключена; единственный сеанс. Нет расширений базы/сеанса, подписок, общих реквизитов, документов, регистров, планов, последовательностей, фоновых заданий или внешних источников данных. Ошибки прав/схемы не являются ожидаемым результатом опыта.
Справочники → УчебноеДерево85: Иерархический=Да; Вид иерархии=Иерархия групп и элементов; Ограничивать количество уровней=Нет; Владельцы пусты. Код только Строка, длина3; Автонумерация=Нет; Наименование длина20. Собственных реквизитов, табчастей и предопределённых элементов нет. Стандартные поля платформы остаются.
Все объектные/менеджерские модули, формы, модули сеанса/приложения и обработчики вручную полностью пусты. Native МодульОбъекта и МодульМенеджера всегда Неопределено и не позволяют прочитать текст BSL: guard не выдаёт это значение за доказательство пустого модуля. Это обязательная проверка читателя в новом Конфигураторе; здесь Конфигуратор не запускался.
Read-only guard проверяет минимальную схему, пустой ФиксированныйМассив предопределённых имён, пустые массивы трёх источников расширений БазаДанных/СеансАктивные/СеансОтключенные и отсутствие изменений метаданных расширениями. До действий запрещена чужая/вложенная транзакция и проверен Число0 собственных записей без их удаления.
Основной код целиком заменяет свой серверный общий модуль УчебныйЯзык; все helpers расположены рядом с экспортной процедурой, не внутри неё. У модуля Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь; клиентские/внешнее соединение отключены, повторное использование выключено. Для следующего урока замените модуль целиком, не объединяйте одноимённые экспортные точки.
Новая собственная внешняя обработка УчебныйПускДвуязычныхМеток85 → управляемая Форма → команда Выполнить и кнопка с одноимённым действием. Остальные модули пусты. Полный отдельный модуль формы:
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Полные собственные проверки завершены; учебных записей не осталось");
КонецПроцедуры&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныйЯзык.ВыполнитьПример();
КонецПроцедурыЭтот урок не создаёт прикладных записей и не начинает транзакцию: ровно4полностью заданные типизированные строки находятся в своей таблице памяти/приватной ВТ. Менеджер закрывается на обеих ветвях; собственный справочник остаётся пустым.
Python моделирует только фиксированные входы, полные ожидания и нашу проверку состава/дерева. Direct HBK подтверждает нативный текст установленной версии, но ни он, ни focused/static tests не доказывают исполнение BSL/запросов/отката в 1С.
Общий обязательный этап перед первым ручным запуском каждого урока: после ВСЕХ настроек метаданных, флагов общего модуля, вставки полного основного модуля и подготовки полного модуля своей формы сохраните свою конфигурацию. Завершите свой предыдущий учебный сеанс; активной транзакции и выполняющегося учебного опыта быть не должно. В Конфигураторе своего стенда выполните Конфигурация → Обновить конфигурацию базы данных (F7), подтвердите только изменения своей новой учебной конфигурации и дождитесь успешного завершения обновления. Затем запустите свежий учебный сеанс и только в нём нажимайте Выполнить. Здесь F7 означает только обновление конфигурации базы данных автором стенда ДО ручного запуска, никогда не аварийный опыт и не действие после пяти Записать внутри активной транзакции. Сохранение/обновление/1С здесь не выполнялись.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойИерархическийСтенд();
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая активная транзакция запрещена даже для своего опыта ВТ";
КонецЕсли;
ПроверитьОтсутствиеСвоихЗаписей();
Менеджер = Неопределено;
Попытка
Менеджер = Новый МенеджерВременныхТаблиц;
ПроверитьСвоеКоличество(0);
ПроверитьСвоеКоличество(9999);
ПроверитьОтклонениеСвоегоКоличества(Неопределено);
ПроверитьОтклонениеСвоегоКоличества("5");
ПроверитьОтклонениеСвоегоКоличества(-1);
ПроверитьОтклонениеСвоегоКоличества(10000);
ПроверитьОтклонениеСвоегоКоличества(5.5);
ПроверитьСвойВводМетки("A:ab", Дата(2026,10,6,12,0,0), 0);
ПроверитьСвойВводМетки("CC:Gamma", Дата(2026,10,8,12,0,0), 9999);
ПроверитьОтклонениеСвоейМетки(Неопределено, Дата(2026,10,6,12,0,0), 2);
ПроверитьОтклонениеСвоейМетки(7, Дата(2026,10,6,12,0,0), 2);
ПроверитьОтклонениеСвоейМетки("ABC", Дата(2026,10,6,12,0,0), 2);
ПроверитьОтклонениеСвоейМетки("ABCDEFGHI", Дата(2026,10,6,12,0,0), 2);
ПроверитьОтклонениеСвоейМетки("AA:Alba", "06.10.2026", 2);
ПроверитьОтклонениеСвоейМетки("AA:Alba", Неопределено, 2);
ПроверитьОтклонениеСвоегоОтбора(Неопределено, 5);
ПроверитьОтклонениеСвоегоОтбора("2026", 5);
ПроверитьОтклонениеСвоегоОтбора(2025, 5);
ПроверитьОтклонениеСвоегоОтбора(2026.5, 5);
ПроверитьОтклонениеСвоегоОтбора(2026, "5");
ГодОтбора = 2026;
Минимум = 5;
ПроверитьСвойОтборМеток(ГодОтбора, Минимум);
Источник = Новый ТаблицаЗначений;
Источник.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(8, ДопустимаяДлина.Переменная)));
Источник.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
Источник.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(4, 0, ДопустимыйЗнак.Неотрицательный)));
ПроверитьСвоюТипизированнуюКолонку(Источник, "Код", Тип("Строка"));
ПроверитьСвоюТипизированнуюКолонку(Источник, "Дата", Тип("Дата"));
ПроверитьСвойЧисловойКвалификатор(Источник);
ОжиданияИсточника = Новый Массив;
ОжиданияИсточника.Добавить(Новый Структура("Код,Дата,Количество", "AA:Alba", Дата(2026, 10, 6, 12, 0, 0), 2));
ОжиданияИсточника.Добавить(Новый Структура("Код,Дата,Количество", "BB:Beta", Дата(2026, 10, 7, 12, 0, 0), 5));
ОжиданияИсточника.Добавить(Новый Структура("Код,Дата,Количество", "CC:Gamma", Дата(2026, 10, 8, 12, 0, 0), 7));
ОжиданияИсточника.Добавить(Новый Структура("Код,Дата,Количество", "DD:Delta", Дата(2025, 10, 9, 12, 0, 0), 9));
ПроверитьСвойВводМетки("AA:Alba", Дата(2026, 10, 6, 12, 0, 0), 2);
Строка = Источник.Добавить();
Строка.Код = "AA:Alba";
Строка.Дата = Дата(2026, 10, 6, 12, 0, 0);
Строка.Количество = 2;
ПроверитьСвойВводМетки("BB:Beta", Дата(2026, 10, 7, 12, 0, 0), 5);
Строка = Источник.Добавить();
Строка.Код = "BB:Beta";
Строка.Дата = Дата(2026, 10, 7, 12, 0, 0);
Строка.Количество = 5;
ПроверитьСвойВводМетки("CC:Gamma", Дата(2026, 10, 8, 12, 0, 0), 7);
Строка = Источник.Добавить();
Строка.Код = "CC:Gamma";
Строка.Дата = Дата(2026, 10, 8, 12, 0, 0);
Строка.Количество = 7;
ПроверитьСвойВводМетки("DD:Delta", Дата(2025, 10, 9, 12, 0, 0), 9);
Строка = Источник.Добавить();
Строка.Код = "DD:Delta";
Строка.Дата = Дата(2025, 10, 9, 12, 0, 0);
Строка.Количество = 9;
ПоляИсточника = Новый Массив;
ПоляИсточника.Добавить("Код");
ПоляИсточника.Добавить("Дата");
ПоляИсточника.Добавить("Количество");
ПроверитьСвоюПолнуюТаблицу(Источник, ОжиданияИсточника, ПоляИсточника, Ложь);
Загрузка = Новый Запрос;
Загрузка.МенеджерВременныхТаблиц = Менеджер;
Загрузка.Текст = "ВЫБРАТЬ Ист.Код КАК Код, Ист.Дата КАК Дата, Ист.Количество КАК Количество ПОМЕСТИТЬ СвоиМетки ИЗ &Источник КАК Ист";
Загрузка.УстановитьПараметр("Источник", Источник);
Загрузка.Выполнить();
ПроверитьСвоиИсходныеМетки(Менеджер, Источник, ОжиданияИсточника);
Ожидания = Новый Массив;
Ожидания.Добавить(Новый Структура("Код,Имя,Год,Дата,Количество", "CC:Gamma", "Gamma", 2026, Дата(2026, 10, 8, 12, 0, 0), 7));
Ожидания.Добавить(Новый Структура("Код,Имя,Год,Дата,Количество", "BB:Beta", "Beta", 2026, Дата(2026, 10, 7, 12, 0, 0), 5));
Поля = Новый Массив;
Поля.Добавить("Код");
Поля.Добавить("Имя");
Поля.Добавить("Год");
Поля.Добавить("Дата");
Поля.Добавить("Количество");
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Менеджер;
Запрос.Текст = "ВЫБРАТЬ Метка.Код КАК Код, ПОДСТРОКА(Метка.Код,4,5) КАК Имя,
|ГОД(Метка.Дата) КАК Год, Метка.Дата КАК Дата, Метка.Количество КАК Количество
|ИЗ СвоиМетки КАК Метка
|ГДЕ ГОД(Метка.Дата) = &Год И Метка.Количество >= &Минимум
|УПОРЯДОЧИТЬ ПО Метка.Количество УБЫВ, Метка.Код ВОЗР";
Запрос.УстановитьПараметр("Год", ГодОтбора);
Запрос.УстановитьПараметр("Минимум", Минимум);
Таблица = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.Прямой);
ПроверитьСвоюПолнуюТаблицу(Таблица, Ожидания, Поля, Истина);
ПроверитьСвоиИсходныеМетки(Менеджер, Источник, ОжиданияИсточника);
Сообщить("Русский: обе полные строки Gamma7/Beta5 и типы5полей совпали");
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Менеджер;
Запрос.Текст = "SELECT Метка.Код AS Код, SUBSTRING(Метка.Код,4,5) AS Имя,
|YEAR(Метка.Дата) AS Год, Метка.Дата AS Дата, Метка.Количество AS Количество
|FROM СвоиМетки AS Метка
|WHERE YEAR(Метка.Дата) = &Год AND Метка.Количество >= &Минимум
|ORDER BY Метка.Количество DESC, Метка.Код ASC";
Запрос.УстановитьПараметр("Год", ГодОтбора);
Запрос.УстановитьПараметр("Минимум", Минимум);
Таблица = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.Прямой);
ПроверитьСвоюПолнуюТаблицу(Таблица, Ожидания, Поля, Истина);
ПроверитьСвоиИсходныеМетки(Менеджер, Источник, ОжиданияИсточника);
Сообщить("English: обе полные строки Gamma7/Beta5 и типы5полей совпали");
Исключение
ЗакрытьСвоиВТБезЗаписей(Менеджер);
ВызватьИсключение;
КонецПопытки;
ЗакрытьСвоиВТБезЗаписей(Менеджер);
Сообщить("Русский и английский запросы проверены независимо; все4исхода сохранены; своих записей нет");
КонецПроцедуры
Процедура ПроверитьСвойИерархическийСтенд()
Если Метаданные.Справочники.Количество() <> 1 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый минимальный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Метаданные своего сеанса не должны изменяться расширениями";
КонецЕсли;
ИсточникиРасширений = Новый Массив;
ИсточникиРасширений.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
ИсточникиРасширений.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
ИсточникиРасширений.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого ИсточникРасширений Из ИсточникиРасширений Цикл
СписокРасширений = РасширенияКонфигурации.Получить(, ИсточникРасширений);
Если ТипЗнч(СписокРасширений) <> Тип("Массив") Тогда
ВызватьИсключение "Список расширений должен иметь native тип Массив";
КонецЕсли;
Если СписокРасширений.Количество() <> 0 Тогда
ВызватьИсключение "В новом своём стенде не должно быть расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
МетаДерево = Метаданные.Справочники.Найти("УчебноеДерево85");
Если МетаДерево = Неопределено Тогда
ВызватьИсключение "Не найден свой справочник УчебноеДерево85";
КонецЕсли;
Свойства = Метаданные.СвойстваОбъектов;
Если Не МетаДерево.Иерархический Или МетаДерево.ВидИерархии <> Свойства.ВидИерархии.ИерархияГруппИЭлементов
Или МетаДерево.ОграничиватьКоличествоУровней Или МетаДерево.Владельцы.Количество() <> 0
Или МетаДерево.ТипКода <> Свойства.ТипКодаСправочника.Строка Или МетаДерево.ДлинаКода <> 3
Или МетаДерево.ДлинаНаименования <> 20 Или МетаДерево.Автонумерация
Или МетаДерево.Реквизиты.Количество() <> 0 Или МетаДерево.ТабличныеЧасти.Количество() <> 0 Тогда
ВызватьИсключение "Не совпала своя минимальная схема иерархии";
КонецЕсли;
Имена = МетаДерево.ПолучитьИменаПредопределенных();
Если ТипЗнч(Имена) <> Тип("ФиксированныйМассив") Тогда
ВызватьИсключение "Предопределённые имена должны иметь native тип ФиксированныйМассив";
КонецЕсли;
Если Имена.Количество() <> 0 Тогда
ВызватьИсключение "В своём справочнике нет предопределённых имён";
КонецЕсли;
КонецПроцедуры
Функция ПолностьюСовпадаетСвояСтрока(СтрокаТаблицы, Ожидаемая, Поля, Колонки)
Для Каждого ИмяПоля Из Поля Цикл
Если Не Ожидаемая.Свойство(ИмяПоля, Ожидание) Тогда
ВызватьИсключение "Не найдено полное собственное ожидание поля " + ИмяПоля;
КонецЕсли;
Колонка = Колонки.Найти(ИмяПоля);
Факт = СтрокаТаблицы.Получить(Колонки.Индекс(Колонка));
Если ТипЗнч(Факт) <> ТипЗнч(Ожидание) Тогда
Возврат Ложь;
КонецЕсли;
Если Факт <> Ожидание Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Процедура ПроверитьСвоюПолнуюТаблицу(Таблица, Ожидания, Поля, Упорядоченный)
Если ТипЗнч(Таблица) <> Тип("ТаблицаЗначений") Тогда
ВызватьИсключение "Нужна своя ТаблицаЗначений";
КонецЕсли;
Если Таблица.Колонки.Количество() <> Поля.Количество() Или Таблица.Количество() <> Ожидания.Количество() Тогда
ВызватьИсключение "Не совпали полные размеры своей таблицы";
КонецЕсли;
Для Каждого ИмяПоля Из Поля Цикл
Если Таблица.Колонки.Найти(ИмяПоля) = Неопределено Тогда
ВызватьИсключение "Не найдена своя колонка " + ИмяПоля;
КонецЕсли;
КонецЦикла;
Использованные = Новый Массив;
Если Ожидания.Количество() > 0 Тогда
Для Индекс = 0 По Ожидания.Количество() - 1 Цикл
Если Упорядоченный Тогда
Если Не ПолностьюСовпадаетСвояСтрока(Таблица[Индекс], Ожидания[Индекс], Поля, Таблица.Колонки) Тогда
ВызватьИсключение "Не совпали все поля, типы или порядок своей строки";
КонецЕсли;
Иначе
Найден = -1;
Для Кандидат = 0 По Ожидания.Количество() - 1 Цикл
Если Использованные.Найти(Кандидат) = Неопределено Тогда
Если ПолностьюСовпадаетСвояСтрока(Таблица[Индекс], Ожидания[Кандидат], Поля, Таблица.Колонки) Тогда
Найден = Кандидат;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Найден = -1 Тогда
ВызватьИсключение "Не совпал полный свой unordered состав с кратностями";
КонецЕсли;
Использованные.Добавить(Найден);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьОтсутствиеСвоихЗаписей()
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Пустота своей базы проверяется вне транзакции";
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Количество ИЗ Справочник.УчебноеДерево85";
Таблица = Запрос.Выполнить().Выгрузить();
Если Таблица.Количество() <> 1 Или Таблица.Колонки.Количество() <> 1
Или Таблица.Колонки.Найти("Количество") = Неопределено Тогда
ВызватьИсключение "Не совпала полная форма собственного счётчика";
КонецЕсли;
Если ТипЗнч(Таблица[0].Количество) <> Тип("Число") Тогда
ВызватьИсключение "Свой счётчик должен иметь тип Число";
КонецЕсли;
Если Таблица[0].Количество <> 0 Тогда
ВызватьИсключение "Новая собственная база должна быть пустой; код ничего не удаляет";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоюТипизированнуюКолонку(Таблица, Имя, НужныйТип)
Колонка = Таблица.Колонки.Найти(Имя);
Если Колонка = Неопределено Тогда
ВызватьИсключение "Не найдена своя типизированная колонка " + Имя;
КонецЕсли;
Описание = Колонка.ТипЗначения;
Если Описание.Типы().Количество() <> 1 Или Не Описание.СодержитТип(НужныйТип) Тогда
ВызватьИсключение "В собственной колонке должен быть ровно заданный тип";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоеКоличество(Количество)
Если ТипЗнч(Количество) <> Тип("Число") Тогда
ВызватьИсключение "Собственное количество должно иметь тип Число";
КонецЕсли;
Если Количество < 0 Или Количество > 9999 Или Количество <> Цел(Количество) Тогда
ВызватьИсключение "Собственное количество должно быть целым0..9999";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьОтклонениеСвоегоКоличества(Количество)
Отклонён = Ложь;
Попытка
ПроверитьСвоеКоличество(Количество);
Исключение
Отклонён = Истина;
Сообщить("Ручной опыт: своё неверное количество отклонено. " + ОписаниеОшибки());
КонецПопытки;
Если Не Отклонён Тогда
ВызватьИсключение "Ожидалось отклонение данного собственного количества";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойЧисловойКвалификатор(Таблица)
ПроверитьСвоюТипизированнуюКолонку(Таблица, "Количество", Тип("Число"));
Квалификатор = Таблица.Колонки.Найти("Количество").ТипЗначения.КвалификаторыЧисла;
Если Квалификатор.Разрядность <> 4 Или Квалификатор.РазрядностьДробнойЧасти <> 0
Или Квалификатор.ДопустимыйЗнак <> ДопустимыйЗнак.Неотрицательный Тогда
ВызватьИсключение "Количество должно иметь собственный Число(4,0), неотрицательный";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойВводМетки(Код, ДатаМетки, Количество)
Если ТипЗнч(Код) <> Тип("Строка") Или ТипЗнч(ДатаМетки) <> Тип("Дата") Тогда
ВызватьИсключение "У собственной метки код Строка, дата Дата";
КонецЕсли;
Если СтрДлина(Код) < 4 Или СтрДлина(Код) > 8 Тогда
ВызватьИсключение "Для нашего выделения суффикса нужен код длиной4..8";
КонецЕсли;
ПроверитьСвоеКоличество(Количество);
КонецПроцедуры
Процедура ПроверитьОтклонениеСвоейМетки(Код, ДатаМетки, Количество)
Отклонён = Ложь;
Попытка
ПроверитьСвойВводМетки(Код, ДатаМетки, Количество);
Исключение
Отклонён = Истина;
Сообщить("Ручной опыт: своя неверная метка отклонена. " + ОписаниеОшибки());
КонецПопытки;
Если Не Отклонён Тогда
ВызватьИсключение "Ожидалось отклонение данной собственной метки";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойОтборМеток(ГодОтбора, Минимум)
Если ТипЗнч(ГодОтбора) <> Тип("Число") Тогда
ВызватьИсключение "Собственный год отбора должен иметь тип Число";
КонецЕсли;
Если ГодОтбора <> 2026 Тогда
ВызватьИсключение "Наш фиксированный опыт проверяет только год2026";
КонецЕсли;
ПроверитьСвоеКоличество(Минимум);
КонецПроцедуры
Процедура ПроверитьОтклонениеСвоегоОтбора(ГодОтбора, Минимум)
Отклонён = Ложь;
Попытка
ПроверитьСвойОтборМеток(ГодОтбора, Минимум);
Исключение
Отклонён = Истина;
Сообщить("Ручной опыт: свой неверный отбор отклонён. " + ОписаниеОшибки());
КонецПопытки;
Если Не Отклонён Тогда
ВызватьИсключение "Ожидалось отклонение данного собственного отбора";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоиИсходныеМетки(Менеджер, Источник, Ожидания)
ПроверитьСвоюТипизированнуюКолонку(Источник, "Код", Тип("Строка"));
ПроверитьСвоюТипизированнуюКолонку(Источник, "Дата", Тип("Дата"));
ПроверитьСвойЧисловойКвалификатор(Источник);
Строковый = Источник.Колонки.Найти("Код").ТипЗначения.КвалификаторыСтроки;
Даты = Источник.Колонки.Найти("Дата").ТипЗначения.КвалификаторыДаты;
Если Строковый.Длина <> 8 Или Строковый.ДопустимаяДлина <> ДопустимаяДлина.Переменная
Или Даты.ЧастиДаты <> ЧастиДаты.ДатаВремя Тогда
ВызватьИсключение "Не совпали свои строковый и датовый квалификаторы";
КонецЕсли;
Поля = Новый Массив;
Поля.Добавить("Код");
Поля.Добавить("Дата");
Поля.Добавить("Количество");
ПроверитьСвоюПолнуюТаблицу(Источник, Ожидания, Поля, Ложь);
Проверка = Новый Запрос;
Проверка.МенеджерВременныхТаблиц = Менеджер;
Проверка.Текст = "ВЫБРАТЬ Метка.Код КАК Код, Метка.Дата КАК Дата, Метка.Количество КАК Количество ИЗ СвоиМетки КАК Метка";
ПроверитьСвоюПолнуюТаблицу(Проверка.Выполнить().Выгрузить(), Ожидания, Поля, Ложь);
КонецПроцедуры
Процедура ЗакрытьСвоиВТБезЗаписей(Менеджер)
ОшибкаЗакрытия = "";
Если Менеджер <> Неопределено Тогда
Попытка
Менеджер.Закрыть();
Исключение
ОшибкаЗакрытия = ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
ПроверитьОтсутствиеСвоихЗаписей();
Если ОшибкаЗакрытия <> "" Тогда
ВызватьИсключение "Свои записи отсутствуют, но закрытие ВТ завершилось ошибкой: " + ОшибкаЗакрытия;
КонецЕсли;
КонецПроцедурыУчебныйПускДвуязычныхМеток85.Форма
Собственная новая внешняя обработка УчебныйПускДвуязычныхМеток85 → управляемая Форма → Модуль
Полный отдельный клиентский/серверный модуль формы; серверная процедура без контекста вызывает свой серверный общий модуль. Не смешивать с основным модулем.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Полные собственные проверки завершены; учебных записей не осталось");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныйЯзык.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Подготовить только новый собственный стенд и полный серверный модуль. Guard до действий сверяет минимальную схему и native metadata-enum вида иерархии.
Проверить конфигурационные предопределённые имена как пустой ФиксированныйМассив. Read-only список расширений проверяется для всех3native источников, не только базы; изменения метаданных расширениями не допускаются.
Пустые модули/формы и единственный сеанс — обязательная ручная подготовка. Native-свойства модулей всегда Неопределено: нельзя на основании этого обещать отсутствие обработчиков.
До действий запретить активную чужую/вложенную транзакцию и непустой собственный источник без очистки. После обеих ветвей проверить отсутствие своих записей вне транзакции; полный запуск дан отдельно от общего модуля.
Прикладные записи не нужны: только4фиксированных строки памяти, приватный МенеджерВременныхТаблиц и пустой собственный справочник. НачатьТранзакцию/Записать отсутствуют; подготовленная схема/версия остаются проверены.
Колонки задаются до значений: Код только Строка(8), переменная; Дата только ДатаВремя; Количество только Число(4,0), неотрицательное. Проверяется единственность типов/квалификаторы и входной тип каждого значения до присвоения.
Исходы точно AA:Alba/06.10.2026/2, BB:Beta/07.10.2026/5, CC:Gamma/08.10.2026/7, DD:Delta/09.10.2025/9; у всех время12:00:00. Полный исходник памяти проверяется до загрузки и затем память/ВТ до/между/после двух запросов.
ГодОтбора=2026 и Минимум=5 передаются отдельными неизменяемыми параметрами. Отсутствующие/строковые параметры отклоняются своим валидатором;2025в параметре тоже отвергается только нашим фиксированным контрактом опыта, не запретом языка запросов.
Native present.html задаёт реальные соответствия ВЫБРАТЬ/SELECT,КАК/AS,ИЗ/FROM,ГДЕ/WHERE,И/AND,ПОДСТРОКА/SUBSTRING,ГОД/YEAR,УПОРЯДОЧИТЬПО/ORDERBY,УБЫВ/DESC,ВОЗР/ASC. Имена своих полей/таблицы/параметров и данные не переводятся.
ПОДСТРОКА с позиции4длиной5 выделяет суффикс Gamma/Beta; YEAR из Дата даёт Число2026. Оба выражения используются в реальном списке, YEAR также в WHERE. Ни один текст не подменён заранее рассчитанным результатом.
Alba не проходит количество2≥5; Delta имеет количество9, но год2025не проходит. Gamma7 и Beta5 проходят оба условия И/AND. Каждая причина отсечения проверена собственными фиксированными исходами.
Оба полных результата имеют Код/Имя/Год/Дата/Количество: CC:Gamma/Gamma/2026/08.10.2026 12:00:00/7, затем BB:Beta/Beta/2026/07.10.2026 12:00:00/5. Типы Строка/Строка/Число/Дата/Число и весь порядок сверяются независимо у обоих выполнений.
Две границы количества0/9999, две границы длины4/8, пять плохих количеств, шесть плохих меток и пять плохих отборов — только подготовительные валидаторы. Catch не скрывает выполнение/проверки положительных запросов.
При успехе/ошибке закрыть свой менеджер ВТ; возможная ошибка закрытия не объявляется успехом. Свой справочник до/после остаётся Число0записей.
Выполнение в 1С не проверялось. Python — только модель собственных фиксированных данных и проверок полного состава, не заменяет будущий ручной BSL опыт.
Как проверить результат
Оба результата независимо содержат ровно2полные строки Gamma7, затем Beta5; все5значений/типов/позиции совпадают с фиксированным ожиданием.
Alba2исключена только количеством; Delta9исключена годом2025. Все4исходных строки памяти/ВТ с точным временем/типами сохранены до/между/после.
Все10пар ключевых слов/функций из native реально применены в полном переводе; имена источника/полей/алиасов/параметров/данные остаются одинаковыми.
Наши проверки отсутствующего/неверного ввода срабатывают до действий. Приватный менеджер закрывается на обеих ветвях; транзакций/прикладных записей нет.
Ожидаемый результат
Содержательный двуязычный опыт проверяет вычисление, обе причины отбора и полный упорядоченный результат, а не просто таблицу переводов ключевых слов.
На что обратить внимание
Native модули объекта/менеджера всегда Неопределено, поэтому guard не может доказать пустой BSL текст. Пустота проверяется вручную в новом Конфигураторе; расширения не отключаются/не удаляются кодом.
Будущие собственные записи нужны только для реальной иерархии первых двух уроков. Здесь база/конфигурация/1С не исполнялись и не менялись; успешное создание/откат не заявляются.
Python моделирует только фиксированные данные, наши ожидания и проверки. Статические тесты/direct native не являются runtime доказательством.
Привязка примера только к реально применённой теме; базовые источники/агрегаты/параметры не добавляются повторно ради счётчика. ДЛЯ ИЗМЕНЕНИЯ, РАЗРЕШЕННЫЕ и РазмерХранимыхДанных разобраны в самостоятельных уроках с собственными сеансами, правами и данными. Этот урок не заменяет их отдельные задачи. Комментарии и общая грамматика также разобраны отдельно.
Ограничение диагностики: аварийная очистка вызывается до ВызватьИсключение без аргументов. Если её собственные ОтменитьТранзакцию, Закрыть менеджера ВТ или readback тоже вызывают исключение, исходная диагностика может быть заменена ошибкой очистки; сохранение исходной диагностики не обещается. Для RU/EN транзакции/записей нет, но ограничение относится к ЗакрытьСвоиВТБезЗаписей и проверке пустоты. При таком сбое фактически закрытые ВТ/откат/пустота требуют отдельной проверки, сообщение успеха не допускается. Здесь аварийные операции и диагностика не проверены runtime.
Переводится язык запроса, не имена метаданных/параметров или значения строк. Кириллические идентификаторы допустимо оставить в английском тексте.
СУММА/иерархия/AUTOORDER здесь не используются и не привязываются. Этот урок не читает свой справочник иначе, чем проверяет его пустоту; все4рабочих входа только в памяти/ВТ.
Native YEAR из Дата возвращает Число, SUBSTRING из Строка возвращает Строка. NULL/неверные native типы этих функций здесь не используются; свои неверные входы отклоняются до загрузки.
Ключевые слова перечислены отдельно в prose; исходники не содержат новых поясняющих комментариев. comments.html не исключён из общей цели, только не входит в эту партию.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.