Отбор.Индекс

Методы · IndexOf

Получает индекс элемента отбора в коллекции отборов.

Синтаксис

Индекс(<ЭлементОтбора>)
Полное описание, параметры и ограничения

Отбор.Индекс (Filter.IndexOf)

Отбор (Filter)

Индекс (IndexOf)

Доступен, начиная с версии 8.0.

Синтаксис:
Индекс(<ЭлементОтбора>)
Параметры:

<ЭлементОтбора> (обязательный)
Тип: ЭлементОтбора.
Элемент отбора, индекс которого требуется определить.
Возвращаемое значение:
Тип: Число.
Индекс указанного элемента в коллекции. Если не найдено, то возвращается -1.
Описание:

Получает индекс элемента отбора в коллекции отборов.

Доступность:

Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.

Использование в версии:

Доступен, начиная с версии 8.0.

Методическая информация

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

Свой отчет в памяти: интервальные отборы, границы и две обычные формы

Полный маршрут для новичка на отдельной пустой конфигурации. Настоящий менеджер создает отчет, его собственная табличная часть дает типизированный источник построителю; отборы и native компоновка проверяются по полным строкам и числам, а Отмена не восстанавливает чужие изменения.

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

Толстый клиент, обычное приложение собственной новой пустой CF; общий модуль УчебныйОтчетМаршрут85, только Клиент (обычное приложение).

Подготовка

  1. Не открывайте УТ/КА/УНФ/БП и не вставляйте этот код в рабочий отчет. Вручную создайте отдельную новую пустую файловую ИБ на установленной платформе8.5.1.1343. Имя конфигурации строго УчебныйОтчетОтбор85. В этой задаче отчет, его строки и отборы живут только в памяти; урок не создает справочников, документов или записей регистров.

  2. В свойствах конфигурации настройте поддерживаемые режимы запуска: Управляемое приложение и обычное приложение; основной режим запуска: Обычное приложение. Первый выбор нужен, чтобы в свойствах общего модуля был виден флаг Клиент (обычное приложение). Проверяйте урок только в собственной файловой ИБ и толстом обычном клиенте, не в тонком/веб/мобильном. ПолучитьФорму и ПолучитьФормуНастроек здесь возвращают старую Форма и по native справке доступны только толстому клиенту.

  3. Сохраните только свою новую конфигурацию и ее собственную учебную базу вручную. Справочники, документы, перечисления, все регистры/планы, общие реквизиты, подписки, задания, внешние источники, константы, обработки, общие формы и хранилища настроек должны отсутствовать. Не устанавливайте расширения ни в ИБ, ни в сеанс. Защитные проверки читают эти списки, но не меняют их.

  4. В ветке Роли создайте единственную роль УчебныйАдминистратор85 с административными правами своей пустой ИБ. В Администрирование → Пользователи создайте ровно одного своего пользователя УченикОтчет85, назначьте эту роль и войдите им. Это ручная подготовка только нового учебного стенда: код пользователей/ролей не создает и не меняет, не выводит их имена или UUID. UUID текущего пользователя сравнивается с единственным реальным пользователем, а не выдумывается.

  5. В Общие → Общие модули создайте единственный модуль УчебныйОтчетМаршрут85. Флаги: Клиент (обычное приложение)=Да, Сервер=Нет, Глобальный=Нет, Привилегированный=Нет. Главный блок урока целиком вставьте в этот модуль. Директив &НаСервере/НаКлиенте в нем нет: это именно толстый обычный клиент.

  6. В Отчеты создайте единственный отчет УчебныйОтбор85. Макетов и основной схемы компоновки не создавайте: результат сформирует собственный полный обработчик ПриКомпоновкеРезультата. Никакие ранее существовавшие отчеты или BSP не используются.

  7. У отчета создайте ровно6 реквизитов: Маркер85 — Строка36 переменной длины; Заголовок85 — Строка80 переменной длины, Проверка заполнения=Показывать ошибку; СуммаС85 и СуммаПо85 — Число9.2, неотрицательное; ВключатьГраницы85 и ОтбиратьPAPER85 — Булево. Для всех, кроме Заголовок85, проверка заполнения=Не проверять. Не назначайте значения по умолчанию, обработчики изменения или сторонние проверки.

  8. В табличных частях отчета создайте ровно одну Строки85 с5 реквизитами: Код85/Категория85 — Строка12 переменной длины; Количество85/Цена85/Сумма85 — Число9.2 неотрицательное. Проверка заполнения каждого=Не проверять. Не создавайте реквизит НомерСтроки самостоятельно: это стандартная нумерация табличной части.

  9. Во вкладке модуль объекта отчета вставьте целиком первый дополнительный блок. Его native события назначаются по именам: ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) и ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка). В обоих обработчиках инструкции #Если ТолстыйКлиентОбычноеПриложение оставляют вызовы клиентского общего модуля только в этом контексте. В файловом обычном приложении этот символ определен у обеих частей приложения; это не универсальный запрет серверной части File. В отдельных серверных, внешних, фоновых и иных клиентских контекстах ветвь #Иначе отказывает до вызова общего модуля: проверка устанавливает Отказ=Истина, компоновка заранее отключает стандартную обработку и оба обработчика вызывают исключение. Не создавайте обработчик ОбработкаКомпоновкиРезультата и не вызывайте ни один из этих обработчиков напрямую.

  10. У отчета создайте2 собственные обычные формы: УчебныйРезультат85 как форму отчета и УчебныеГраницы85 как форму настроек. Главный реквизит обеих — Отчет, тип ОтчетОбъект.УчебныйОтбор85. В свойствах форм отключите Восстанавливать настройки автоматически. Не добавляйте сохранение настроек, стандартные команды работы с хранилищем, файл/печать/расшифровку. Собственные команды только из следующих шагов.

  11. В обычной форме УчебныйРезультат85 добавьте поле табличного документа Результат85 и две кнопки Сформировать85/Настройки85. Назначьте их действия одноименным процедурам модуля; событие формы ПриОткрытии — процедуре ПриОткрытии. Весь второй дополнительный блок — полный модуль этой формы. Отчет создается через native менеджер, а форма получается именно у этого экземпляра, не через неизвестную ссылку.

  12. В обычной форме УчебныеГраницы85 создайте только локальные реквизиты формы ГраницаС85/ГраницаПо85 (Число9.2 неотрицательное), Включать85/КатегорияPAPER85 (Булево). Разместите2 числовых поля и2 флажка, связанные с этими реквизитами, НЕ с Отчет.СуммаС85/СуммаПо85 и НЕ напрямую с реквизитами отчета. Поэтому ввод в форму не меняет отчет до команды Применить.

  13. Там же добавьте собственные кнопки Применить85 и Отмена85 с одноименными действиями. Назначьте события ПриОткрытии/ПередЗакрытием одноименным процедурам. Полный третий дополнительный блок — модуль этой формы. Не создавайте ПриИзменении для полей или автоматическую запись/сохранение в ПриЗакрытии.

  14. В модуль обычного приложения вставьте целиком четвертый дополнительный блок; назначьте native событие ПриНачалеРаботыСистемы. Никакая команда не запускает программу/сервис/фоновое задание и не печатает документ. Подготовку метаданных и открытие своего тестового клиента выполняет только человек.

  15. Перед запуском проверьте синтаксис всех5 модулей конфигурации. Если версия/права/состав метаданных или типы не совпали, остановитесь и исправьте только новый учебный стенд. Этот опубликованный текст проверен статически по installed native справке; запуск в1С не выполнен.

  16. При начале собственного сеанса выполнятся4 числовых этапа750/950/0/1000 и5 ожидаемых исключений; затем отдельный новый отчет с пустым обязательным заголовком обязан дать Ложь у native ПроверитьЗаполнение. Платформа покажет только собственную учебную ошибку заполнения. Не очищайте чужие сообщения; здесь они не запрашиваются и никуда не отправляются.

  17. После проверок открывается своя форма результата с BOOK3×250=750. Нажмите Настройки: поставьте200/750, включенные границы, PAPER, Применить; в форме результата нажмите Сформировать и ожидайте BOOK750 + PAD200 =950. Форма настроек не обещает автообновление другой формы: формирование явно отдельно.

  18. Откройте настройки снова, меняйте только локальные поля, например50/750, и нажмите Отмена либо крестик окна. Затем Сформировать должен снова показать950, а не1000. Fresh readback проверяет неизменность всех6 настоящих реквизитов и всех3 строк; если отчет уже изменен извне, отмена не восстанавливает старый снимок, а останавливает работу.

  19. Для проверки исключения границ поставьте200/750, выключите Включать, оставьте PAPER: оба собственных товара на границах исключены, итог0. Затем50/750, включенные границы, выключите PAPER: явное удаление только собственного условия категории дает3 товара и1000. Источник с3 строками/1000 не удаляется ни на одном шаге.

  20. При неожиданной ошибке формирования/вывода/применения закройте свой тестовый сеанс и разберите ошибку. Код не обещает атомарности нескольких присваиваний или Очистить+Вывести, не повторяет неясно завершившиеся операции, не делает слепой rollback. Контроль относится к бизнес-данным и явным вызовам урока; внутренние платформенные UI-кеши/геометрию окон он не доказывает.

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

Функция ПроверитьСвойСтенд85() Экспорт
    ПроверитьСвойПустойСтенд();
    Если Метаданные.Отчеты.Количество() <> 1 Или Метаданные.ОбщиеМодули.Количество() <> 1
        Или Метаданные.ОбщиеФормы.Количество() <> 0 Или Метаданные.Обработки.Количество() <> 0
        Или Метаданные.Константы.Количество() <> 0 Или Метаданные.ХранилищаНастроек.Количество() <> 0
        Или Метаданные.Роли.Количество() <> 1 Тогда
        ВызватьИсключение "OWN-REPORT-METADATA: нужна только своя схема";
    КонецЕсли;
    ОписаниеОтчета = Метаданные.Отчеты.Найти("УчебныйОтбор85");
    Если ОписаниеОтчета = Неопределено Или Метаданные.ОбщиеМодули.Найти("УчебныйОтчетМаршрут85") = Неопределено
        Или Метаданные.Роли.Найти("УчебныйАдминистратор85") = Неопределено Тогда
        ВызватьИсключение "OWN-REPORT-METADATA: нет собственных объектов";
    КонецЕсли;
    Если ОписаниеОтчета.Реквизиты.Количество() <> 6 Или ОписаниеОтчета.ТабличныеЧасти.Количество() <> 1
        Или ОписаниеОтчета.Формы.Количество() <> 2 Или ОписаниеОтчета.Макеты.Количество() <> 0 Тогда
        ВызватьИсключение "OWN-REPORT-METADATA: неверный состав отчета";
    КонецЕсли;
    Для Каждого ИмяРеквизита Из СтрРазделить("Маркер85,Заголовок85,СуммаС85,СуммаПо85,ВключатьГраницы85,ОтбиратьPAPER85", ",") Цикл
        Если ОписаниеОтчета.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
            ВызватьИсключение "OWN-REPORT-METADATA: нет собственного реквизита";
        КонецЕсли;
    КонецЦикла;
    ТабличнаяЧасть = ОписаниеОтчета.ТабличныеЧасти.Найти("Строки85");
    Если ТабличнаяЧасть = Неопределено Или ТабличнаяЧасть.Реквизиты.Количество() <> 5
        Или ОписаниеОтчета.Формы.Найти("УчебныйРезультат85") = Неопределено
        Или ОписаниеОтчета.Формы.Найти("УчебныеГраницы85") = Неопределено Тогда
        ВызватьИсключение "OWN-REPORT-METADATA: нет своих строк или форм";
    КонецЕсли;
    Для Каждого ИмяКолонки Из СтрРазделить("Код85,Категория85,Количество85,Цена85,Сумма85", ",") Цикл
        Если ТабличнаяЧасть.Реквизиты.Найти(ИмяКолонки) = Неопределено Тогда
            ВызватьИсключение "OWN-REPORT-METADATA: нет своей колонки";
        КонецЕсли;
    КонецЦикла;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1
        Или ТипЗнч(Пользователь) <> Тип("ПользовательИнформационнойБазы") Тогда
        ВызватьИсключение "OWN-REPORT-USER: нужен ровно один собственный пользователь";
    КонецЕсли;
    Если Пользователь.Имя <> "УченикОтчет85" Или Пользователи[0].Имя <> "УченикОтчет85"
        Или ТипЗнч(Пользователь.УникальныйИдентификатор) <> Тип("УникальныйИдентификатор")
        Или Пользователь.УникальныйИдентификатор <> Пользователи[0].УникальныйИдентификатор
        Или Пользователь.УникальныйИдентификатор = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000") Тогда
        ВызватьИсключение "OWN-REPORT-USER: не совпал собственный аутентифицированный пользователь";
    КонецЕсли;
    Возврат Пользователь.УникальныйИдентификатор;
КонецФункции

Функция СвоиОбразцы85()
    Образцы = Новый Массив;
    Образцы.Добавить(Новый Структура("Код85,Категория85,Количество85,Цена85,Сумма85", "BOOK", "PAPER", 3, 250, 750));
    Образцы.Добавить(Новый Структура("Код85,Категория85,Количество85,Цена85,Сумма85", "PAD", "PAPER", 2, 100, 200));
    Образцы.Добавить(Новый Структура("Код85,Категория85,Количество85,Цена85,Сумма85", "PEN", "OFFICE", 1, 50, 50));
    Возврат Образцы;
КонецФункции

Процедура ПроверитьТипКолонки85(ОписаниеТипа, Имя)
    Числовая = Имя = "Количество85" Или Имя = "Цена85" Или Имя = "Сумма85";
    НужныйТип = ?(Числовая, Тип("Число"), Тип("Строка"));
    Если ОписаниеТипа.Типы().Количество() <> 1 Или Не ОписаниеТипа.СодержитТип(НужныйТип) Тогда
        ВызватьИсключение "OWN-REPORT-COLUMN-TYPE: " + Имя;
    КонецЕсли;
    Если Числовая Тогда
        Квалификаторы = ОписаниеТипа.КвалификаторыЧисла;
        Если Квалификаторы.Разрядность <> 9 Или Квалификаторы.РазрядностьДробнойЧасти <> 2
            Или Квалификаторы.ДопустимыйЗнак <> ДопустимыйЗнак.Неотрицательный Тогда
            ВызватьИсключение "OWN-REPORT-COLUMN-TYPE: нужны Число9.2 и неотрицательный знак";
        КонецЕсли;
    Иначе
        Если ОписаниеТипа.КвалификаторыСтроки.Длина <> 12 Тогда
            ВызватьИсключение "OWN-REPORT-COLUMN-TYPE: нужна Строка12";
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьТаблицу85(Таблица, Ожидания, ПроверятьКвалификаторы = Истина) Экспорт
    Если ТипЗнч(Таблица) <> Тип("ТаблицаЗначений") Или ТипЗнч(Ожидания) <> Тип("Массив") Тогда
        ВызватьИсключение "OWN-REPORT-TABLE-TYPE: нужны собственные типизированные данные";
    КонецЕсли;
    Имена = СтрРазделить("Код85,Категория85,Количество85,Цена85,Сумма85", ",");
    Если Таблица.Колонки.Количество() <> 5 Или Таблица.Количество() <> Ожидания.Количество() Тогда
        ВызватьИсключение "OWN-REPORT-DATA: неверные размеры таблицы";
    КонецЕсли;
    Для Каждого Имя Из Имена Цикл
        Колонка = Таблица.Колонки.Найти(Имя);
        Если Колонка = Неопределено Тогда
            ВызватьИсключение "OWN-REPORT-DATA: нет собственной колонки";
        КонецЕсли;
        Если ПроверятьКвалификаторы Тогда
            ПроверитьТипКолонки85(Колонка.ТипЗначения, Имя);
        Иначе
            НужныйТип = ?(Имя = "Код85" Или Имя = "Категория85", Тип("Строка"), Тип("Число"));
            Если Не Колонка.ТипЗначения.СодержитТип(НужныйТип) Тогда
                ВызватьИсключение "OWN-REPORT-COLUMN-TYPE: результат должен содержать нужный тип";
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Встреченные = Новый Массив;
    Для Каждого СтрокаДанных Из Таблица Цикл
        Совпадение = Неопределено;
        Для Каждого Ожидание Из Ожидания Цикл
            Если СтрокаДанных.Код85 = Ожидание.Код85 Тогда
                Совпадение = Ожидание;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        Если Совпадение = Неопределено Или Встреченные.Найти(СтрокаДанных.Код85) <> Неопределено Тогда
            ВызватьИсключение "OWN-REPORT-DATA: чужой или повторный код";
        КонецЕсли;
        Для Каждого Имя Из Имена Цикл
            Факт = СтрокаДанных[Имя];
            Ожидается = Совпадение[Имя];
            Если ТипЗнч(Факт) <> ТипЗнч(Ожидается) Или Факт <> Ожидается Тогда
                ВызватьИсключение "OWN-REPORT-DATA: не совпала полная собственная строка";
            КонецЕсли;
        КонецЦикла;
        Если СтрокаДанных.Количество85 * СтрокаДанных.Цена85 <> СтрокаДанных.Сумма85 Тогда
            ВызватьИсключение "OWN-REPORT-DATA: неверная арифметика строки";
        КонецЕсли;
        Встреченные.Добавить(СтрокаДанных.Код85);
    КонецЦикла;
КонецПроцедуры

Функция ПроверитьОтчет85(СвойОтчет, СвойUUID, РазрешитьПустойЗаголовок = Ложь) Экспорт
    ПроверитьСвойСтенд85();
    Если ТипЗнч(СвойUUID) <> Тип("УникальныйИдентификатор")
        Или СвойUUID = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000")
        Или ТипЗнч(СвойОтчет) <> Тип("ОтчетОбъект.УчебныйОтбор85") Тогда
        ВызватьИсключение "OWN-REPORT-OWNER: нужен собственный отчет и ненулевой UUID";
    КонецЕсли;
    Если СвойОтчет.Метаданные() <> Метаданные.Отчеты.УчебныйОтбор85 Или СвойОтчет.Маркер85 <> Строка(СвойUUID) Тогда
        ВызватьИсключение "OWN-REPORT-OWNER: не совпал собственный объект";
    КонецЕсли;
    Если СвойОтчет.Заголовок85 <> "Три своих учебных товара" Тогда
        Если Не РазрешитьПустойЗаголовок Или СвойОтчет.Заголовок85 <> "" Тогда
            ВызватьИсключение "OWN-REPORT-HEADER: неизвестный заголовок";
        КонецЕсли;
    КонецЕсли;
    ПроверитьГраницы85(СвойОтчет.СуммаС85, СвойОтчет.СуммаПо85, СвойОтчет.ВключатьГраницы85, СвойОтчет.ОтбиратьPAPER85);
    Если ТипЗнч(СвойОтчет.Строки85) <> Тип("ОтчетТабличнаяЧасть.УчебныйОтбор85.Строки85") Тогда
        ВызватьИсключение "OWN-REPORT-OWNER: нет своей настоящей табличной части";
    КонецЕсли;
    Данные = СвойОтчет.Строки85.Выгрузить(, "Код85,Категория85,Количество85,Цена85,Сумма85");
    ПроверитьТаблицу85(Данные, СвоиОбразцы85());
    Если Данные.Итог("Сумма85") <> 1000 Тогда
        ВызватьИсключение "OWN-REPORT-DATA: полный источник должен давать1000";
    КонецЕсли;
    Возврат Данные;
КонецФункции

Процедура ПроверитьГраницы85(СуммаС, СуммаПо, ВключатьГраницы, ОтбиратьPAPER) Экспорт
    Если ТипЗнч(СуммаС) <> Тип("Число") Или ТипЗнч(СуммаПо) <> Тип("Число")
        Или ТипЗнч(ВключатьГраницы) <> Тип("Булево") Или ТипЗнч(ОтбиратьPAPER) <> Тип("Булево") Тогда
        ВызватьИсключение "OWN-REPORT-RANGE-TYPE: границы числа, переключатели булево";
    КонецЕсли;
    Если СуммаС < 0 Или СуммаПо > 1000 Или СуммаС > СуммаПо
        Или Окр(СуммаС, 2) <> СуммаС Или Окр(СуммаПо, 2) <> СуммаПо Тогда
        ВызватьИсключение "OWN-REPORT-RANGE: нужны0..1000, два знака, начало не больше конца";
    КонецЕсли;
КонецПроцедуры

Функция СоздатьСвоиДанные85()
    ПользовательUUID = ПроверитьСвойСтенд85();
    Менеджеры = Отчеты;
    Если ТипЗнч(Менеджеры) <> Тип("ОтчетыМенеджер") Тогда
        ВызватьИсключение "OWN-REPORT-FACTORY: нужен настоящий менеджер отчетов";
    КонецЕсли;
    СвойОтчет = Менеджеры["УчебныйОтбор85"].Создать();
    Если ТипЗнч(СвойОтчет) <> Тип("ОтчетОбъект.УчебныйОтбор85") Или СвойОтчет.Строки85.Количество() <> 0 Тогда
        ВызватьИсключение "OWN-REPORT-FACTORY: нужен новый пустой экземпляр";
    КонецЕсли;
    СвойUUID = Новый УникальныйИдентификатор;
    СвойОтчет.Маркер85 = Строка(СвойUUID);
    СвойОтчет.Заголовок85 = "Три своих учебных товара";
    СвойОтчет.СуммаС85 = 250;
    СвойОтчет.СуммаПо85 = 750;
    СвойОтчет.ВключатьГраницы85 = Истина;
    СвойОтчет.ОтбиратьPAPER85 = Истина;
    Для Каждого Образец Из СвоиОбразцы85() Цикл
        НоваяСтрока = СвойОтчет.Строки85.Добавить();
        НоваяСтрока.Код85 = Образец.Код85;
        НоваяСтрока.Категория85 = Образец.Категория85;
        НоваяСтрока.Количество85 = Образец.Количество85;
        НоваяСтрока.Цена85 = Образец.Цена85;
        НоваяСтрока.Сумма85 = НоваяСтрока.Количество85 * НоваяСтрока.Цена85;
    КонецЦикла;
    ПроверитьОтчет85(СвойОтчет, СвойUUID);
    Контекст = Новый Структура("UUID,ПользовательUUID,Отчет", СвойUUID, ПользовательUUID, СвойОтчет);
    Если Не СвойОтчет.ПроверитьЗаполнение() Тогда
        ВызватьИсключение "OWN-REPORT-FILL: подготовленные данные не прошли native проверку";
    КонецЕсли;
    Возврат Контекст;
КонецФункции

Процедура ПроверитьКонтекст85(Контекст) Экспорт
    Если ТипЗнч(Контекст) <> Тип("Структура") Или Контекст.Количество() <> 3 Тогда
        ВызватьИсключение "OWN-REPORT-CONTEXT: нужен свой полный контекст";
    КонецЕсли;
    Если Не Контекст.Свойство("UUID", UUID) Или Не Контекст.Свойство("ПользовательUUID", ПользовательUUID)
        Или Не Контекст.Свойство("Отчет", СвойОтчет) Тогда
        ВызватьИсключение "OWN-REPORT-CONTEXT: неверные поля контекста";
    КонецЕсли;
    Если ТипЗнч(ПользовательUUID) <> Тип("УникальныйИдентификатор") Или ПользовательUUID <> ПроверитьСвойСтенд85() Тогда
        ВызватьИсключение "OWN-REPORT-USER: контекст не своего пользователя";
    КонецЕсли;
    ПроверитьОтчет85(СвойОтчет, UUID);
КонецПроцедуры

Функция СнятьНастройки85(Контекст) Экспорт
    ПроверитьКонтекст85(Контекст);
    СвойОтчет = Контекст.Отчет;
    Возврат Новый ФиксированнаяСтруктура(Новый Структура("Маркер,Заголовок,СуммаС,СуммаПо,ВключатьГраницы,ОтбиратьPAPER",
        СвойОтчет.Маркер85, СвойОтчет.Заголовок85, СвойОтчет.СуммаС85, СвойОтчет.СуммаПо85,
        СвойОтчет.ВключатьГраницы85, СвойОтчет.ОтбиратьPAPER85));
КонецФункции

Процедура ПроверитьСнимок85(Контекст, Снимок) Экспорт
    Свежий = СнятьНастройки85(Контекст);
    Если ТипЗнч(Снимок) <> Тип("ФиксированнаяСтруктура") Или Снимок.Количество() <> 6 Тогда
        ВызватьИсключение "OWN-REPORT-SNAPSHOT: нужен свой снимок";
    КонецЕсли;
    Для Каждого Пара Из Свежий Цикл
        Если Не Снимок.Свойство(Пара.Ключ, Значение) Или ТипЗнч(Значение) <> ТипЗнч(Пара.Значение) Или Значение <> Пара.Значение Тогда
            ВызватьИсключение "OWN-REPORT-SNAPSHOT: настройки уже изменились; остановитесь";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Процедура ПринятьГраницы85(Контекст, Снимок, СуммаС, СуммаПо, ВключатьГраницы, ОтбиратьPAPER) Экспорт
    ПроверитьСнимок85(Контекст, Снимок);
    ПроверитьГраницы85(СуммаС, СуммаПо, ВключатьГраницы, ОтбиратьPAPER);
    Контекст.Отчет.СуммаС85 = СуммаС;
    Контекст.Отчет.СуммаПо85 = СуммаПо;
    Контекст.Отчет.ВключатьГраницы85 = ВключатьГраницы;
    Контекст.Отчет.ОтбиратьPAPER85 = ОтбиратьPAPER;
    Свежий = СнятьНастройки85(Контекст);
    Если Свежий.СуммаС <> СуммаС Или Свежий.СуммаПо <> СуммаПо Или Свежий.ВключатьГраницы <> ВключатьГраницы
        Или Свежий.ОтбиратьPAPER <> ОтбиратьPAPER Тогда
        ВызватьИсключение "OWN-REPORT-READBACK: принятие настроек не подтверждено";
    КонецЕсли;
КонецПроцедуры

Функция ОжидаемыеСтроки85(СуммаС, СуммаПо, ВключатьГраницы, ОтбиратьPAPER)
    ПроверитьГраницы85(СуммаС, СуммаПо, ВключатьГраницы, ОтбиратьPAPER);
    Ожидания = Новый Массив;
    Для Каждого Образец Из СвоиОбразцы85() Цикл
        ВДиапазоне = ?(ВключатьГраницы, Образец.Сумма85 >= СуммаС И Образец.Сумма85 <= СуммаПо,
            Образец.Сумма85 > СуммаС И Образец.Сумма85 < СуммаПо);
        Если ВДиапазоне И (Не ОтбиратьPAPER Или Образец.Категория85 = "PAPER") Тогда
            Ожидания.Добавить(Образец);
        КонецЕсли;
    КонецЦикла;
    Возврат Ожидания;
КонецФункции

Функция ВыполнитьСвойПостроитель85(Построитель, Ожидания)
    Построитель.Выполнить();
    Если ТипЗнч(Построитель.Результат) <> Тип("РезультатЗапроса") Тогда
        ВызватьИсключение "OWN-REPORT-RESULT: нет настоящего результата";
    КонецЕсли;
    Результат = Построитель.Результат.Выгрузить();
    ПроверитьТаблицу85(Результат, Ожидания, Ложь);
    Возврат Результат;
КонецФункции

Функция ОтобратьСвоиСтроки85(СвойОтчет, СвойUUID)
    Данные = ПроверитьОтчет85(СвойОтчет, СвойUUID);
    Описание = Новый ОписаниеИсточникаДанных(Данные);
    ПроверитьТаблицу85(Описание.ИсточникДанных, СвоиОбразцы85());
    Если Описание.Колонки.Количество() <> 5 Тогда
        ВызватьИсключение "OWN-REPORT-SOURCE: описание не своего источника";
    КонецЕсли;
    Для Каждого КолонкаОписания Из Описание.Колонки Цикл
        Если Данные.Колонки.Найти(КолонкаОписания.Имя) = Неопределено Тогда
            ВызватьИсключение "OWN-REPORT-SOURCE: чужая колонка описания";
        КонецЕсли;
        КолонкаОписания.Поле = Истина;
        Если КолонкаОписания.Имя = "Категория85" Или КолонкаОписания.Имя = "Сумма85" Тогда
            Если ТипЗнч(КолонкаОписания.Отбор) <> Тип("Булево") Или Не КолонкаОписания.Отбор Тогда
                ВызватьИсключение "OWN-REPORT-SOURCE: native возможность отбора должна быть доступна";
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Построитель = Новый ПостроительОтчета;
    Построитель.ИсточникДанных = Описание;
    Построитель.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
    Построитель.ВыбранныеПоля.Очистить();
    Для Каждого Колонка Из Данные.Колонки Цикл
        Построитель.ВыбранныеПоля.Добавить(Колонка.Имя, Колонка.Имя);
    КонецЦикла;
    Отбор85 = Построитель.Отбор;
    Если ТипЗнч(Отбор85) <> Тип("Отбор") Или Отбор85.Количество() <> 0 Тогда
        ВызватьИсключение "OWN-REPORT-FILTER: нужен собственный пустой отбор";
    КонецЕсли;
    Доступные = Отбор85.ПолучитьДоступныеПоля();
    Если ТипЗнч(Доступные) <> Тип("ПоляНастройки") Или Доступные.Найти("Категория85") = Неопределено
        Или Доступные.Найти("Сумма85") = Неопределено Тогда
        ВызватьИсключение "OWN-REPORT-FILTER: свои поля недоступны";
    КонецЕсли;
    Для Каждого Поле Из Доступные Цикл
        Если Данные.Колонки.Найти(Поле.Имя) = Неопределено Тогда
            ВызватьИсключение "OWN-REPORT-FILTER: доступно неизвестное поле";
        КонецЕсли;
    КонецЦикла;
    Категория = Отбор85.Добавить("Категория85", "СвояКатегория85", "Только свои PAPER");
    Интервал = Отбор85.Добавить("Сумма85", "СвойИнтервал85", "Свой диапазон суммы");
    Если Категория = Неопределено Или Интервал = Неопределено Тогда
        ВызватьИсключение "OWN-REPORT-FILTER: native Добавить вернул Неопределено";
    КонецЕсли;
    Категория.ВидСравнения = ВидСравнения.Равно;
    Категория.Значение = "PAPER";
    Категория.Использование = Истина;
    Интервал.ВидСравнения = ?(СвойОтчет.ВключатьГраницы85, ВидСравнения.ИнтервалВключаяГраницы, ВидСравнения.Интервал);
    Интервал.ЗначениеС = СвойОтчет.СуммаС85;
    Интервал.ЗначениеПо = СвойОтчет.СуммаПо85;
    Интервал.Использование = Истина;
    Интервал.Представление = "Диапазон собственного отчета " + Строка(СвойUUID);
    Если Отбор85.Количество() <> 2 Или Отбор85.Индекс(Категория) <> 0 Или Отбор85.Индекс(Интервал) <> 1
        Или Отбор85.Получить(0) <> Категория Или Отбор85.Получить(1) <> Интервал
        Или Категория.ПутьКДанным <> "Категория85" Или Интервал.ПутьКДанным <> "Сумма85"
        Или Интервал.Представление <> "Диапазон собственного отчета " + Строка(СвойUUID)
        Или Интервал.ЗначениеС <> СвойОтчет.СуммаС85 Или Интервал.ЗначениеПо <> СвойОтчет.СуммаПо85 Тогда
        ВызватьИсключение "OWN-REPORT-FILTER: неверная структура собственных условий";
    КонецЕсли;
    СКатегорией = ОжидаемыеСтроки85(СвойОтчет.СуммаС85, СвойОтчет.СуммаПо85, СвойОтчет.ВключатьГраницы85, Истина);
    ВыполнитьСвойПостроитель85(Построитель, СКатегорией);
    Отбор85.Сдвинуть(Отбор85.Индекс(Интервал), -1);
    Если Отбор85.Индекс(Интервал) <> 0 Или Отбор85.Индекс(Категория) <> 1 Или Отбор85.Получить(0) <> Интервал Тогда
        ВызватьИсключение "OWN-REPORT-FILTER: перемещение собственного условия не подтверждено";
    КонецЕсли;
    Результат = ВыполнитьСвойПостроитель85(Построитель, СКатегорией);
    Если Не СвойОтчет.ОтбиратьPAPER85 Тогда
        ИндексКатегории = Отбор85.Индекс(Категория);
        Если ИндексКатегории <> 1 Или Отбор85.Количество() <> 2 Или Отбор85.Получить(ИндексКатегории) <> Категория Тогда
            ВызватьИсключение "OWN-REPORT-FILTER: удаление только подтвержденного собственного условия";
        КонецЕсли;
        Отбор85.Удалить(ИндексКатегории);
        Если Отбор85.Количество() <> 1 Или Отбор85.Индекс(Категория) <> -1 Или Отбор85.Получить(0) <> Интервал Тогда
            ВызватьИсключение "OWN-REPORT-FILTER: удаление собственного условия не подтверждено";
        КонецЕсли;
        Ожидания = ОжидаемыеСтроки85(СвойОтчет.СуммаС85, СвойОтчет.СуммаПо85, СвойОтчет.ВключатьГраницы85, Ложь);
        Результат = ВыполнитьСвойПостроитель85(Построитель, Ожидания);
    КонецЕсли;
    ПроверитьТаблицу85(Описание.ИсточникДанных, СвоиОбразцы85());
    ПроверитьОтчет85(СвойОтчет, СвойUUID);
    Возврат Результат;
КонецФункции

Процедура ПроверитьДокумент85(Документ, Ожидания) Экспорт
    Если ТипЗнч(Документ) <> Тип("ТабличныйДокумент") И ТипЗнч(Документ) <> Тип("ПолеТабличногоДокумента") Тогда
        ВызватьИсключение "OWN-REPORT-OUTPUT-TYPE: нужен свой документ или его поле";
    КонецЕсли;
    Если Документ.ВысотаТаблицы <> Ожидания.Количество() + 3 Или Документ.ШиринаТаблицы <> 5
        Или Документ.Область(1, 1).Текст <> "Собственный учебный отбор" Тогда
        ВызватьИсключение "OWN-REPORT-OUTPUT: неверная структура вывода";
    КонецЕсли;
    Сумма = 0;
    Если Ожидания.Количество() > 0 Тогда
        Для Индекс = 0 По Ожидания.Количество() - 1 Цикл
            Образец = Ожидания[Индекс];
            СтрокаВывода = Индекс + 3;
            Если Документ.Область(СтрокаВывода, 1).Текст <> Образец.Код85
                Или Документ.Область(СтрокаВывода, 2).Текст <> Образец.Категория85 Тогда
                ВызватьИсключение "OWN-REPORT-OUTPUT: неверный собственный товар";
            КонецЕсли;
            Для НомерКолонки = 3 По 5 Цикл
                Имя = СтрРазделить("Код85,Категория85,Количество85,Цена85,Сумма85", ",")[НомерКолонки - 1];
                Ячейка = Документ.Область(СтрокаВывода, НомерКолонки);
                Если Не Ячейка.СодержитЗначение Или ТипЗнч(Ячейка.Значение) <> Тип("Число") Или Ячейка.Значение <> Образец[Имя] Тогда
                    ВызватьИсключение "OWN-REPORT-OUTPUT: числа проверяются как числа, не строки";
                КонецЕсли;
            КонецЦикла;
            Сумма = Сумма + Образец.Сумма85;
        КонецЦикла;
    КонецЕсли;
    Итог = Документ.Область(Ожидания.Количество() + 3, 5);
    Если Не Итог.СодержитЗначение Или ТипЗнч(Итог.Значение) <> Тип("Число") Или Итог.Значение <> Сумма Тогда
        ВызватьИсключение "OWN-REPORT-OUTPUT: итог не совпал с независимыми ожиданиями";
    КонецЕсли;
КонецПроцедуры

Процедура СформироватьСвойДокумент85(СвойОтчет, СвойUUID, ДокументРезультат) Экспорт
    Если ТипЗнч(ДокументРезультат) <> Тип("ТабличныйДокумент") Или ДокументРезультат.ВысотаТаблицы <> 0 Тогда
        ВызватьИсключение "OWN-REPORT-OUTPUT-TYPE: только свой новый пустой документ";
    КонецЕсли;
    СтрокиРезультата = ОтобратьСвоиСтроки85(СвойОтчет, СвойUUID);
    Ожидания = ОжидаемыеСтроки85(СвойОтчет.СуммаС85, СвойОтчет.СуммаПо85, СвойОтчет.ВключатьГраницы85, СвойОтчет.ОтбиратьPAPER85);
    ДокументРезультат.Область(1, 1).Текст = "Собственный учебный отбор";
    Имена = СтрРазделить("Код85,Категория85,Количество85,Цена85,Сумма85", ",");
    Для Индекс = 0 По 4 Цикл
        ДокументРезультат.Область(2, Индекс + 1).Текст = Имена[Индекс];
    КонецЦикла;
    Если Ожидания.Количество() > 0 Тогда
        Для Индекс = 0 По Ожидания.Количество() - 1 Цикл
            Образец = Ожидания[Индекс];
            СтрокаРезультата = СтрокиРезультата.Найти(Образец.Код85, "Код85");
            Если СтрокаРезультата = Неопределено Тогда
                ВызватьИсключение "OWN-REPORT-RESULT: собственная ожидаемая строка не найдена";
            КонецЕсли;
            Для Колонка = 0 По 4 Цикл
                Ячейка = ДокументРезультат.Область(Индекс + 3, Колонка + 1);
                Если Колонка < 2 Тогда
                    Ячейка.Текст = СтрокаРезультата[Имена[Колонка]];
                Иначе
                    Ячейка.СодержитЗначение = Истина;
                    Ячейка.Значение = СтрокаРезультата[Имена[Колонка]];
                КонецЕсли;
            КонецЦикла;
        КонецЦикла;
    КонецЕсли;
    ИтоговаяСтрока = Ожидания.Количество() + 3;
    ДокументРезультат.Область(ИтоговаяСтрока, 1).Текст = "Итого";
    Итог = ДокументРезультат.Область(ИтоговаяСтрока, 5);
    Итог.СодержитЗначение = Истина;
    Итог.Значение = 0;
    Для Каждого СтрокаРезультата Из СтрокиРезультата Цикл
        Итог.Значение = Итог.Значение + СтрокаРезультата.Сумма85;
    КонецЦикла;
    ПроверитьДокумент85(ДокументРезультат, Ожидания);
    ДокументРезультат.ТолькоПросмотр = Истина;
КонецПроцедуры

Функция Скомпоновать85(Контекст) Экспорт
    ПроверитьКонтекст85(Контекст);
    Снимок = СнятьНастройки85(Контекст);
    Если Не Контекст.Отчет.ПроверитьЗаполнение() Тогда
        ВызватьИсключение "OWN-REPORT-FILL: формирование отказано";
    КонецЕсли;
    Документ = Новый ТабличныйДокумент;
    Контекст.Отчет.СкомпоноватьРезультат(Документ);
    ПроверитьСнимок85(Контекст, Снимок);
    ПроверитьДокумент85(Документ, ОжидаемыеСтроки85(Снимок.СуммаС, Снимок.СуммаПо, Снимок.ВключатьГраницы, Снимок.ОтбиратьPAPER));
    Возврат Документ;
КонецФункции

Процедура ПроверитьЭтап85(Контекст, СуммаС, СуммаПо, ВключатьГраницы, ОтбиратьPAPER, ЧислоСтрок, Сумма)
    ПринятьГраницы85(Контекст, СнятьНастройки85(Контекст), СуммаС, СуммаПо, ВключатьГраницы, ОтбиратьPAPER);
    Документ = Скомпоновать85(Контекст);
    Если Документ.ВысотаТаблицы <> ЧислоСтрок + 3 Или Документ.Область(ЧислоСтрок + 3, 5).Значение <> Сумма Тогда
        ВызватьИсключение "OWN-REPORT-GOLDEN: не совпал независимый числовой этап";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьМаркерОтказа85(Номер, Маркер)
    ОтказПолучен = Ложь;
    Попытка
        Если Номер = 1 Тогда
            ПроверитьГраницы85("200", 750, Истина, Истина);
        ИначеЕсли Номер = 2 Тогда
            ПроверитьГраницы85(751, 750, Истина, Истина);
        ИначеЕсли Номер = 3 Тогда
            Контекст = СоздатьСвоиДанные85();
            Контекст.Отчет.Строки85.Получить(0).Сумма85 = 749;
            ПроверитьКонтекст85(Контекст);
        ИначеЕсли Номер = 4 Тогда
            Контекст = СоздатьСвоиДанные85();
            ПроверитьОтчет85(Контекст.Отчет, Новый УникальныйИдентификатор);
        ИначеЕсли Номер = 5 Тогда
            Контекст = СоздатьСвоиДанные85();
            Снимок = СнятьНастройки85(Контекст);
            Контекст.Отчет.СуммаС85 = 200;
            ПроверитьСнимок85(Контекст, Снимок);
        Иначе
            ВызватьИсключение "OWN-REPORT-NEGATIVE: неизвестная проверка";
        КонецЕсли;
    Исключение
        Если СтрНайти(ОписаниеОшибки(), Маркер) = 0 Тогда
            ВызватьИсключение;
        КонецЕсли;
        ОтказПолучен = Истина;
    КонецПопытки;
    Если Не ОтказПолучен Тогда
        ВызватьИсключение "OWN-REPORT-NEGATIVE: ожидаемый отказ не получен";
    КонецЕсли;
КонецПроцедуры

Процедура ОткрытьСвоиГраницы85(Контекст, ПолеВладелец) Экспорт
    ПроверитьКонтекст85(Контекст);
    Если ТипЗнч(ПолеВладелец) <> Тип("ПолеТабличногоДокумента") Тогда
        ВызватьИсключение "OWN-REPORT-FORM: только реальное поле своей формы результата";
    КонецЕсли;
    СвояФорма = Контекст.Отчет.ПолучитьФормуНастроек("УчебныеГраницы85", ПолеВладелец, Новый УникальныйИдентификатор);
    Если СвояФорма = Неопределено Или ТипЗнч(СвояФорма) <> Тип("Форма") Тогда
        ВызватьИсключение "OWN-REPORT-FORM: форма своих границ не создана";
    КонецЕсли;
    СвояФорма.Подготовить85(Контекст);
    СвояФорма.Открыть();
КонецПроцедуры

Процедура Запустить85() Экспорт
    Контекст = СоздатьСвоиДанные85();
    ПроверитьЭтап85(Контекст, 250, 750, Истина, Истина, 1, 750);
    ПроверитьЭтап85(Контекст, 200, 750, Истина, Истина, 2, 950);
    ПроверитьЭтап85(Контекст, 200, 750, Ложь, Истина, 0, 0);
    ПроверитьЭтап85(Контекст, 50, 750, Истина, Ложь, 3, 1000);
    ПроверитьМаркерОтказа85(1, "OWN-REPORT-RANGE-TYPE");
    ПроверитьМаркерОтказа85(2, "OWN-REPORT-RANGE:");
    ПроверитьМаркерОтказа85(3, "OWN-REPORT-DATA:");
    ПроверитьМаркерОтказа85(4, "OWN-REPORT-OWNER:");
    ПроверитьМаркерОтказа85(5, "OWN-REPORT-SNAPSHOT:");
    ПустойЗаголовок = СоздатьСвоиДанные85();
    ПустойЗаголовок.Отчет.Заголовок85 = "";
    Если ПустойЗаголовок.Отчет.ПроверитьЗаполнение() Тогда
        ВызватьИсключение "OWN-REPORT-FILL: пустой обязательный заголовок должен быть отвергнут";
    КонецЕсли;
    ПринятьГраницы85(Контекст, СнятьНастройки85(Контекст), 250, 750, Истина, Истина);
    ФормаРезультата = Контекст.Отчет.ПолучитьФорму("УчебныйРезультат85", , Контекст.UUID);
    Если ФормаРезультата = Неопределено Или ТипЗнч(ФормаРезультата) <> Тип("Форма") Тогда
        ВызватьИсключение "OWN-REPORT-FORM: создание своей обычной формы отказано";
    КонецЕсли;
    ФормаРезультата.ВосстанавливатьЗначенияПриОткрытии = Ложь;
    СвоеПоле = ФормаРезультата.ЭлементыФормы.Результат85;
    Если ТипЗнч(СвоеПоле) <> Тип("ПолеТабличногоДокумента") Тогда
        ВызватьИсключение "OWN-REPORT-FORM: результат должен выводиться в реальное свое поле";
    КонецЕсли;
    ФормаРезультата.РезультатОтчета = СвоеПоле;
    Если ФормаРезультата.ВосстанавливатьЗначенияПриОткрытии Или ФормаРезультата.РезультатОтчета <> СвоеПоле Тогда
        ВызватьИсключение "OWN-REPORT-FORM: настройка результата не подтверждена";
    КонецЕсли;
    ФормаРезультата.Подготовить85(Контекст);
    ФормаРезультата.Открыть();
КонецПроцедуры
Полный модуль объекта собственного отчета УчебныйОтбор85

Отчеты → УчебныйОтбор85 → Модуль объекта

Собственный File-стенд и толстое обычное приложение: символ ТолстыйКлиентОбычноеПриложение определен у обеих частей File; отдельные server/external/background и другие клиентские контексты отказывают до client-only общего модуля. Native события вызываются только платформой.

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
#Если ТолстыйКлиентОбычноеПриложение Тогда
    Если ТипЗнч(ПроверяемыеРеквизиты) <> Тип("Массив") Или ПроверяемыеРеквизиты.Найти("Заголовок85") = Неопределено Тогда
        Отказ = Истина;
        ВызватьИсключение "OWN-REPORT-FILL: в native списке должна оставаться проверка заголовка";
    КонецЕсли;
    УчебныйОтчетМаршрут85.ПроверитьОтчет85(ЭтотОбъект, Новый УникальныйИдентификатор(ЭтотОбъект.Маркер85), Истина);
#Иначе
    Отказ = Истина;
    ВызватьИсключение "OWN-REPORT-CONTEXT: проверка этого учебного отчета разрешена только в толстом обычном клиенте";
#КонецЕсли
КонецПроцедуры

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
#Если ТолстыйКлиентОбычноеПриложение Тогда
    УчебныйОтчетМаршрут85.ПроверитьОтчет85(ЭтотОбъект, Новый УникальныйИдентификатор(ЭтотОбъект.Маркер85));
    Если ДанныеРасшифровки <> Null Тогда
        ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    КонецЕсли;
    УчебныйОтчетМаршрут85.СформироватьСвойДокумент85(ЭтотОбъект, Новый УникальныйИдентификатор(ЭтотОбъект.Маркер85), ДокументРезультат);
#Иначе
    ВызватьИсключение "OWN-REPORT-CONTEXT: компоновка этого учебного отчета разрешена только в толстом обычном клиенте";
#КонецЕсли
КонецПроцедуры
Полный модуль обычной формы результата УчебныйРезультат85

Отчеты → УчебныйОтбор85 → Формы → УчебныйРезультат85 → Модуль

Толстый клиент, обычная форма отчета с главным реквизитом Отчет.

Перем СвойКонтекст85;

Процедура Подготовить85(Контекст) Экспорт
    УчебныйОтчетМаршрут85.ПроверитьКонтекст85(Контекст);
    Если Отчет <> Контекст.Отчет Тогда
        ВызватьИсключение "OWN-REPORT-FORM: форма должна принадлежать своему экземпляру";
    КонецЕсли;
    Если ТипЗнч(ЭлементыФормы.Результат85) <> Тип("ПолеТабличногоДокумента") Тогда
        ВызватьИсключение "OWN-REPORT-FORM: нужен свой реальный элемент управления";
    КонецЕсли;
    ВосстанавливатьЗначенияПриОткрытии = Ложь;
    РезультатОтчета = ЭлементыФормы.Результат85;
    Если ВосстанавливатьЗначенияПриОткрытии Или РезультатОтчета <> ЭлементыФормы.Результат85 Тогда
        ВызватьИсключение "OWN-REPORT-FORM: параметры своей формы не подтверждены";
    КонецЕсли;
    СвойКонтекст85 = Контекст;
КонецПроцедуры

Процедура ПриОткрытии()
    Если СвойКонтекст85 = Неопределено Тогда
        ВызватьИсключение "OWN-REPORT-FORM: запускайте только через свой модуль приложения";
    КонецЕсли;
    ВывестиСвоиДанные85();
КонецПроцедуры

Процедура Сформировать85(Кнопка)
    ПроверитьСвоюКнопку85(Кнопка, "Сформировать85");
    ВывестиСвоиДанные85();
КонецПроцедуры

Процедура ПроверитьСвоюКнопку85(Кнопка, Имя)
    Если Кнопка = Неопределено Или ТипЗнч(Кнопка) <> Тип("Кнопка") Тогда
        ВызватьИсключение "OWN-REPORT-BUTTON: нужна настоящая кнопка своей формы";
    КонецЕсли;
    Если Кнопка <> ЭлементыФормы[Имя] Или Кнопка.Имя <> Имя Тогда
        ВызватьИсключение "OWN-REPORT-BUTTON: неизвестная кнопка";
    КонецЕсли;
КонецПроцедуры

Процедура ВывестиСвоиДанные85()
    УчебныйОтчетМаршрут85.ПроверитьКонтекст85(СвойКонтекст85);
    Если Отчет <> СвойКонтекст85.Отчет Или РезультатОтчета <> ЭлементыФормы.Результат85
        Или ТипЗнч(РезультатОтчета) <> Тип("ПолеТабличногоДокумента") Или ВосстанавливатьЗначенияПриОткрытии Тогда
        ВызватьИсключение "OWN-REPORT-FORM: неизвестная форма или поле результата";
    КонецЕсли;
    НовыйДокумент = УчебныйОтчетМаршрут85.Скомпоновать85(СвойКонтекст85);
    РезультатОтчета.Очистить();
    РезультатОтчета.Вывести(НовыйДокумент);
    Если РезультатОтчета.ВысотаТаблицы <> НовыйДокумент.ВысотаТаблицы
        Или РезультатОтчета.ШиринаТаблицы <> НовыйДокумент.ШиринаТаблицы Тогда
        ВызватьИсключение "OWN-REPORT-FORM: вывод не подтвержден; не повторяйте автоматически";
    КонецЕсли;
    Для Строка = 1 По НовыйДокумент.ВысотаТаблицы Цикл
        Для Колонка = 1 По НовыйДокумент.ШиринаТаблицы Цикл
            Ожидаемая = НовыйДокумент.Область(Строка, Колонка);
            Факт = РезультатОтчета.Область(Строка, Колонка);
            Если Ожидаемая.СодержитЗначение Тогда
                Если Не Факт.СодержитЗначение Или ТипЗнч(Факт.Значение) <> ТипЗнч(Ожидаемая.Значение) Или Факт.Значение <> Ожидаемая.Значение Тогда
                    ВызватьИсключение "OWN-REPORT-FORM: число после вывода изменилось";
                КонецЕсли;
            Иначе
                Если Факт.СодержитЗначение Или Факт.Текст <> Ожидаемая.Текст Тогда
                    ВызватьИсключение "OWN-REPORT-FORM: текст после вывода изменился";
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    РезультатОтчета.ТолькоПросмотр = Истина;
КонецПроцедуры

Процедура Настройки85(Кнопка)
    ПроверитьСвоюКнопку85(Кнопка, "Настройки85");
    УчебныйОтчетМаршрут85.ПроверитьКонтекст85(СвойКонтекст85);
    Если Отчет <> СвойКонтекст85.Отчет Или РезультатОтчета <> ЭлементыФормы.Результат85 Тогда
        ВызватьИсключение "OWN-REPORT-FORM: владелец настроек должен быть своим";
    КонецЕсли;
    УчебныйОтчетМаршрут85.ОткрытьСвоиГраницы85(СвойКонтекст85, РезультатОтчета);
КонецПроцедуры
Полный модуль обычной формы настроек УчебныеГраницы85

Отчеты → УчебныйОтбор85 → Формы → УчебныеГраницы85 → Модуль

Толстый клиент, обычная форма настроек того же отчета; локальные реквизиты не связаны с Отчет.*.

Перем СвойКонтекст85;
Перем СвойСнимок85;
Перем Принято85;

Процедура Подготовить85(Контекст) Экспорт
    УчебныйОтчетМаршрут85.ПроверитьКонтекст85(Контекст);
    Если Отчет <> Контекст.Отчет Тогда
        ВызватьИсключение "OWN-REPORT-SETTINGS: не свой объект отчета";
    КонецЕсли;
    ВосстанавливатьЗначенияПриОткрытии = Ложь;
    Если ВосстанавливатьЗначенияПриОткрытии Тогда
        ВызватьИсключение "OWN-REPORT-SETTINGS: восстановление настроек должно быть отключено";
    КонецЕсли;
    СвойКонтекст85 = Контекст;
    СвойСнимок85 = УчебныйОтчетМаршрут85.СнятьНастройки85(Контекст);
    ГраницаС85 = СвойСнимок85.СуммаС;
    ГраницаПо85 = СвойСнимок85.СуммаПо;
    Включать85 = СвойСнимок85.ВключатьГраницы;
    КатегорияPAPER85 = СвойСнимок85.ОтбиратьPAPER;
    Принято85 = Ложь;
КонецПроцедуры

Процедура ПриОткрытии()
    УчебныйОтчетМаршрут85.ПроверитьСнимок85(СвойКонтекст85, СвойСнимок85);
    Если Отчет <> СвойКонтекст85.Отчет Или ВосстанавливатьЗначенияПриОткрытии Тогда
        ВызватьИсключение "OWN-REPORT-SETTINGS: неизвестная форма настроек";
    КонецЕсли;
КонецПроцедуры

Процедура Применить85(Кнопка)
    ПроверитьСвоюКнопку85(Кнопка, "Применить85");
    УчебныйОтчетМаршрут85.ПроверитьСнимок85(СвойКонтекст85, СвойСнимок85);
    Если Отчет <> СвойКонтекст85.Отчет Или Принято85 Тогда
        ВызватьИсключение "OWN-REPORT-SETTINGS: применение допускается один раз для своего объекта";
    КонецЕсли;
    УчебныйОтчетМаршрут85.ПринятьГраницы85(СвойКонтекст85, СвойСнимок85, ГраницаС85, ГраницаПо85, Включать85, КатегорияPAPER85);
    Принято85 = Истина;
    Закрыть();
КонецПроцедуры

Процедура Отмена85(Кнопка)
    ПроверитьСвоюКнопку85(Кнопка, "Отмена85");
    УчебныйОтчетМаршрут85.ПроверитьСнимок85(СвойКонтекст85, СвойСнимок85);
    Если Отчет <> СвойКонтекст85.Отчет Или Принято85 Тогда
        ВызватьИсключение "OWN-REPORT-SETTINGS: неизвестная отмена";
    КонецЕсли;
    Закрыть();
КонецПроцедуры

Процедура ПроверитьСвоюКнопку85(Кнопка, Имя)
    Если Кнопка = Неопределено Или ТипЗнч(Кнопка) <> Тип("Кнопка") Тогда
        ВызватьИсключение "OWN-REPORT-BUTTON: нужна настоящая кнопка своих настроек";
    КонецЕсли;
    Если Кнопка <> ЭлементыФормы[Имя] Или Кнопка.Имя <> Имя Тогда
        ВызватьИсключение "OWN-REPORT-BUTTON: неизвестная кнопка настроек";
    КонецЕсли;
КонецПроцедуры

Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    Если СвойКонтекст85 = Неопределено Или Отчет <> СвойКонтекст85.Отчет Тогда
        Отказ = Истина;
        ВызватьИсключение "OWN-REPORT-SETTINGS: неизвестный владелец закрываемой формы";
    КонецЕсли;
    Если Не Принято85 Тогда
        УчебныйОтчетМаршрут85.ПроверитьСнимок85(СвойКонтекст85, СвойСнимок85);
    Иначе
        УчебныйОтчетМаршрут85.ПроверитьКонтекст85(СвойКонтекст85);
    КонецЕсли;
КонецПроцедуры
Полный модуль обычного приложения собственной пустой CF

Корень конфигурации → Модуль обычного приложения

Толстый клиент; только native ПриНачалеРаботыСистемы.

Процедура ПриНачалеРаботыСистемы()
    УчебныйОтчетМаршрут85.Запустить85();
КонецПроцедуры

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

  1. Создать свой отчет через Отчеты[имя].Создать, доказать точные метаданные/пользователя/UUID и пустую табличную часть. Заполнить3 вымышленных товара. Сумма вычисляется как количество×цена, затем полная выгрузка независимо сравнивается с750/200/50 и общим1000.

  2. Вызвать native ПроверитьЗаполнение: платформа сама доставляет ОбработкаПроверкиЗаполнения. ЭтотОбъект — реальный текущий отчет внутри его модуля; проверка обязательного заголовка остается в native списке. Отдельный испорченный новый отчет должен быть отвергнут, не меняя положительный экземпляр.

  3. Создать ОписаниеИсточникаДанных из выгруженной ТаблицаЗначений. Проверить ее фактический ИсточникДанных и колонки. Включить5 своих выводимых полей через RW Поле; readonly возможность Отбор для категории/суммы только читать и проверить, никогда не включать присваиванием. Взять именно native Отбор своего нового построителя.

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

  5. Выполнить реальный построитель до и после Сдвинуть(числовой индекс,-1); все условия соединены И, поэтому результат тот же. Если PAPER выключен, перед Удалить заново подтвердить ровно свой индекс1 и свой элемент; после удаления проверять count1/index-1 и новые3 строки/1000.

  6. Проверить каждую строку native результата по всем5 полям, фактическим типам скалярных значений и математике. Квалификаторы9.2/Строка12 проверяются у источника; их неизменность у результата построителя не обещается. Сформировать свой табличный документ именно из настоящих строк результата, не из ожиданий; контроль ожиданий создается отдельно из фиксированных учебных чисел. Числовые ячейки проверяются через СодержитЗначение и Значение.

  7. Вызвать у собственного отчета СкомпоноватьРезультат с новым пустым ТабличныйДокумент. Native ПриКомпоновкеРезультата получает его, первым действием отключает стандартную обработку и строит только свой результат. После возврата подтвердить неизменность источника и настроек, а также все ячейки.

  8. Получить у своего экземпляра собственную обычную форму результата. РезультатОтчета — ссылка на реальное ПолеТабличногоДокумента, а не сам ТабличныйДокумент. Полный readback после Вывести сравнивает каждую текстовую и числовую ячейку.

  9. Получить собственную форму границ через ПолучитьФормуНастроек, с реальным своим полем как владельцем и свежим UUID-ключом. Только Применить передает валидированные локальные реквизиты в отчет. Отмена и крестик лишь проверяют исходное фактическое состояние; чужих изменений не откатывают.

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

  1. Полный неизменный источник: BOOK/PAPER3/250/750; PAD/PAPER2/100/200; PEN/OFFICE1/50/50. Все5 типов колонок точны, исходный итог1000.

  2. 250..750 включительно +PAPER:1 строка750; 200..750 включительно +PAPER:2 строки950; 200..750 строго +PAPER:0 строк0; 50..750 включительно без категории:3 строки1000.

  3. У собственного отбора после добавления2 элемента; интервал перемещается1→0, категория0→1. После явного удаления категории1 элемент, индекс старого элемента=-1. Полные строки до/после перестановки одинаковы.

  4. 5 ожидаемых исключений: строковая граница, начало больше конца, сумма749 вместо750, чужой UUID и изменение состояния после снимка. Только точные собственные маркеры принимаются; неожиданное исключение перекидывается.

  5. Положительный заполненный отчет: native ПроверитьЗаполнение=Истина. Отдельный новый отчет с пустым Заголовок85: Ложь. Обработчики не вызываются напрямую и не подменяются обычными функциями.

  6. После изменения локальных полей и Отмена/крестика настоящий отчет и строки остаются прежними. Изменившийся извне отчет дает fail-stop, а не восстановление прошлого состояния.

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

Ожидаемый при ручном запуске результат — собственный читаемый отчет и4 подтвержденных итога750/950/0/1000 с отдельным безопасным вводом границ. Реальные1С/ИБ/формы/компоновка и внутреннее поведение сохранения платформы не проверялись; выполнены авторство и статические проверки контрактов.

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

  1. Это старый ПостроительОтчета для изучения/сопровождения, не СКД и не рекомендация заменять современную компоновку. Схема компоновки и неизвестные рабочие источники не требуются.

  2. ПолучитьДоступныеПоля/Добавить/Удалить запрещены справкой у отборов динамических списков. Здесь receiver только Отбор собственного построителя; не копируйте код на СправочникСписок или ДокументСписок.

  3. Сдвинуть и Удалить у Отбор получают числовые индексы. Не переносите контракт коллекций, где передается сам элемент. ПутьКДанным только для чтения, Представление не переименовывает исходную колонку.

  4. Ctor ОписаниеИсточникаДанных принимает ТаблицаЗначений/РезультатЗапроса/ОбластьЯчеек, не табличную часть. Поэтому выполняется настоящая Выгрузить с явным списком5 колонок и без стандартного НомерСтроки.

  5. В8.5.1 новый ОбработкаКомпоновкиРезультата может получать readonly копию отчета для фонового формирования. Его здесь нет. Старый ПриКомпоновкеРезультата документирован как callback метода СкомпоноватьРезультат; Standard=false исключает стандартную схему/новый callback.

  6. По native справке безопасный режим на время старых обработчиков объекта временно отключается платформой. Урок сам защиту не отключает, а использует только свою пустую конфигурацию, проверенный источник и память. Это не образец запуска недоверенного рабочего кода.

  7. ВосстанавливатьЗначенияПриОткрытии=false отключает именно автоматическое восстановление настроек формы. Это не универсальный запрет внутренних UI-кешей и не доказательство отсутствия любой внутренней системной записи. Явных storage/settings/file/network/DB write вызовов в уроке нет.

  8. Изменение локальных реквизитов формы настроек не должно быть связано с Отчет.* напрямую. Применение нескольких присваиваний и замена вывода не атомарны: неожиданная ошибка требует остановки, не скрытого rollback или повтора.

  9. Нет печати, URL, внешних данных, записи строк в ИБ, сохранения отчета в файл, запуска фонового задания и прямых вызовов native callback. Метаданные и подготовку пользователь создаёт вручную только в новой пустой ИБ.

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

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

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

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

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