Тип: СхемаКомпоновкиДанных. Схема компоновки, на основании которой будет выполняться отчет.
Полное описание, параметры и ограничения
ОтчетОбъект.<Имя отчета>.СхемаКомпоновкиДанных (ReportObject.<Report name>.DataCompositionSchema)
ОтчетОбъект.<Имя отчета> (ReportObject.<Report name>)
СхемаКомпоновкиДанных (DataCompositionSchema)
Доступен, начиная с версии 8.1.
Использование:
Чтение и запись.
Описание:
Тип: СхемаКомпоновкиДанных.
Схема компоновки, на основании которой будет выполняться отчет.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Создать штатный редактор собственного порога и сверить весь состав отчёта
Сервер создаёт редактор единственной собственной пользовательской настройки в подготовленной пустой группе. Завершённый ввод порогов 0→1→3 проверяется по actual параметру события и полному составу деталей. При пороге 3 пустой итог только наблюдается; типизированный/плоский вывод не обещан native и требует ручной проверки.
Где и как запускать
Полный модуль подготовленной управляемой формы собственного отчёта. Все процедуры на уровне модуля, директивы уже включены. Только толстый управляемый desktop-клиент 8.5.1.1343; runtime не проверен.
Подготовка
Никакие приведённые модули здесь не запускались. Статические проверки не компилируют и не запускают 1С, не подтверждают автоматическую разметку СКД, типизированные значения или отображение.
Создайте новую отдельную пустую учебную информационную базу платформы 8.5.1.1343. Имя конфигурации УчебныеФормыОтчетов85, основной режим запуска УправляемоеПриложение, режим совместимости НеИспользовать. Рабочую конфигурацию не используйте.
Создайте отдельного нового учебного пользователя собственной новой базы. Запустите именно толстый клиент в режиме управляемого приложения. Это обязательный desktop-стенд, не тонкий, web или мобильный клиент: native enum РежимОтображенияРезультатаОтчета доступен только в толстом клиенте.
Оставьте интерфейс собственной новой конфигурации Такси. Не меняйте интерфейс, пользователя или режимы окон рабочего сеанса. Дайте новому учебному пользователю права на собственный отчёт и команды; права текущего рабочего пользователя не меняйте.
В дереве конфигурации Отчёты создайте УчебныеТовары85. Реквизитов прикладных объектов, справочников, документов, регистров и записей базы для него не требуется. Модуль объекта отчёта оставьте пустым: события урока принадлежат ФОРМЕ, не объекту отчёта.
Схема полностью создаётся функцией СоздатьСхему в приложенном серверном общем модуле; файловый макет не нужен. Источник УчебныйИсточник имеет ТипИсточникаДанных Local, набор УчебныеТовары является запросом из собственных двух константных строк. Условие Количество > &МинимальноеКоличество, по умолчанию 0.
Свой параметр порога имеет ОписаниеТипов("Число", КвалификаторыЧисла(1,0,Неотрицательный)): только целые 0..9 по описанию, а правила этого опыта допускают лишь 0, 1, 3. Квалификатор передан явно: native запрещает хранить числа в ОписаниеТипов без него. Это наш узкий учебный тип, не универсальный тип количества.
Собственные четыре выбранных поля: Наименование, Количество, Цена, Сумма. Структура содержит только одну используемую группировку без полей группировки, с АвтоВыбраннымПолем: это детальные записи. Единственный ресурс Сумма вычисляется выражением Сумма(Сумма); в его массив Группировки добавлено документированное значение ОбщийИтог. Вложенных группировок и промежуточных итогов нет. Штатное размещение самого итога не считается заранее подтверждённым.
Полный отдельный модуль УчебныеОтчетыФорм85 вставьте в Общие → Общие модули → УчебныеОтчетыФорм85 → Модуль. Включите Сервер, выключите Клиент, Глобальный и Вызов сервера. Экспортные функции вызываются только из серверных обработчиков собственной формы.
Контракт СОБСТВЕННОГО вывода является условием будущего ручного опыта, не обещанием native авторазметки: одна строка с уникальными подписями Наименование, Количество, Цена, Сумма; далее полные детальные строки; один общий итог для непустого набора; вне найденных четырёх колонок нет данных. Максимум 200 строк и 40 колонок — защитная граница нашего reader, не предел платформы.
Числовые ячейки количества, цены, суммы и непустого общего итога должны иметь СодержитЗначение=Истина и Значение типа Число. Reader не устанавливает эти свойства, не исправляет результат и никогда не преобразует текст 750/50/800 в числа. При нарушении условия он выдаёт диагностику, КонтрольПрошел остаётся Ложь.
Сверка читает actual параметр Результат нового события ПослеКомпоновкиРезультата ДО помещения в реквизит. При опыте с режимами второй источник — actual реквизит формы Результат ПОСЛЕ преобразования. Ни исходный запрос, ни повторное вычисление суммы не подменяют эти источники.
В каждой собственной форме создайте дополнительные реквизиты СостояниеУрока и ОтпечатокДоПомещения типа Строка неограниченной длины, КонтрольПрошел типа Булево, ПорогПриКомпоновке и СобытийДо, СобытийПосле, СобытийИзменения типа Число длиной 6, точность 0, неотрицательный.
Для наблюдения создайте поля ПолеСостояния, ПолеКонтроля, ПолеПорога, ПолеСобытийДо, ПолеСобытийПосле, ПолеСобытийИзменения с путями к одноимённым подготовленным реквизитам СостояниеУрока, КонтрольПрошел, ПорогПриКомпоновке, СобытийДо, СобытийПосле, СобытийИзменения. Всем установите ТолькоПросмотр=Истина. Поле отпечатка необязательно: реквизит смотрите в отладчике.
Назначьте в свойствах событий ФОРМЫ ПриСозданииНаСервере → ПриСозданииНаСервере, ПриКомпоновкеРезультата → ПриКомпоновкеРезультата, ПослеКомпоновкиРезультата → ПослеКомпоновкиРезультата, ПриИзмененииНастроек → ПриИзмененииНастроек. Полные сигнатуры уже в модуле. Не назначайте трёхпараметрическое одноимённое событие модуля объекта отчёта.
АвтоматическоеСохранениеДанныхВНастройках собственной формы оставьте НеИспользовать. Не вызывайте сохранение вариантов, настроек, документа, печать или запись данных. Платформа всё же может читать/сохранять системные настройки отчётной формы: новый пользователь и новая база изолируют опыт, но это НЕ обещание отсутствия внутренних операций.
В Отчёты → УчебныеТовары85 → Формы создайте управляемую форму отчёта УчебныйПорог85 (тип формы Отчёта, Основная). В конструкторе выберите стандартную форму отчёта, не общую форму. Основной реквизит Отчет должен иметь тип ОтчетОбъект.УчебныеТовары85 и признак Основной.
Проверьте созданные конструктором реквизит Результат типа ТабличныйДокумент и поле табличного документа с ПутьКДанным=Результат; явно назовите это собственное поле ПолеРезультата. Стандартная команда Сформировать должна иметь штатный результат. Если конструктор дал иные имена, исправьте подготовку на указанные, не добавляйте второй результат и не угадывайте имя.
Полный основной блок вставьте целиком в Отчёты → УчебныеТовары85 → Формы → УчебныйПорог85 → Модуль формы. Замените только исходный пустой/сгенерированный модуль СВОЕЙ новой учебной формы; никакие модули рабочего отчёта не меняйте.
Создайте команды формы СформироватьИПроверить; каждой назначьте одноимённый обработчик из полного модуля и отдельную кнопку. Разместите их вне ПолеРезультата. Стандартные команды сохранения/печати в опыте не используйте.
Полный отдельный модуль запуска ОткрытьУчебныйПорог85 вставьте в Общие → Общие команды → ОткрытьУчебныйПорог85 → Модуль команды. Команду без параметра разместите в командном интерфейсе собственного учебного приложения. Каждый запуск передаёт свежий UUID ключа уникальности и не должен случайно переиспользовать предыдущий экземпляр.
В корне формы создайте собственную пустую обычную группу ГруппаУчебныхНастроек. Не добавляйте внутрь ручные поля: сервер создаст элементы штатно после загрузки схемы/настроек.
У параметра настроек до загрузки установлен непустой ИдентификаторПользовательскойНастройки=УчебныйПорог и ПредставлениеПользовательскойНастройки=Количество больше. Именно этот ID включает параметр в пользовательские настройки; не ищите выдуманные имена автоматически созданных элементов.
Редактируйте только видимый штатный числовой редактор собственной подписи Количество больше. Допустимые опытные значения 0, 1, 3, без дробей. Завершайте ввод выходом из поля до нажатия СформироватьИПроверить; обработчик на сервере также проверяет фактический тип и значение.
ПриИзмененииНастроек отключает стандартную реакцию только этого события, чтобы отчёт не формировался автоматически при вводе. Оно оставляет явную нашу и стандартную команды формирования доступными; глобальные пользовательские настройки автокомпоновки не меняются.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если ЭтаФорма.ТипФормыОтчета <> ТипФормыОтчета.Основная Тогда
Отказ = Истина;
ВызватьИсключение "Подготовьте именно управляемую форму отчёта Основная";
КонецЕсли;
ОбъектОтчета = ЭтаФорма.РеквизитФормыВЗначение("Отчет");
Схема = УчебныеОтчетыФорм85.СоздатьСхему();
ОбъектОтчета.СхемаКомпоновкиДанных = Схема;
ОбъектОтчета.КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
ОбъектОтчета.КомпоновщикНастроек.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
ЭтаФорма.ЗначениеВРеквизитФормы(ОбъектОтчета, "Отчет");
ЭтаФорма.ПорогПриКомпоновке = 0;
ЭтаФорма.СобытийДо = 0;
ЭтаФорма.СобытийПосле = 0;
ЭтаФорма.СобытийИзменения = 0;
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.ОтпечатокДоПомещения = "";
ЭтаФорма.СостояниеУрока = "Собственная схема готова. Контракт штатного вывода ещё не подтверждён";
ЭтаФорма.СоздатьЭлементыФормыПользовательскихНастроек(ЭтаФорма.Элементы.ГруппаУчебныхНастроек, РежимОтображенияНастроекКомпоновкиДанных.Все, 1);
КонецПроцедуры
&НаСервере
Процедура ПриКомпоновкеРезультата(СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.ОтпечатокДоПомещения = "";
ОбъектОтчета = ЭтаФорма.РеквизитФормыВЗначение("Отчет");
РабочиеНастройки = ОбъектОтчета.КомпоновщикНастроек.ПолучитьНастройки();
ПараметрНастроек = РабочиеНастройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МинимальноеКоличество"));
Если ПараметрНастроек = Неопределено Тогда
ВызватьИсключение "В фактических настройках нет собственного параметра";
КонецЕсли;
Если Не ПараметрНастроек.Использование Или ТипЗнч(ПараметрНастроек.Значение) <> Тип("Число") Тогда
ВызватьИсключение "Собственный числовой параметр должен использоваться";
КонецЕсли;
Порог = ПараметрНастроек.Значение;
Если Порог <> 0 И Порог <> 1 И Порог <> 3 Тогда
ВызватьИсключение "Завершите ввод одного из учебных порогов 0, 1, 3";
КонецЕсли;
ЭтаФорма.ПорогПриКомпоновке = Порог;
ЭтаФорма.СобытийДо = ЭтаФорма.СобытийДо + 1;
КонецПроцедуры
&НаСервере
Процедура ПослеКомпоновкиРезультата(Результат, СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
ЭтаФорма.СобытийПосле = ЭтаФорма.СобытийПосле + 1;
ЭтаФорма.КонтрольПрошел = Ложь;
Попытка
Прочитанное = УчебныеОтчетыФорм85.ПрочитатьПлоскийРезультат(Результат);
ЭтаФорма.ОтпечатокДоПомещения = УчебныеОтчетыФорм85.ПроверитьСоставИПолучитьОтпечаток(Прочитанное, ЭтаФорма.ПорогПриКомпоновке);
ЭтаФорма.КонтрольПрошел = Истина;
ЭтаФорма.СостояниеУрока = СтрШаблон("Прочитан фактический параметр события: порог %1; детали %2. %3",
ЭтаФорма.ПорогПриКомпоновке, Прочитанное.Детали.Количество(), Прочитанное.НаблюдениеИтога);
Исключение
ЭтаФорма.ОтпечатокДоПомещения = "";
ЭтаФорма.СостояниеУрока = "Контракт фактического вывода не подтверждён: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПриИзмененииНастроек(СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ЭтаФорма.СобытийИзменения = ЭтаФорма.СобытийИзменения + 1;
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.СостояниеУрока = "Настройки изменены. Завершите ввод и явно сформируйте новый результат";
КонецПроцедуры
&НаКлиенте
Процедура СформироватьИПроверить(Команда)
До = ЭтаФорма.СобытийДо;
После = ЭтаФорма.СобытийПосле;
ЭтаФорма.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Непосредственно);
Если ЭтаФорма.СобытийДо <> До + 1 Или ЭтаФорма.СобытийПосле <> После + 1 Тогда
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.СостояниеУрока = "Проверьте назначения двух событий именно формы отчёта";
КонецЕсли;
Сообщить(ЭтаФорма.СостояниеУрока);
КонецПроцедурыУчебныеОтчетыФорм85
Общие → Общие модули → УчебныеОтчетыФорм85 → Модуль
Полный отдельный серверный общий модуль УчебныеОтчетыФорм85. Только собственная учебная база и толстый управляемый desktop-клиент 8.5.1.1343; фактический запуск 1С не выполнен.
Функция СоздатьСхему() Экспорт
Схема = Новый СхемаКомпоновкиДанных;
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "УчебныйИсточник";
Источник.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Набор.Имя = "УчебныеТовары";
Набор.ИсточникДанных = Источник.Имя;
Набор.АвтоЗаполнениеДоступныхПолей = Истина;
Набор.Запрос = "ВЫБРАТЬ
| ""Книга"" КАК Наименование,
| 3 КАК Количество,
| 250 КАК Цена,
| 750 КАК Сумма
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""Ручка"", 1, 50, 50";
Настройки = Схема.НастройкиПоУмолчанию;
Для Каждого ИмяПоля Из СтрРазделить("Наименование,Количество,Цена,Сумма", ",") Цикл
Выбранное = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
Выбранное.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
Выбранное.Использование = Истина;
КонецЦикла;
Детали = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Детали.Использование = Истина;
АвтоВыбор = Детали.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
АвтоВыбор.Использование = Истина;
Набор.Запрос = "ВЫБРАТЬ Товары.Наименование, Товары.Количество, Товары.Цена, Товары.Сумма
|ИЗ (
|ВЫБРАТЬ
| ""Книга"" КАК Наименование,
| 3 КАК Количество,
| 250 КАК Цена,
| 750 КАК Сумма
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""Ручка"", 1, 50, 50
|) КАК Товары
|ГДЕ Товары.Количество > &МинимальноеКоличество";
Порог = Схема.Параметры.Добавить();
Порог.Имя = "МинимальноеКоличество";
Порог.Заголовок = "Количество больше";
Порог.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный));
Порог.Значение = 0;
Порог.Использование = ИспользованиеПараметраКомпоновкиДанных.Всегда;
Порог.ЗапрещатьНезаполненныеЗначения = Ложь;
Порог.ДоступенСписокЗначений = Ложь;
Порог.ОграничениеИспользования = Ложь;
Порог.ВключатьВДоступныеПоля = Ложь;
Итог = Схема.ПоляИтога.Добавить();
Итог.ПутьКДанным = "Сумма";
Итог.Выражение = "Сумма(Сумма)";
Итог.Группировки.Добавить("ОбщийИтог");
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("МинимальноеКоличество", 0);
ПараметрНастроек = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МинимальноеКоличество"));
Если ПараметрНастроек = Неопределено Тогда
ВызватьИсключение "Собственная схема не создала параметр порога";
КонецЕсли;
ПараметрНастроек.Использование = Истина;
ПараметрНастроек.ИдентификаторПользовательскойНастройки = "УчебныйПорог";
ПараметрНастроек.ПредставлениеПользовательскойНастройки = "Количество больше";
Возврат Схема;
КонецФункции
Функция ПрочитатьЯчейку(Документ, НомерСтроки, НомерКолонки)
Ячейка = Документ.Область(НомерСтроки, НомерКолонки);
Содержит = Ячейка.СодержитЗначение;
ЗначениеЯчейки = Неопределено;
Если Содержит Тогда
ЗначениеЯчейки = Ячейка.Значение;
КонецЕсли;
Возврат Новый Структура("Текст,Содержит,Значение", СокрЛП(Строка(Ячейка.Текст)), Содержит, ЗначениеЯчейки);
КонецФункции
Функция ЯчейкаПуста(Ячейка)
Возврат Ячейка.Текст = "" И (Не Ячейка.Содержит Или Ячейка.Значение = Неопределено);
КонецФункции
Функция ЧислоЯчейки(Ячейка, ИмяПоля)
Если Не Ячейка.Содержит Тогда
ВызватьИсключение "Нет типизированного значения поля " + ИмяПоля;
КонецЕсли;
Если ТипЗнч(Ячейка.Значение) <> Тип("Число") Тогда
ВызватьИсключение "Тип значения поля " + ИмяПоля + " не Число";
КонецЕсли;
Возврат Ячейка.Значение;
КонецФункции
Функция ПрочитатьПлоскийРезультат(Документ) Экспорт
Если ТипЗнч(Документ) <> Тип("ТабличныйДокумент") Тогда
ВызватьИсключение "Ожидался фактический ТабличныйДокумент";
КонецЕсли;
Высота = Документ.ВысотаТаблицы;
Ширина = Документ.ШиринаТаблицы;
Если Высота = 0 Или Ширина = 0 Или Высота > 200 Или Ширина > 40 Тогда
ВызватьИсключение "Вывод вне ограниченного собственного плоского контракта 200 на 40";
КонецЕсли;
Заголовки = СтрРазделить("Наименование,Количество,Цена,Сумма", ",");
Колонки = Неопределено;
СтрокаЗаголовков = 0;
Для НомерСтроки = 1 По Высота Цикл
Найденные = Новый Структура;
Для НомерКолонки = 1 По Ширина Цикл
Ячейка = ПрочитатьЯчейку(Документ, НомерСтроки, НомерКолонки);
Если Заголовки.Найти(Ячейка.Текст) <> Неопределено Тогда
Если Найденные.Свойство(Ячейка.Текст) Тогда
ВызватьИсключение "Повтор заголовка в одной строке: " + Ячейка.Текст;
КонецЕсли;
Найденные.Вставить(Ячейка.Текст, НомерКолонки);
КонецЕсли;
КонецЦикла;
Если Найденные.Количество() = 4 Тогда
Если Колонки <> Неопределено Тогда
ВызватьИсключение "Несколько полных строк заголовков: вывод неоднозначен";
КонецЕсли;
Колонки = Найденные;
СтрокаЗаголовков = НомерСтроки;
ИначеЕсли Найденные.Количество() <> 0 Тогда
ВызватьИсключение "Неполная строка собственных заголовков";
КонецЕсли;
КонецЦикла;
Если Колонки = Неопределено Тогда
ВызватьИсключение "Четыре собственных заголовка не найдены в одной строке";
КонецЕсли;
Детали = Новый Массив;
ИтогПрочитан = Ложь;
КандидатовИтога = 0;
ЗначениеИтога = Неопределено;
НаблюдениеИтога = "В колонке Сумма отдельная строка итога не обнаружена";
Для НомерСтроки = 1 По Высота Цикл
Для НомерКолонки = 1 По Ширина Цикл
Если НомерКолонки = Колонки.Наименование Или НомерКолонки = Колонки.Количество
Или НомерКолонки = Колонки.Цена Или НомерКолонки = Колонки.Сумма Тогда
Продолжить;
КонецЕсли;
ВнешняяЯчейка = ПрочитатьЯчейку(Документ, НомерСтроки, НомерКолонки);
Если Не ЯчейкаПуста(ВнешняяЯчейка) Тогда
ВызватьИсключение "Есть данные вне четырёх найденных колонок";
КонецЕсли;
КонецЦикла;
Если НомерСтроки = СтрокаЗаголовков Тогда
Продолжить;
КонецЕсли;
Имя = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Наименование);
Количество = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Количество);
Цена = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Цена);
Сумма = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Сумма);
Если Не ЯчейкаПуста(Количество) Или Не ЯчейкаПуста(Цена) Тогда
Если Имя.Текст = "" Тогда
ВызватьИсключение "Детальная строка без наименования";
КонецЕсли;
Если НомерСтроки < СтрокаЗаголовков Тогда
ВызватьИсключение "Детальные данные расположены перед заголовками";
КонецЕсли;
Детали.Добавить(Новый Структура("Наименование,Количество,Цена,Сумма", Имя.Текст,
ЧислоЯчейки(Количество, "Количество"), ЧислоЯчейки(Цена, "Цена"), ЧислоЯчейки(Сумма, "Сумма")));
Иначе
Если Имя.Текст <> "" И Имя.Текст <> "Итого" И Имя.Текст <> "Общий итог" И Имя.Текст <> "Всего" Тогда
ВызватьИсключение "Неполная детальная строка или неизвестная подпись: " + Имя.Текст;
КонецЕсли;
Если Не ЯчейкаПуста(Сумма) Или Имя.Текст <> "" Тогда
КандидатовИтога = КандидатовИтога + 1;
Если КандидатовИтога > 1 Тогда
ВызватьИсключение "Несколько итогов без деталей: вывод неоднозначен";
КонецЕсли;
КонецЕсли;
Если Не ЯчейкаПуста(Сумма) Тогда
ЗначениеИтога = ЧислоЯчейки(Сумма, "общий итог Сумма");
ИтогПрочитан = Истина;
НаблюдениеИтога = "Фактический типизированный итог: " + Строка(ЗначениеИтога);
ИначеЕсли Имя.Текст <> "" Тогда
НаблюдениеИтога = "Фактическая подпись " + Имя.Текст + ": ячейка Сумма пуста";
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Новый Структура("Детали,ЕстьИтог,Итог,НаблюдениеИтога", Детали, ИтогПрочитан, ЗначениеИтога, НаблюдениеИтога);
КонецФункции
Функция ПроверитьСоставИПолучитьОтпечаток(Прочитанное, Порог) Экспорт
Если ТипЗнч(Порог) <> Тип("Число") Тогда
ВызватьИсключение "Фактический порог не Число";
КонецЕсли;
Если Порог <> 0 И Порог <> 1 И Порог <> 3 Тогда
ВызватьИсключение "В этом опыте допустимы только пороги 0, 1, 3";
КонецЕсли;
КоличествоОжидается = 0;
Если Порог = 0 Тогда
КоличествоОжидается = 2;
ИначеЕсли Порог = 1 Тогда
КоличествоОжидается = 1;
КонецЕсли;
Если Прочитанное.Детали.Количество() <> КоличествоОжидается Тогда
ВызватьИсключение "Фактическое число детальных строк отличается от собственного набора";
КонецЕсли;
Книга = "";
Ручка = "";
Для Каждого Деталь Из Прочитанное.Детали Цикл
Если Деталь.Наименование = "Книга" Тогда
Если Книга <> "" Или Деталь.Количество <> 3 Или Деталь.Цена <> 250 Или Деталь.Сумма <> 750 Тогда
ВызватьИсключение "Неверная или повторная фактическая строка Книга";
КонецЕсли;
Книга = СтрШаблон("Книга;%1;%2;%3", Деталь.Количество, Деталь.Цена, Деталь.Сумма);
ИначеЕсли Деталь.Наименование = "Ручка" Тогда
Если Ручка <> "" Или Порог <> 0 Или Деталь.Количество <> 1 Или Деталь.Цена <> 50 Или Деталь.Сумма <> 50 Тогда
ВызватьИсключение "Неверная, повторная или лишняя фактическая строка Ручка";
КонецЕсли;
Ручка = СтрШаблон("Ручка;%1;%2;%3", Деталь.Количество, Деталь.Цена, Деталь.Сумма);
Иначе
ВызватьИсключение "Неизвестная фактическая детальная строка";
КонецЕсли;
КонецЦикла;
Если Порог < 3 И Книга = "" Тогда
ВызватьИсключение "В фактическом результате отсутствует Книга";
КонецЕсли;
Если Порог = 0 И Ручка = "" Тогда
ВызватьИсключение "В фактическом результате отсутствует Ручка";
КонецЕсли;
Если Порог < 3 Тогда
Если Не Прочитанное.ЕстьИтог Тогда
ВызватьИсключение "Нет отдельного типизированного общего итога";
КонецЕсли;
Если (Порог = 0 И Прочитанное.Итог <> 800) Или (Порог = 1 И Прочитанное.Итог <> 750) Тогда
ВызватьИсключение "Фактический общий итог отличается от собственного набора";
КонецЕсли;
КонецЕсли;
Возврат СтрШаблон("%1|%2|итог:%3:%4|%5", Книга, Ручка,
Прочитанное.ЕстьИтог, Строка(Прочитанное.Итог), Прочитанное.НаблюдениеИтога);
КонецФункцииОткрытьУчебныйПорог85
Общие → Общие команды → ОткрытьУчебныйПорог85 → Модуль команды
Полный отдельный клиентский модуль общей команды запуска именно собственной подготовленной формы отчёта, толстый управляемый desktop-клиент 8.5.1.1343.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ОткрытьФорму("Отчет.УчебныеТовары85.Форма.УчебныйПорог85", , , "owned-report-" + Строка(Новый УникальныйИдентификатор));
КонецПроцедурыРазбор по шагам
Откройте ОткрытьУчебныйПорог85. Проверьте, что собственная группа была пустой до единственного серверного вызова СоздатьЭлементыФормыПользовательскихНастроек с режимом Все и одной колонкой.
Визуально найдите редактор Количество больше. Это будущая ручная проверка штатного UI, не тест количества/имён сгенерированных элементов.
Оставьте 0, завершите ввод и нажмите СформироватьИПроверить. Reader должен подтвердить обе полные записи и отдельно фактический итог 800, либо отказать по контракту.
Введите 1 и выйдите из поля. ПриИзмененииНастроек увеличивает свой счётчик и сбрасывает КонтрольПрошел; старое содержимое результата пока не считается новым проверенным отчётом.
Явно сформируйте снова. Фактический порог снимется перед компоновкой; полный состав теперь только Книга 3/250/750 и отдельный typed общий итог 750.
Введите 3, завершите ввод и сформируйте. Обе собственные записи не проходят строгое условие Количество > 3. Reader требует ноль деталей, но не требует значения итога 0 или определённого вида пустого итога.
Для нулевых деталей наблюдайте НаблюдениеИтога: отсутствие отдельной строки, пустая ячейка при подписи или фактический typed итог. Эти варианты не нормализуются к ожидаемому нулю; отсутствие заголовков всё равно означает отказ контракта.
Верните 0 штатным редактором, завершите ввод и явно сформируйте. Полный фактический состав и итог 800 должны восстановиться только при пригодном фактическом выводе.
Как проверить результат
Порог 0: полный фактический набор Книга и Ручка, общий итог 800. Порог 1: ровно Книга, общий итог 750. Порядок детальных строк не принимается за контракт.
Порог 3: ровно ноль детальных строк; наличие/пустота/значение общего итога записывается как фактическое наблюдение, не как гарантированный 0.
СобытийИзменения наблюдается после ручного ввода, но точное число UI-событий не фиксируется: штатная загрузка настроек тоже может его вызвать.
До явного формирования после изменения КонтрольПрошел=Ложь. После сравнивается ПорогПриКомпоновке именно текущего формирования, не предположение о ещё не завершённом вводе.
Нет доступа по выдуманному имени auto-поля, нет обещания конкретного количества auto-элементов. Их реальное размещение и взаимодействие проверьте вручную.
Пороги вне 0/1/3, неверный тип или неиспользуемый параметр не дают положительного контроля. Не снижайте защиту ради неподтверждённого результата.
Ожидаемый результат
Собственная пользовательская настройка проходит полный штатный маршрут ввод → effective настройки → actual детали и отдельный итог → восстановление исходного порога.
На что обратить внимание
Запуск в 1С не подтверждён. Native API-контракты и статические тесты не доказывают, что стандартный генератор даст наш плоский контракт вывода; это обязательная будущая ручная проверка, а не безусловный успешный результат.
При отсутствии уникальных заголовков, полном повторе заголовков, частичной строке, лишних колонках, нескольких итогах или отсутствии typed values reader отказывает. Не удаляйте диагностику ради зелёного сообщения и не преобразуйте текст числа в ожидаемый результат.
Суммы 750/50/800 в проверке — известный контроль собственного константного набора, но сравниваемая сторона прочитана из фактического документа. Независимый BSL-расчёт 3*250+1*50 не подтверждает сформированный отчёт.
Отказ от СтандартнойОбработки в ПослеКомпоновкиРезультата не отменяет действие, а отключает автоматическое компактное преобразование. Урок оставляет Истина; события и реквизит читаются в разные моменты.
Все уроки ограничены толстым управляемым desktop-клиентом: узкая доступность enum режима не расширяется более широкими контекстами методов.
Никакие записи, файлы, печать или сетевые действия примеры явно не выполняют. Это не означает отсутствия внутренних операций системного хранилища платформы; не переносите опыт на рабочего пользователя.
Пустой набор не гарантирует ни ячейку итога, ни 0, ни даже заголовки. Если собственный контракт заголовков отсутствует, это честный отказ reader, а не успешная сверка нулевой таблицы.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Сформировать собственный отчёт и строго прочитать фактический результат события
Управляемая форма собственного отчёта Основная запускает штатную компоновку. Новые события 8.5.1 разделяют настройки до формирования и фактический ТабличныйДокумент до помещения. Успех условен: собственный плоский контракт/typed values должны быть подтверждены будущим ручным опытом; native не гарантирует эту авторазметку.
Где и как запускать
Полный модуль подготовленной управляемой формы собственного отчёта. Все процедуры на уровне модуля, директивы уже включены. Только толстый управляемый desktop-клиент 8.5.1.1343; runtime не проверен.
Подготовка
Никакие приведённые модули здесь не запускались. Статические проверки не компилируют и не запускают 1С, не подтверждают автоматическую разметку СКД, типизированные значения или отображение.
Создайте новую отдельную пустую учебную информационную базу платформы 8.5.1.1343. Имя конфигурации УчебныеФормыОтчетов85, основной режим запуска УправляемоеПриложение, режим совместимости НеИспользовать. Рабочую конфигурацию не используйте.
Создайте отдельного нового учебного пользователя собственной новой базы. Запустите именно толстый клиент в режиме управляемого приложения. Это обязательный desktop-стенд, не тонкий, web или мобильный клиент: native enum РежимОтображенияРезультатаОтчета доступен только в толстом клиенте.
Оставьте интерфейс собственной новой конфигурации Такси. Не меняйте интерфейс, пользователя или режимы окон рабочего сеанса. Дайте новому учебному пользователю права на собственный отчёт и команды; права текущего рабочего пользователя не меняйте.
В дереве конфигурации Отчёты создайте УчебныеТовары85. Реквизитов прикладных объектов, справочников, документов, регистров и записей базы для него не требуется. Модуль объекта отчёта оставьте пустым: события урока принадлежат ФОРМЕ, не объекту отчёта.
Схема полностью создаётся функцией СоздатьСхему в приложенном серверном общем модуле; файловый макет не нужен. Источник УчебныйИсточник имеет ТипИсточникаДанных Local, набор УчебныеТовары является запросом из собственных двух константных строк. Условие Количество > &МинимальноеКоличество, по умолчанию 0.
Свой параметр порога имеет ОписаниеТипов("Число", КвалификаторыЧисла(1,0,Неотрицательный)): только целые 0..9 по описанию, а правила этого опыта допускают лишь 0, 1, 3. Квалификатор передан явно: native запрещает хранить числа в ОписаниеТипов без него. Это наш узкий учебный тип, не универсальный тип количества.
Собственные четыре выбранных поля: Наименование, Количество, Цена, Сумма. Структура содержит только одну используемую группировку без полей группировки, с АвтоВыбраннымПолем: это детальные записи. Единственный ресурс Сумма вычисляется выражением Сумма(Сумма); в его массив Группировки добавлено документированное значение ОбщийИтог. Вложенных группировок и промежуточных итогов нет. Штатное размещение самого итога не считается заранее подтверждённым.
Полный отдельный модуль УчебныеОтчетыФорм85 вставьте в Общие → Общие модули → УчебныеОтчетыФорм85 → Модуль. Включите Сервер, выключите Клиент, Глобальный и Вызов сервера. Экспортные функции вызываются только из серверных обработчиков собственной формы.
Контракт СОБСТВЕННОГО вывода является условием будущего ручного опыта, не обещанием native авторазметки: одна строка с уникальными подписями Наименование, Количество, Цена, Сумма; далее полные детальные строки; один общий итог для непустого набора; вне найденных четырёх колонок нет данных. Максимум 200 строк и 40 колонок — защитная граница нашего reader, не предел платформы.
Числовые ячейки количества, цены, суммы и непустого общего итога должны иметь СодержитЗначение=Истина и Значение типа Число. Reader не устанавливает эти свойства, не исправляет результат и никогда не преобразует текст 750/50/800 в числа. При нарушении условия он выдаёт диагностику, КонтрольПрошел остаётся Ложь.
Сверка читает actual параметр Результат нового события ПослеКомпоновкиРезультата ДО помещения в реквизит. При опыте с режимами второй источник — actual реквизит формы Результат ПОСЛЕ преобразования. Ни исходный запрос, ни повторное вычисление суммы не подменяют эти источники.
В каждой собственной форме создайте дополнительные реквизиты СостояниеУрока и ОтпечатокДоПомещения типа Строка неограниченной длины, КонтрольПрошел типа Булево, ПорогПриКомпоновке и СобытийДо, СобытийПосле, СобытийИзменения типа Число длиной 6, точность 0, неотрицательный.
Для наблюдения создайте поля ПолеСостояния, ПолеКонтроля, ПолеПорога, ПолеСобытийДо, ПолеСобытийПосле, ПолеСобытийИзменения с путями к одноимённым подготовленным реквизитам СостояниеУрока, КонтрольПрошел, ПорогПриКомпоновке, СобытийДо, СобытийПосле, СобытийИзменения. Всем установите ТолькоПросмотр=Истина. Поле отпечатка необязательно: реквизит смотрите в отладчике.
Назначьте в свойствах событий ФОРМЫ ПриСозданииНаСервере → ПриСозданииНаСервере, ПриКомпоновкеРезультата → ПриКомпоновкеРезультата, ПослеКомпоновкиРезультата → ПослеКомпоновкиРезультата, ПриИзмененииНастроек → ПриИзмененииНастроек. Полные сигнатуры уже в модуле. Не назначайте трёхпараметрическое одноимённое событие модуля объекта отчёта.
АвтоматическоеСохранениеДанныхВНастройках собственной формы оставьте НеИспользовать. Не вызывайте сохранение вариантов, настроек, документа, печать или запись данных. Платформа всё же может читать/сохранять системные настройки отчётной формы: новый пользователь и новая база изолируют опыт, но это НЕ обещание отсутствия внутренних операций.
В Отчёты → УчебныеТовары85 → Формы создайте управляемую форму отчёта УчебнаяКомпоновка85 (тип формы Отчёта, Основная). В конструкторе выберите стандартную форму отчёта, не общую форму. Основной реквизит Отчет должен иметь тип ОтчетОбъект.УчебныеТовары85 и признак Основной.
Проверьте созданные конструктором реквизит Результат типа ТабличныйДокумент и поле табличного документа с ПутьКДанным=Результат; явно назовите это собственное поле ПолеРезультата. Стандартная команда Сформировать должна иметь штатный результат. Если конструктор дал иные имена, исправьте подготовку на указанные, не добавляйте второй результат и не угадывайте имя.
Полный основной блок вставьте целиком в Отчёты → УчебныеТовары85 → Формы → УчебнаяКомпоновка85 → Модуль формы. Замените только исходный пустой/сгенерированный модуль СВОЕЙ новой учебной формы; никакие модули рабочего отчёта не меняйте.
Создайте команды формы СформироватьИПроверить; каждой назначьте одноимённый обработчик из полного модуля и отдельную кнопку. Разместите их вне ПолеРезультата. Стандартные команды сохранения/печати в опыте не используйте.
Полный отдельный модуль запуска ОткрытьУчебнаяКомпоновка85 вставьте в Общие → Общие команды → ОткрытьУчебнаяКомпоновка85 → Модуль команды. Команду без параметра разместите в командном интерфейсе собственного учебного приложения. Каждый запуск передаёт свежий UUID ключа уникальности и не должен случайно переиспользовать предыдущий экземпляр.
Не создавайте редактируемых пользовательских полей настроек в этом базовом опыте. Порог собственной схемы остаётся 0; две другие формы используются отдельно.
Перед опытом в отладчике поставьте точку останова в ПослеКомпоновкиРезультата перед вызовом ПрочитатьПлоскийРезультат. Исследуйте фактический параметр события, а не заранее созданный вручную ТабличныйДокумент.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если ЭтаФорма.ТипФормыОтчета <> ТипФормыОтчета.Основная Тогда
Отказ = Истина;
ВызватьИсключение "Подготовьте именно управляемую форму отчёта Основная";
КонецЕсли;
ОбъектОтчета = ЭтаФорма.РеквизитФормыВЗначение("Отчет");
Схема = УчебныеОтчетыФорм85.СоздатьСхему();
ОбъектОтчета.СхемаКомпоновкиДанных = Схема;
ОбъектОтчета.КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
ОбъектОтчета.КомпоновщикНастроек.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
ЭтаФорма.ЗначениеВРеквизитФормы(ОбъектОтчета, "Отчет");
ЭтаФорма.ПорогПриКомпоновке = 0;
ЭтаФорма.СобытийДо = 0;
ЭтаФорма.СобытийПосле = 0;
ЭтаФорма.СобытийИзменения = 0;
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.ОтпечатокДоПомещения = "";
ЭтаФорма.СостояниеУрока = "Собственная схема готова. Контракт штатного вывода ещё не подтверждён";
КонецПроцедуры
&НаСервере
Процедура ПриКомпоновкеРезультата(СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.ОтпечатокДоПомещения = "";
ОбъектОтчета = ЭтаФорма.РеквизитФормыВЗначение("Отчет");
РабочиеНастройки = ОбъектОтчета.КомпоновщикНастроек.ПолучитьНастройки();
ПараметрНастроек = РабочиеНастройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МинимальноеКоличество"));
Если ПараметрНастроек = Неопределено Тогда
ВызватьИсключение "В фактических настройках нет собственного параметра";
КонецЕсли;
Если Не ПараметрНастроек.Использование Или ТипЗнч(ПараметрНастроек.Значение) <> Тип("Число") Тогда
ВызватьИсключение "Собственный числовой параметр должен использоваться";
КонецЕсли;
Порог = ПараметрНастроек.Значение;
Если Порог <> 0 И Порог <> 1 И Порог <> 3 Тогда
ВызватьИсключение "Завершите ввод одного из учебных порогов 0, 1, 3";
КонецЕсли;
ЭтаФорма.ПорогПриКомпоновке = Порог;
ЭтаФорма.СобытийДо = ЭтаФорма.СобытийДо + 1;
КонецПроцедуры
&НаСервере
Процедура ПослеКомпоновкиРезультата(Результат, СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
ЭтаФорма.СобытийПосле = ЭтаФорма.СобытийПосле + 1;
ЭтаФорма.КонтрольПрошел = Ложь;
Попытка
Прочитанное = УчебныеОтчетыФорм85.ПрочитатьПлоскийРезультат(Результат);
ЭтаФорма.ОтпечатокДоПомещения = УчебныеОтчетыФорм85.ПроверитьСоставИПолучитьОтпечаток(Прочитанное, ЭтаФорма.ПорогПриКомпоновке);
ЭтаФорма.КонтрольПрошел = Истина;
ЭтаФорма.СостояниеУрока = СтрШаблон("Прочитан фактический параметр события: порог %1; детали %2. %3",
ЭтаФорма.ПорогПриКомпоновке, Прочитанное.Детали.Количество(), Прочитанное.НаблюдениеИтога);
Исключение
ЭтаФорма.ОтпечатокДоПомещения = "";
ЭтаФорма.СостояниеУрока = "Контракт фактического вывода не подтверждён: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПриИзмененииНастроек(СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ЭтаФорма.СобытийИзменения = ЭтаФорма.СобытийИзменения + 1;
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.СостояниеУрока = "Настройки изменены. Завершите ввод и явно сформируйте новый результат";
КонецПроцедуры
&НаКлиенте
Процедура СформироватьИПроверить(Команда)
До = ЭтаФорма.СобытийДо;
После = ЭтаФорма.СобытийПосле;
ЭтаФорма.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Непосредственно);
Если ЭтаФорма.СобытийДо <> До + 1 Или ЭтаФорма.СобытийПосле <> После + 1 Тогда
ЭтаФорма.КонтрольПрошел = Ложь;
ЭтаФорма.СостояниеУрока = "Проверьте назначения двух событий именно формы отчёта";
КонецЕсли;
Сообщить(ЭтаФорма.СостояниеУрока);
КонецПроцедурыУчебныеОтчетыФорм85
Общие → Общие модули → УчебныеОтчетыФорм85 → Модуль
Полный отдельный серверный общий модуль УчебныеОтчетыФорм85. Только собственная учебная база и толстый управляемый desktop-клиент 8.5.1.1343; фактический запуск 1С не выполнен.
Функция СоздатьСхему() Экспорт
Схема = Новый СхемаКомпоновкиДанных;
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "УчебныйИсточник";
Источник.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Набор.Имя = "УчебныеТовары";
Набор.ИсточникДанных = Источник.Имя;
Набор.АвтоЗаполнениеДоступныхПолей = Истина;
Набор.Запрос = "ВЫБРАТЬ
| ""Книга"" КАК Наименование,
| 3 КАК Количество,
| 250 КАК Цена,
| 750 КАК Сумма
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""Ручка"", 1, 50, 50";
Настройки = Схема.НастройкиПоУмолчанию;
Для Каждого ИмяПоля Из СтрРазделить("Наименование,Количество,Цена,Сумма", ",") Цикл
Выбранное = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
Выбранное.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
Выбранное.Использование = Истина;
КонецЦикла;
Детали = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Детали.Использование = Истина;
АвтоВыбор = Детали.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
АвтоВыбор.Использование = Истина;
Набор.Запрос = "ВЫБРАТЬ Товары.Наименование, Товары.Количество, Товары.Цена, Товары.Сумма
|ИЗ (
|ВЫБРАТЬ
| ""Книга"" КАК Наименование,
| 3 КАК Количество,
| 250 КАК Цена,
| 750 КАК Сумма
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""Ручка"", 1, 50, 50
|) КАК Товары
|ГДЕ Товары.Количество > &МинимальноеКоличество";
Порог = Схема.Параметры.Добавить();
Порог.Имя = "МинимальноеКоличество";
Порог.Заголовок = "Количество больше";
Порог.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный));
Порог.Значение = 0;
Порог.Использование = ИспользованиеПараметраКомпоновкиДанных.Всегда;
Порог.ЗапрещатьНезаполненныеЗначения = Ложь;
Порог.ДоступенСписокЗначений = Ложь;
Порог.ОграничениеИспользования = Ложь;
Порог.ВключатьВДоступныеПоля = Ложь;
Итог = Схема.ПоляИтога.Добавить();
Итог.ПутьКДанным = "Сумма";
Итог.Выражение = "Сумма(Сумма)";
Итог.Группировки.Добавить("ОбщийИтог");
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("МинимальноеКоличество", 0);
ПараметрНастроек = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МинимальноеКоличество"));
Если ПараметрНастроек = Неопределено Тогда
ВызватьИсключение "Собственная схема не создала параметр порога";
КонецЕсли;
ПараметрНастроек.Использование = Истина;
ПараметрНастроек.ИдентификаторПользовательскойНастройки = "УчебныйПорог";
ПараметрНастроек.ПредставлениеПользовательскойНастройки = "Количество больше";
Возврат Схема;
КонецФункции
Функция ПрочитатьЯчейку(Документ, НомерСтроки, НомерКолонки)
Ячейка = Документ.Область(НомерСтроки, НомерКолонки);
Содержит = Ячейка.СодержитЗначение;
ЗначениеЯчейки = Неопределено;
Если Содержит Тогда
ЗначениеЯчейки = Ячейка.Значение;
КонецЕсли;
Возврат Новый Структура("Текст,Содержит,Значение", СокрЛП(Строка(Ячейка.Текст)), Содержит, ЗначениеЯчейки);
КонецФункции
Функция ЯчейкаПуста(Ячейка)
Возврат Ячейка.Текст = "" И (Не Ячейка.Содержит Или Ячейка.Значение = Неопределено);
КонецФункции
Функция ЧислоЯчейки(Ячейка, ИмяПоля)
Если Не Ячейка.Содержит Тогда
ВызватьИсключение "Нет типизированного значения поля " + ИмяПоля;
КонецЕсли;
Если ТипЗнч(Ячейка.Значение) <> Тип("Число") Тогда
ВызватьИсключение "Тип значения поля " + ИмяПоля + " не Число";
КонецЕсли;
Возврат Ячейка.Значение;
КонецФункции
Функция ПрочитатьПлоскийРезультат(Документ) Экспорт
Если ТипЗнч(Документ) <> Тип("ТабличныйДокумент") Тогда
ВызватьИсключение "Ожидался фактический ТабличныйДокумент";
КонецЕсли;
Высота = Документ.ВысотаТаблицы;
Ширина = Документ.ШиринаТаблицы;
Если Высота = 0 Или Ширина = 0 Или Высота > 200 Или Ширина > 40 Тогда
ВызватьИсключение "Вывод вне ограниченного собственного плоского контракта 200 на 40";
КонецЕсли;
Заголовки = СтрРазделить("Наименование,Количество,Цена,Сумма", ",");
Колонки = Неопределено;
СтрокаЗаголовков = 0;
Для НомерСтроки = 1 По Высота Цикл
Найденные = Новый Структура;
Для НомерКолонки = 1 По Ширина Цикл
Ячейка = ПрочитатьЯчейку(Документ, НомерСтроки, НомерКолонки);
Если Заголовки.Найти(Ячейка.Текст) <> Неопределено Тогда
Если Найденные.Свойство(Ячейка.Текст) Тогда
ВызватьИсключение "Повтор заголовка в одной строке: " + Ячейка.Текст;
КонецЕсли;
Найденные.Вставить(Ячейка.Текст, НомерКолонки);
КонецЕсли;
КонецЦикла;
Если Найденные.Количество() = 4 Тогда
Если Колонки <> Неопределено Тогда
ВызватьИсключение "Несколько полных строк заголовков: вывод неоднозначен";
КонецЕсли;
Колонки = Найденные;
СтрокаЗаголовков = НомерСтроки;
ИначеЕсли Найденные.Количество() <> 0 Тогда
ВызватьИсключение "Неполная строка собственных заголовков";
КонецЕсли;
КонецЦикла;
Если Колонки = Неопределено Тогда
ВызватьИсключение "Четыре собственных заголовка не найдены в одной строке";
КонецЕсли;
Детали = Новый Массив;
ИтогПрочитан = Ложь;
КандидатовИтога = 0;
ЗначениеИтога = Неопределено;
НаблюдениеИтога = "В колонке Сумма отдельная строка итога не обнаружена";
Для НомерСтроки = 1 По Высота Цикл
Для НомерКолонки = 1 По Ширина Цикл
Если НомерКолонки = Колонки.Наименование Или НомерКолонки = Колонки.Количество
Или НомерКолонки = Колонки.Цена Или НомерКолонки = Колонки.Сумма Тогда
Продолжить;
КонецЕсли;
ВнешняяЯчейка = ПрочитатьЯчейку(Документ, НомерСтроки, НомерКолонки);
Если Не ЯчейкаПуста(ВнешняяЯчейка) Тогда
ВызватьИсключение "Есть данные вне четырёх найденных колонок";
КонецЕсли;
КонецЦикла;
Если НомерСтроки = СтрокаЗаголовков Тогда
Продолжить;
КонецЕсли;
Имя = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Наименование);
Количество = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Количество);
Цена = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Цена);
Сумма = ПрочитатьЯчейку(Документ, НомерСтроки, Колонки.Сумма);
Если Не ЯчейкаПуста(Количество) Или Не ЯчейкаПуста(Цена) Тогда
Если Имя.Текст = "" Тогда
ВызватьИсключение "Детальная строка без наименования";
КонецЕсли;
Если НомерСтроки < СтрокаЗаголовков Тогда
ВызватьИсключение "Детальные данные расположены перед заголовками";
КонецЕсли;
Детали.Добавить(Новый Структура("Наименование,Количество,Цена,Сумма", Имя.Текст,
ЧислоЯчейки(Количество, "Количество"), ЧислоЯчейки(Цена, "Цена"), ЧислоЯчейки(Сумма, "Сумма")));
Иначе
Если Имя.Текст <> "" И Имя.Текст <> "Итого" И Имя.Текст <> "Общий итог" И Имя.Текст <> "Всего" Тогда
ВызватьИсключение "Неполная детальная строка или неизвестная подпись: " + Имя.Текст;
КонецЕсли;
Если Не ЯчейкаПуста(Сумма) Или Имя.Текст <> "" Тогда
КандидатовИтога = КандидатовИтога + 1;
Если КандидатовИтога > 1 Тогда
ВызватьИсключение "Несколько итогов без деталей: вывод неоднозначен";
КонецЕсли;
КонецЕсли;
Если Не ЯчейкаПуста(Сумма) Тогда
ЗначениеИтога = ЧислоЯчейки(Сумма, "общий итог Сумма");
ИтогПрочитан = Истина;
НаблюдениеИтога = "Фактический типизированный итог: " + Строка(ЗначениеИтога);
ИначеЕсли Имя.Текст <> "" Тогда
НаблюдениеИтога = "Фактическая подпись " + Имя.Текст + ": ячейка Сумма пуста";
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Новый Структура("Детали,ЕстьИтог,Итог,НаблюдениеИтога", Детали, ИтогПрочитан, ЗначениеИтога, НаблюдениеИтога);
КонецФункции
Функция ПроверитьСоставИПолучитьОтпечаток(Прочитанное, Порог) Экспорт
Если ТипЗнч(Порог) <> Тип("Число") Тогда
ВызватьИсключение "Фактический порог не Число";
КонецЕсли;
Если Порог <> 0 И Порог <> 1 И Порог <> 3 Тогда
ВызватьИсключение "В этом опыте допустимы только пороги 0, 1, 3";
КонецЕсли;
КоличествоОжидается = 0;
Если Порог = 0 Тогда
КоличествоОжидается = 2;
ИначеЕсли Порог = 1 Тогда
КоличествоОжидается = 1;
КонецЕсли;
Если Прочитанное.Детали.Количество() <> КоличествоОжидается Тогда
ВызватьИсключение "Фактическое число детальных строк отличается от собственного набора";
КонецЕсли;
Книга = "";
Ручка = "";
Для Каждого Деталь Из Прочитанное.Детали Цикл
Если Деталь.Наименование = "Книга" Тогда
Если Книга <> "" Или Деталь.Количество <> 3 Или Деталь.Цена <> 250 Или Деталь.Сумма <> 750 Тогда
ВызватьИсключение "Неверная или повторная фактическая строка Книга";
КонецЕсли;
Книга = СтрШаблон("Книга;%1;%2;%3", Деталь.Количество, Деталь.Цена, Деталь.Сумма);
ИначеЕсли Деталь.Наименование = "Ручка" Тогда
Если Ручка <> "" Или Порог <> 0 Или Деталь.Количество <> 1 Или Деталь.Цена <> 50 Или Деталь.Сумма <> 50 Тогда
ВызватьИсключение "Неверная, повторная или лишняя фактическая строка Ручка";
КонецЕсли;
Ручка = СтрШаблон("Ручка;%1;%2;%3", Деталь.Количество, Деталь.Цена, Деталь.Сумма);
Иначе
ВызватьИсключение "Неизвестная фактическая детальная строка";
КонецЕсли;
КонецЦикла;
Если Порог < 3 И Книга = "" Тогда
ВызватьИсключение "В фактическом результате отсутствует Книга";
КонецЕсли;
Если Порог = 0 И Ручка = "" Тогда
ВызватьИсключение "В фактическом результате отсутствует Ручка";
КонецЕсли;
Если Порог < 3 Тогда
Если Не Прочитанное.ЕстьИтог Тогда
ВызватьИсключение "Нет отдельного типизированного общего итога";
КонецЕсли;
Если (Порог = 0 И Прочитанное.Итог <> 800) Или (Порог = 1 И Прочитанное.Итог <> 750) Тогда
ВызватьИсключение "Фактический общий итог отличается от собственного набора";
КонецЕсли;
КонецЕсли;
Возврат СтрШаблон("%1|%2|итог:%3:%4|%5", Книга, Ручка,
Прочитанное.ЕстьИтог, Строка(Прочитанное.Итог), Прочитанное.НаблюдениеИтога);
КонецФункцииОткрытьУчебнаяКомпоновка85
Общие → Общие команды → ОткрытьУчебнаяКомпоновка85 → Модуль команды
Полный отдельный клиентский модуль общей команды запуска именно собственной подготовленной формы отчёта, толстый управляемый desktop-клиент 8.5.1.1343.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ОткрытьФорму("Отчет.УчебныеТовары85.Форма.УчебнаяКомпоновка85", , , "owned-report-" + Строка(Новый УникальныйИдентификатор));
КонецПроцедурыРазбор по шагам
Запустите ОткрытьУчебнаяКомпоновка85 в собственном толстом управляемом клиенте. Проверка версии/имени конфигурации и ТипФормыОтчета выполняется на сервере.
ПриСозданииНаСервере создаёт полный собственный запрос/схему, назначает её реальному ОбъектОтчета.СхемаКомпоновкиДанных, инициализирует существующий readonly КомпоновщикНастроек и возвращает объект в основной реквизит.
Нажмите СформироватьИПроверить. СкомпоноватьРезультат вызывается явно в режиме Непосредственно; наша команда лишь наблюдает, а не заменяет стандартное формирование.
ПриКомпоновкеРезультата читает копию фактически действующих настроек с применением слоёв, проверяет использование числового собственного параметра и сохраняет порог этого формирования.
ПослеКомпоновкиРезультата читает переданный actual документ до помещения. Reader находит четыре колонки по уникальной строке собственных подписей, затем получает numeric Значение только при СодержитЗначение=Истина.
Полный состав детальных записей сверяется независимо от порядка: Книга 3/250/750 и Ручка 1/50/50; единственный фактический общий итог отдельно сравнивается с 800.
Если reader остановился, оставьте КонтрольПрошел=Ложь. В отладчике зафиксируйте фактический тип/текст/СодержитЗначение проблемных ячеек и сообщите диагностику; успех не считается достигнутым.
Повторно нажмите нашу кнопку, затем штатную Сформировать. Оба маршрута должны вызвать назначенные события формы; визуальный вывод и события требуют реального ручного запуска.
Как проверить результат
Будущий положительный результат только при подтверждённом контракте: ПорогПриКомпоновке=0, КонтрольПрошел=Истина, полный фактический состав 2 строк и отдельный typed итог 800.
Одна наша команда увеличивает СобытийДо и СобытийПосле ровно на 1. Ошибка назначения события не даёт положительного контроля.
Строки проверяются целиком: неверная цена, сумма, количество, неизвестный товар, дубликат или лишняя строка вызывают диагностику, даже если отдельный итог равен 800.
В событии источник — параметр Результат; модуль не пишет в его ячейки и не использует реквизит формы вместо ещё не помещённого документа.
Визуально подтвердите две детальные строки и один общий итог. Статические тесты не подтверждают этот экран или typed values штатной СКД.
Ожидаемый результат
Подготовлен условный ручной опыт штатной компоновки с fail-closed проверкой именно фактического документа, без подмены результата независимым расчётом.
На что обратить внимание
Запуск в 1С не подтверждён. Native API-контракты и статические тесты не доказывают, что стандартный генератор даст наш плоский контракт вывода; это обязательная будущая ручная проверка, а не безусловный успешный результат.
При отсутствии уникальных заголовков, полном повторе заголовков, частичной строке, лишних колонках, нескольких итогах или отсутствии typed values reader отказывает. Не удаляйте диагностику ради зелёного сообщения и не преобразуйте текст числа в ожидаемый результат.
Суммы 750/50/800 в проверке — известный контроль собственного константного набора, но сравниваемая сторона прочитана из фактического документа. Независимый BSL-расчёт 3*250+1*50 не подтверждает сформированный отчёт.
Отказ от СтандартнойОбработки в ПослеКомпоновкиРезультата не отменяет действие, а отключает автоматическое компактное преобразование. Урок оставляет Истина; события и реквизит читаются в разные моменты.
Все уроки ограничены толстым управляемым desktop-клиентом: узкая доступность enum режима не расширяется более широкими контекстами методов.
Никакие записи, файлы, печать или сетевые действия примеры явно не выполняют. Это не означает отсутствия внутренних операций системного хранилища платформы; не переносите опыт на рабочего пользователя.
Результат события и реквизит формы не взаимозаменяемы. Старый обработчик объекта отчёта с тремя параметрами не является событием формы 8.5.1.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.