Получает индекс элемента отбора в коллекции отборов.
Синтаксис
Индекс(<ЭлементОтбора>)Полное описание, параметры и ограничения
Отбор.Индекс (Filter.IndexOf)
Отбор (Filter)
Индекс (IndexOf)
Доступен, начиная с версии 8.0.
Синтаксис:
Индекс(<ЭлементОтбора>)
Параметры:
<ЭлементОтбора> (обязательный)
Тип: ЭлементОтбора.
Элемент отбора, индекс которого требуется определить.
Возвращаемое значение:
Тип: Число.
Индекс указанного элемента в коллекции. Если не найдено, то возвращается -1.
Описание:
Получает индекс элемента отбора в коллекции отборов.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Использование в версии:
Доступен, начиная с версии 8.0.
Методическая информация
Практические примеры
Свой отчет в памяти: интервальные отборы, границы и две обычные формы
Полный маршрут для новичка на отдельной пустой конфигурации. Настоящий менеджер создает отчет, его собственная табличная часть дает типизированный источник построителю; отборы и native компоновка проверяются по полным строкам и числам, а Отмена не восстанавливает чужие изменения.
Где и как запускать
Толстый клиент, обычное приложение собственной новой пустой CF; общий модуль УчебныйОтчетМаршрут85, только Клиент (обычное приложение).
Подготовка
Не открывайте УТ/КА/УНФ/БП и не вставляйте этот код в рабочий отчет. Вручную создайте отдельную новую пустую файловую ИБ на установленной платформе8.5.1.1343. Имя конфигурации строго УчебныйОтчетОтбор85. В этой задаче отчет, его строки и отборы живут только в памяти; урок не создает справочников, документов или записей регистров.
В свойствах конфигурации настройте поддерживаемые режимы запуска: Управляемое приложение и обычное приложение; основной режим запуска: Обычное приложение. Первый выбор нужен, чтобы в свойствах общего модуля был виден флаг Клиент (обычное приложение). Проверяйте урок только в собственной файловой ИБ и толстом обычном клиенте, не в тонком/веб/мобильном. ПолучитьФорму и ПолучитьФормуНастроек здесь возвращают старую Форма и по native справке доступны только толстому клиенту.
Сохраните только свою новую конфигурацию и ее собственную учебную базу вручную. Справочники, документы, перечисления, все регистры/планы, общие реквизиты, подписки, задания, внешние источники, константы, обработки, общие формы и хранилища настроек должны отсутствовать. Не устанавливайте расширения ни в ИБ, ни в сеанс. Защитные проверки читают эти списки, но не меняют их.
В ветке Роли создайте единственную роль УчебныйАдминистратор85 с административными правами своей пустой ИБ. В Администрирование → Пользователи создайте ровно одного своего пользователя УченикОтчет85, назначьте эту роль и войдите им. Это ручная подготовка только нового учебного стенда: код пользователей/ролей не создает и не меняет, не выводит их имена или UUID. UUID текущего пользователя сравнивается с единственным реальным пользователем, а не выдумывается.
В Общие → Общие модули создайте единственный модуль УчебныйОтчетМаршрут85. Флаги: Клиент (обычное приложение)=Да, Сервер=Нет, Глобальный=Нет, Привилегированный=Нет. Главный блок урока целиком вставьте в этот модуль. Директив &НаСервере/НаКлиенте в нем нет: это именно толстый обычный клиент.
В Отчеты создайте единственный отчет УчебныйОтбор85. Макетов и основной схемы компоновки не создавайте: результат сформирует собственный полный обработчик ПриКомпоновкеРезультата. Никакие ранее существовавшие отчеты или BSP не используются.
У отчета создайте ровно6 реквизитов: Маркер85 — Строка36 переменной длины; Заголовок85 — Строка80 переменной длины, Проверка заполнения=Показывать ошибку; СуммаС85 и СуммаПо85 — Число9.2, неотрицательное; ВключатьГраницы85 и ОтбиратьPAPER85 — Булево. Для всех, кроме Заголовок85, проверка заполнения=Не проверять. Не назначайте значения по умолчанию, обработчики изменения или сторонние проверки.
В табличных частях отчета создайте ровно одну Строки85 с5 реквизитами: Код85/Категория85 — Строка12 переменной длины; Количество85/Цена85/Сумма85 — Число9.2 неотрицательное. Проверка заполнения каждого=Не проверять. Не создавайте реквизит НомерСтроки самостоятельно: это стандартная нумерация табличной части.
Во вкладке модуль объекта отчета вставьте целиком первый дополнительный блок. Его native события назначаются по именам: ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) и ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка). В обоих обработчиках инструкции #Если ТолстыйКлиентОбычноеПриложение оставляют вызовы клиентского общего модуля только в этом контексте. В файловом обычном приложении этот символ определен у обеих частей приложения; это не универсальный запрет серверной части File. В отдельных серверных, внешних, фоновых и иных клиентских контекстах ветвь #Иначе отказывает до вызова общего модуля: проверка устанавливает Отказ=Истина, компоновка заранее отключает стандартную обработку и оба обработчика вызывают исключение. Не создавайте обработчик ОбработкаКомпоновкиРезультата и не вызывайте ни один из этих обработчиков напрямую.
У отчета создайте2 собственные обычные формы: УчебныйРезультат85 как форму отчета и УчебныеГраницы85 как форму настроек. Главный реквизит обеих — Отчет, тип ОтчетОбъект.УчебныйОтбор85. В свойствах форм отключите Восстанавливать настройки автоматически. Не добавляйте сохранение настроек, стандартные команды работы с хранилищем, файл/печать/расшифровку. Собственные команды только из следующих шагов.
В обычной форме УчебныйРезультат85 добавьте поле табличного документа Результат85 и две кнопки Сформировать85/Настройки85. Назначьте их действия одноименным процедурам модуля; событие формы ПриОткрытии — процедуре ПриОткрытии. Весь второй дополнительный блок — полный модуль этой формы. Отчет создается через native менеджер, а форма получается именно у этого экземпляра, не через неизвестную ссылку.
В обычной форме УчебныеГраницы85 создайте только локальные реквизиты формы ГраницаС85/ГраницаПо85 (Число9.2 неотрицательное), Включать85/КатегорияPAPER85 (Булево). Разместите2 числовых поля и2 флажка, связанные с этими реквизитами, НЕ с Отчет.СуммаС85/СуммаПо85 и НЕ напрямую с реквизитами отчета. Поэтому ввод в форму не меняет отчет до команды Применить.
Там же добавьте собственные кнопки Применить85 и Отмена85 с одноименными действиями. Назначьте события ПриОткрытии/ПередЗакрытием одноименным процедурам. Полный третий дополнительный блок — модуль этой формы. Не создавайте ПриИзменении для полей или автоматическую запись/сохранение в ПриЗакрытии.
В модуль обычного приложения вставьте целиком четвертый дополнительный блок; назначьте native событие ПриНачалеРаботыСистемы. Никакая команда не запускает программу/сервис/фоновое задание и не печатает документ. Подготовку метаданных и открытие своего тестового клиента выполняет только человек.
Перед запуском проверьте синтаксис всех5 модулей конфигурации. Если версия/права/состав метаданных или типы не совпали, остановитесь и исправьте только новый учебный стенд. Этот опубликованный текст проверен статически по installed native справке; запуск в1С не выполнен.
При начале собственного сеанса выполнятся4 числовых этапа750/950/0/1000 и5 ожидаемых исключений; затем отдельный новый отчет с пустым обязательным заголовком обязан дать Ложь у native ПроверитьЗаполнение. Платформа покажет только собственную учебную ошибку заполнения. Не очищайте чужие сообщения; здесь они не запрашиваются и никуда не отправляются.
После проверок открывается своя форма результата с BOOK3×250=750. Нажмите Настройки: поставьте200/750, включенные границы, PAPER, Применить; в форме результата нажмите Сформировать и ожидайте BOOK750 + PAD200 =950. Форма настроек не обещает автообновление другой формы: формирование явно отдельно.
Откройте настройки снова, меняйте только локальные поля, например50/750, и нажмите Отмена либо крестик окна. Затем Сформировать должен снова показать950, а не1000. Fresh readback проверяет неизменность всех6 настоящих реквизитов и всех3 строк; если отчет уже изменен извне, отмена не восстанавливает старый снимок, а останавливает работу.
Для проверки исключения границ поставьте200/750, выключите Включать, оставьте PAPER: оба собственных товара на границах исключены, итог0. Затем50/750, включенные границы, выключите PAPER: явное удаление только собственного условия категории дает3 товара и1000. Источник с3 строками/1000 не удаляется ни на одном шаге.
При неожиданной ошибке формирования/вывода/применения закройте свой тестовый сеанс и разберите ошибку. Код не обещает атомарности нескольких присваиваний или Очистить+Вывести, не повторяет неясно завершившиеся операции, не делает слепой 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();
КонецПроцедурыРазбор по шагам
Создать свой отчет через Отчеты[имя].Создать, доказать точные метаданные/пользователя/UUID и пустую табличную часть. Заполнить3 вымышленных товара. Сумма вычисляется как количество×цена, затем полная выгрузка независимо сравнивается с750/200/50 и общим1000.
Вызвать native ПроверитьЗаполнение: платформа сама доставляет ОбработкаПроверкиЗаполнения. ЭтотОбъект — реальный текущий отчет внутри его модуля; проверка обязательного заголовка остается в native списке. Отдельный испорченный новый отчет должен быть отвергнут, не меняя положительный экземпляр.
Создать ОписаниеИсточникаДанных из выгруженной ТаблицаЗначений. Проверить ее фактический ИсточникДанных и колонки. Включить5 своих выводимых полей через RW Поле; readonly возможность Отбор для категории/суммы только читать и проверить, никогда не включать присваиванием. Взять именно native Отбор своего нового построителя.
Получить настоящие доступные поля; проверить свои категория/сумма и отсутствие чужих имен. Добавить2 условия, проверить nullable результаты, имена/пути/диапазон/представление/позиции. ВидСравнения.Интервал исключает обе границы, ИнтервалВключаяГраницы включает их.
Выполнить реальный построитель до и после Сдвинуть(числовой индекс,-1); все условия соединены И, поэтому результат тот же. Если PAPER выключен, перед Удалить заново подтвердить ровно свой индекс1 и свой элемент; после удаления проверять count1/index-1 и новые3 строки/1000.
Проверить каждую строку native результата по всем5 полям, фактическим типам скалярных значений и математике. Квалификаторы9.2/Строка12 проверяются у источника; их неизменность у результата построителя не обещается. Сформировать свой табличный документ именно из настоящих строк результата, не из ожиданий; контроль ожиданий создается отдельно из фиксированных учебных чисел. Числовые ячейки проверяются через СодержитЗначение и Значение.
Вызвать у собственного отчета СкомпоноватьРезультат с новым пустым ТабличныйДокумент. Native ПриКомпоновкеРезультата получает его, первым действием отключает стандартную обработку и строит только свой результат. После возврата подтвердить неизменность источника и настроек, а также все ячейки.
Получить у своего экземпляра собственную обычную форму результата. РезультатОтчета — ссылка на реальное ПолеТабличногоДокумента, а не сам ТабличныйДокумент. Полный readback после Вывести сравнивает каждую текстовую и числовую ячейку.
Получить собственную форму границ через ПолучитьФормуНастроек, с реальным своим полем как владельцем и свежим UUID-ключом. Только Применить передает валидированные локальные реквизиты в отчет. Отмена и крестик лишь проверяют исходное фактическое состояние; чужих изменений не откатывают.
Как проверить результат
Полный неизменный источник: BOOK/PAPER3/250/750; PAD/PAPER2/100/200; PEN/OFFICE1/50/50. Все5 типов колонок точны, исходный итог1000.
250..750 включительно +PAPER:1 строка750; 200..750 включительно +PAPER:2 строки950; 200..750 строго +PAPER:0 строк0; 50..750 включительно без категории:3 строки1000.
У собственного отбора после добавления2 элемента; интервал перемещается1→0, категория0→1. После явного удаления категории1 элемент, индекс старого элемента=-1. Полные строки до/после перестановки одинаковы.
5 ожидаемых исключений: строковая граница, начало больше конца, сумма749 вместо750, чужой UUID и изменение состояния после снимка. Только точные собственные маркеры принимаются; неожиданное исключение перекидывается.
Положительный заполненный отчет: native ПроверитьЗаполнение=Истина. Отдельный новый отчет с пустым Заголовок85: Ложь. Обработчики не вызываются напрямую и не подменяются обычными функциями.
После изменения локальных полей и Отмена/крестика настоящий отчет и строки остаются прежними. Изменившийся извне отчет дает fail-stop, а не восстановление прошлого состояния.
Ожидаемый результат
Ожидаемый при ручном запуске результат — собственный читаемый отчет и4 подтвержденных итога750/950/0/1000 с отдельным безопасным вводом границ. Реальные1С/ИБ/формы/компоновка и внутреннее поведение сохранения платформы не проверялись; выполнены авторство и статические проверки контрактов.
На что обратить внимание
Это старый ПостроительОтчета для изучения/сопровождения, не СКД и не рекомендация заменять современную компоновку. Схема компоновки и неизвестные рабочие источники не требуются.
ПолучитьДоступныеПоля/Добавить/Удалить запрещены справкой у отборов динамических списков. Здесь receiver только Отбор собственного построителя; не копируйте код на СправочникСписок или ДокументСписок.
Сдвинуть и Удалить у Отбор получают числовые индексы. Не переносите контракт коллекций, где передается сам элемент. ПутьКДанным только для чтения, Представление не переименовывает исходную колонку.
Ctor ОписаниеИсточникаДанных принимает ТаблицаЗначений/РезультатЗапроса/ОбластьЯчеек, не табличную часть. Поэтому выполняется настоящая Выгрузить с явным списком5 колонок и без стандартного НомерСтроки.
В8.5.1 новый ОбработкаКомпоновкиРезультата может получать readonly копию отчета для фонового формирования. Его здесь нет. Старый ПриКомпоновкеРезультата документирован как callback метода СкомпоноватьРезультат; Standard=false исключает стандартную схему/новый callback.
По native справке безопасный режим на время старых обработчиков объекта временно отключается платформой. Урок сам защиту не отключает, а использует только свою пустую конфигурацию, проверенный источник и память. Это не образец запуска недоверенного рабочего кода.
ВосстанавливатьЗначенияПриОткрытии=false отключает именно автоматическое восстановление настроек формы. Это не универсальный запрет внутренних UI-кешей и не доказательство отсутствия любой внутренней системной записи. Явных storage/settings/file/network/DB write вызовов в уроке нет.
Изменение локальных реквизитов формы настроек не должно быть связано с Отчет.* напрямую. Применение нескольких присваиваний и замена вывода не атомарны: неожиданная ошибка требует остановки, не скрытого rollback или повтора.
Нет печати, URL, внешних данных, записи строк в ИБ, сохранения отчета в файл, запуска фонового задания и прямых вызовов native callback. Метаданные и подготовку пользователь создаёт вручную только в новой пустой ИБ.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.