Русский и английский запрос: сверить полный отбор и вычисления своих четырёх меток

Учебные задачи

Два полных текста RU/EN вычисляют суффикс/год, отбирают2026и количество≥5, явно сортируют и отдельно проверяют все поля двух результатов. Третий/четвёртый исходы показывают разные причины отбора.

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

Полный серверный общий модуль УчебныйЯзык только нового собственного стенда УчебныеИерархическиеИтоги85 на 8.5.1.1343. BSL, запросы и транзакции здесь не исполнялись.

Подготовка

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

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

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

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

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

  6. Справочники → УчебноеДерево85: Иерархический=Да; Вид иерархии=Иерархия групп и элементов; Ограничивать количество уровней=Нет; Владельцы пусты. Код только Строка, длина3; Автонумерация=Нет; Наименование длина20. Собственных реквизитов, табчастей и предопределённых элементов нет. Стандартные поля платформы остаются.

  7. Все объектные/менеджерские модули, формы, модули сеанса/приложения и обработчики вручную полностью пусты. Native МодульОбъекта и МодульМенеджера всегда Неопределено и не позволяют прочитать текст BSL: guard не выдаёт это значение за доказательство пустого модуля. Это обязательная проверка читателя в новом Конфигураторе; здесь Конфигуратор не запускался.

  8. Read-only guard проверяет минимальную схему, пустой ФиксированныйМассив предопределённых имён, пустые массивы трёх источников расширений БазаДанных/СеансАктивные/СеансОтключенные и отсутствие изменений метаданных расширениями. До действий запрещена чужая/вложенная транзакция и проверен Число0 собственных записей без их удаления.

  9. Основной код целиком заменяет свой серверный общий модуль УчебныйЯзык; все helpers расположены рядом с экспортной процедурой, не внутри неё. У модуля Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь; клиентские/внешнее соединение отключены, повторное использование выключено. Для следующего урока замените модуль целиком, не объединяйте одноимённые экспортные точки.

  10. Новая собственная внешняя обработка УчебныйПускДвуязычныхМеток85 → управляемая Форма → команда Выполнить и кнопка с одноимённым действием. Остальные модули пусты. Полный отдельный модуль формы:

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

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

  11. Этот урок не создаёт прикладных записей и не начинает транзакцию: ровно4полностью заданные типизированные строки находятся в своей таблице памяти/приватной ВТ. Менеджер закрывается на обеих ветвях; собственный справочник остаётся пустым.

  12. Python моделирует только фиксированные входы, полные ожидания и нашу проверку состава/дерева. Direct HBK подтверждает нативный текст установленной версии, но ни он, ни focused/static tests не доказывают исполнение BSL/запросов/отката в 1С.

  13. Общий обязательный этап перед первым ручным запуском каждого урока: после ВСЕХ настроек метаданных, флагов общего модуля, вставки полного основного модуля и подготовки полного модуля своей формы сохраните свою конфигурацию. Завершите свой предыдущий учебный сеанс; активной транзакции и выполняющегося учебного опыта быть не должно. В Конфигураторе своего стенда выполните Конфигурация → Обновить конфигурацию базы данных (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 → управляемая Форма → Модуль

Полный отдельный клиентский/серверный модуль формы; серверная процедура без контекста вызывает свой серверный общий модуль. Не смешивать с основным модулем.

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

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

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

  1. Подготовить только новый собственный стенд и полный серверный модуль. Guard до действий сверяет минимальную схему и native metadata-enum вида иерархии.

  2. Проверить конфигурационные предопределённые имена как пустой ФиксированныйМассив. Read-only список расширений проверяется для всех3native источников, не только базы; изменения метаданных расширениями не допускаются.

  3. Пустые модули/формы и единственный сеанс — обязательная ручная подготовка. Native-свойства модулей всегда Неопределено: нельзя на основании этого обещать отсутствие обработчиков.

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

  5. Прикладные записи не нужны: только4фиксированных строки памяти, приватный МенеджерВременныхТаблиц и пустой собственный справочник. НачатьТранзакцию/Записать отсутствуют; подготовленная схема/версия остаются проверены.

  6. Колонки задаются до значений: Код только Строка(8), переменная; Дата только ДатаВремя; Количество только Число(4,0), неотрицательное. Проверяется единственность типов/квалификаторы и входной тип каждого значения до присвоения.

  7. Исходы точно 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. Полный исходник памяти проверяется до загрузки и затем память/ВТ до/между/после двух запросов.

  8. ГодОтбора=2026 и Минимум=5 передаются отдельными неизменяемыми параметрами. Отсутствующие/строковые параметры отклоняются своим валидатором;2025в параметре тоже отвергается только нашим фиксированным контрактом опыта, не запретом языка запросов.

  9. Native present.html задаёт реальные соответствия ВЫБРАТЬ/SELECT,КАК/AS,ИЗ/FROM,ГДЕ/WHERE,И/AND,ПОДСТРОКА/SUBSTRING,ГОД/YEAR,УПОРЯДОЧИТЬПО/ORDERBY,УБЫВ/DESC,ВОЗР/ASC. Имена своих полей/таблицы/параметров и данные не переводятся.

  10. ПОДСТРОКА с позиции4длиной5 выделяет суффикс Gamma/Beta; YEAR из Дата даёт Число2026. Оба выражения используются в реальном списке, YEAR также в WHERE. Ни один текст не подменён заранее рассчитанным результатом.

  11. Alba не проходит количество2≥5; Delta имеет количество9, но год2025не проходит. Gamma7 и Beta5 проходят оба условия И/AND. Каждая причина отсечения проверена собственными фиксированными исходами.

  12. Оба полных результата имеют Код/Имя/Год/Дата/Количество: CC:Gamma/Gamma/2026/08.10.2026 12:00:00/7, затем BB:Beta/Beta/2026/07.10.2026 12:00:00/5. Типы Строка/Строка/Число/Дата/Число и весь порядок сверяются независимо у обоих выполнений.

  13. Две границы количества0/9999, две границы длины4/8, пять плохих количеств, шесть плохих меток и пять плохих отборов — только подготовительные валидаторы. Catch не скрывает выполнение/проверки положительных запросов.

  14. При успехе/ошибке закрыть свой менеджер ВТ; возможная ошибка закрытия не объявляется успехом. Свой справочник до/после остаётся Число0записей.

  15. Выполнение в 1С не проверялось. Python — только модель собственных фиксированных данных и проверок полного состава, не заменяет будущий ручной BSL опыт.

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

  1. Оба результата независимо содержат ровно2полные строки Gamma7, затем Beta5; все5значений/типов/позиции совпадают с фиксированным ожиданием.

  2. Alba2исключена только количеством; Delta9исключена годом2025. Все4исходных строки памяти/ВТ с точным временем/типами сохранены до/между/после.

  3. Все10пар ключевых слов/функций из native реально применены в полном переводе; имена источника/полей/алиасов/параметров/данные остаются одинаковыми.

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

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

Содержательный двуязычный опыт проверяет вычисление, обе причины отбора и полный упорядоченный результат, а не просто таблицу переводов ключевых слов.

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

  1. Native модули объекта/менеджера всегда Неопределено, поэтому guard не может доказать пустой BSL текст. Пустота проверяется вручную в новом Конфигураторе; расширения не отключаются/не удаляются кодом.

  2. Будущие собственные записи нужны только для реальной иерархии первых двух уроков. Здесь база/конфигурация/1С не исполнялись и не менялись; успешное создание/откат не заявляются.

  3. Python моделирует только фиксированные данные, наши ожидания и проверки. Статические тесты/direct native не являются runtime доказательством.

  4. Привязка примера только к реально применённой теме; базовые источники/агрегаты/параметры не добавляются повторно ради счётчика. ДЛЯ ИЗМЕНЕНИЯ, РАЗРЕШЕННЫЕ и РазмерХранимыхДанных разобраны в самостоятельных уроках с собственными сеансами, правами и данными. Этот урок не заменяет их отдельные задачи. Комментарии и общая грамматика также разобраны отдельно.

  5. Ограничение диагностики: аварийная очистка вызывается до ВызватьИсключение без аргументов. Если её собственные ОтменитьТранзакцию, Закрыть менеджера ВТ или readback тоже вызывают исключение, исходная диагностика может быть заменена ошибкой очистки; сохранение исходной диагностики не обещается. Для RU/EN транзакции/записей нет, но ограничение относится к ЗакрытьСвоиВТБезЗаписей и проверке пустоты. При таком сбое фактически закрытые ВТ/откат/пустота требуют отдельной проверки, сообщение успеха не допускается. Здесь аварийные операции и диагностика не проверены runtime.

  6. Переводится язык запроса, не имена метаданных/параметров или значения строк. Кириллические идентификаторы допустимо оставить в английском тексте.

  7. СУММА/иерархия/AUTOORDER здесь не используются и не привязываются. Этот урок не читает свой справочник иначе, чем проверяет его пустоту; все4рабочих входа только в памяти/ВТ.

  8. Native YEAR из Дата возвращает Число, SUBSTRING из Строка возвращает Строка. NULL/неверные native типы этих функций здесь не используются; свои неверные входы отклоняются до загрузки.

  9. Ключевые слова перечислены отдельно в prose; исходники не содержат новых поясняющих комментариев. comments.html не исключён из общей цели, только не входит в эту партию.

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

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

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

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

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