Глобальный контекст.БиблиотекаМакетовОформленияКомпоновкиДанных

Свойства · DataCompositionAppearanceTemplateLib

Тип: БиблиотекаМакетовОформленияКомпоновкиДанных. Библиотека макетов оформления компоновки данных. Доступны следующие предопределенные макеты оформления: Основной(Main), Яркий(Gaudy), Море(Sea), Арктика(Arctic), Зеленый(Green), Античный(Antique).

Полное описание, параметры и ограничения

Глобальный контекст.БиблиотекаМакетовОформленияКомпоновкиДанных (Global context.DataCompositionAppearanceTemplateLib)

Глобальный контекст (Global context)

БиблиотекаМакетовОформленияКомпоновкиДанных (DataCompositionAppearanceTemplateLib)

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

Использование:
Только чтение.
Описание:
Тип: БиблиотекаМакетовОформленияКомпоновкиДанных.
Библиотека макетов оформления компоновки данных. Доступны следующие предопределенные макеты оформления: Основной(Main), Яркий(Gaudy), Море(Sea), Арктика(Arctic), Зеленый(Green), Античный(Antique).
Доступность:

Сервер, толстый клиент, внешнее соединение.

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

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

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

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

Три настоящих конструктора СКД: свои заголовки, выбор полей и оформление отчёта

Собственная обычная форма толстого клиента открывает native конструкторы, принимает реальные результаты и перестраивает отчёт из двух собственных literal строк. Это ограниченный учебный импорт заголовков и выбора полей, не выполнение произвольной изменённой схемы.

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

Модуль собственной обычной формы обработки УчебныеКонструкторыСКД85. Только ТолстыйКлиентОбычноеПриложение 8.5.1.1343; настоящие события формы и кнопок. Без серверных директив, managed/form wrappers и искусственных callback.

Подготовка

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

  2. Создайте обработку УчебныеКонструкторыСКД85 и её Обычную форму Основная. У формы создайте реквизит Состояние85 типа Строка неограниченной длины, разместите его как многострочное поле только для просмотра. Добавьте ТабличноеПоле с именем Таблица85; его данные присваиваются собственной ТаблицаЗначений через .Значение, не managed данные формы.

  3. Добавьте командную панель и семь кнопок. Действия кнопок точно свяжите с процедурами: Сформировать85, ИзменитьЗаголовки85, ПрименитьЗаголовки85, ВыбратьПоля85, СоздатьОформление85, ИзменитьОформление85, ОтброситьКандидаты85. Код целиком вставьте в модуль этой обычной формы. События формы ПриОткрытии и ОбработкаВыбора назначьте одноимённым процедурам; не вызывайте ОбработкаВыбора вручную и не подставляйте искусственный Источник.

  4. Обновите только свою учебную конфигурацию, запустите её именно толстым клиентом в обычном приложении и откройте свою обработку. Здесь нужны модальные окна обычного клиента; код не предназначен для тонкого, web, managed формы или серверного вызова конструктора.

  5. Источник схемы создаётся кодом: Local МойLocal85, один набор МоиДвеСтроки85, поля Наименование/Количество/Цена; Альфа85=1/100 и Бета85=5/250. Нет справочников, документов, запросов к рабочим таблицам, файлов, сети или сохранения результата.

  6. Начальное оформление — отдельная XML копия native БиблиотекаМакетовОформленияКомпоновкиДанных.Основной. Исходный библиотечный макет никогда не редактируется. Все снимки и копии находятся в памяти формы, не являются резервными копиями файлов или базы. Native справка именует область ДетальныеЗаписи (Detail); чтение принимает оба этих документированных имени.

#Если ТолстыйКлиентОбычноеПриложение Тогда

Перем СвояСхема85;
Перем СвоиНастройки85;
Перем СвойСтиль85;
Перем СхемаДоДиалогаXML85;
Перем НастройкиДоДиалогаXML85;
Перем СтильДоДиалогаXML85;
Перем КонструкторСхемы85;
Перем КонструкторСтиля85;
Перем КандидатЗаголовков85;

Процедура ПриОткрытии()
    ПроверитьСвойПустойСтенд();
    СвояСхема85 = СоздатьСвоюСхему85();
    СвоиНастройки85 = СвояСхема85.НастройкиПоУмолчанию;
    Основной = БиблиотекаМакетовОформленияКомпоновкиДанных.Основной;
    Если ТипЗнч(Основной) <> Тип("МакетОформленияКомпоновкиДанных") Тогда
        ВызватьИсключение "Основной должен быть native макетом оформления, а не предполагаемым объектом библиотеки";
    КонецЕсли;
    СвойСтиль85 = ПрочитатьСвойXML85(ЗаписатьСвойXML85(Основной), Тип("МакетОформленияКомпоновкиДанных"));
    КонструкторСхемы85 = Неопределено;
    КонструкторСтиля85 = Неопределено;
    КандидатЗаголовков85 = Неопределено;
    Состояние85 = "Свой отчёт: Альфа85=1, Бета85=5. Сначала Сформировать85, затем редактируйте свои кандидаты.";
КонецПроцедуры

Функция СоздатьСвоюСхему85()
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "МойLocal85";
    Источник.ТипИсточникаДанных = "Local";
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
    Набор.Имя = "МоиДвеСтроки85";
    Набор.ИсточникДанных = Источник.Имя;
    Набор.АвтоЗаполнениеДоступныхПолей = Ложь;
    Набор.Запрос = "ВЫБРАТЬ ""Альфа85"" КАК Наименование, 1 КАК Количество, 100 КАК Цена
|ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""Бета85"", 5, 250";
    Для Каждого ИмяПоля Из СтрРазделить("Наименование,Количество,Цена", ",") Цикл
        Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
        Поле.Поле = ИмяПоля;
        Поле.ПутьКДанным = ИмяПоля;
        Поле.Заголовок = ИмяПоля;
        Если ИмяПоля = "Наименование" Тогда
            Поле.ТипЗначения = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(32));
        Иначе
            Поле.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9, 0));
        КонецЕсли;
        Выбранное = Схема.НастройкиПоУмолчанию.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
        Выбранное.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
        Выбранное.Использование = Истина;
    КонецЦикла;
    Детали = Схема.НастройкиПоУмолчанию.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
    Детали.Использование = Истина;
    АвтоВыбор = Детали.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
    АвтоВыбор.Использование = Истина;
    Возврат Схема;
КонецФункции

Процедура ИзменитьЗаголовки85(Кнопка)
    ПроверитьСвойПустойСтенд();
    ПроверитьНетОткрытогоКонструктора85();
    КандидатЗаголовков85 = Неопределено;
    СхемаДоДиалогаXML85 = ЗаписатьСвойXML85(СвояСхема85);
    Копия = ПрочитатьСвойXML85(СхемаДоДиалогаXML85, Тип("СхемаКомпоновкиДанных"));
    КонструкторСхемы85 = Новый КонструкторСхемыКомпоновкиДанных;
    КонструкторСхемы85.УстановитьСхему(Копия);
    Состояние85 = "В своём наборе измените Заголовок поля Количество на Количество штук. Запрос и пути не меняйте. После закрытия отдельно ПрименитьЗаголовки85.";
    КонструкторСхемы85.Редактировать(ЭтотОбъект);
КонецПроцедуры

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

Функция ПеренестиТолькоСвоиЗаголовки85(Кандидат)
    Если ТипЗнч(Кандидат) <> Тип("СхемаКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужна настоящая схема из native callback";
    КонецЕсли;
    Если Кандидат.ИсточникиДанных.Количество() <> 1 Или Кандидат.НаборыДанных.Количество() <> 1 Тогда
        ВызватьИсключение "Разрешён ровно свой Local и свой единственный набор";
    КонецЕсли;
    Источник = Кандидат.ИсточникиДанных.Получить(0);
    Набор = Кандидат.НаборыДанных.Получить(0);
    СвояЧистая = СоздатьСвоюСхему85();
    СвойНабор = СвояЧистая.НаборыДанных.Получить(0);
    Если Источник.Имя <> "МойLocal85" Или Источник.ТипИсточникаДанных <> "Local"
        Или ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
        ВызватьИсключение "Подмена своего источника или типа набора запрещена";
    КонецЕсли;
    Если Набор.ИсточникДанных <> Источник.Имя Или Набор.Имя <> "МоиДвеСтроки85"
        Или Набор.Запрос <> СвойНабор.Запрос Или Набор.Поля.Количество() <> 3 Тогда
        ВызватьИсключение "Запрос, состав и привязку своего набора менять нельзя";
    КонецЕсли;
    Для Каждого СвоеПоле Из СвойНабор.Поля Цикл
        Поле = Набор.Поля.Найти(СвоеПоле.ПутьКДанным);
        Если Поле = Неопределено Или ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
            ВызватьИсключение "Потеряно одно из своих точных полей";
        КонецЕсли;
        Если Поле.Поле <> СвоеПоле.Поле Или Поле.ПутьКДанным <> СвоеПоле.ПутьКДанным Тогда
            ВызватьИсключение "Имя и путь собственного поля не совпали";
        КонецЕсли;
        Если ТипЗнч(Поле.Заголовок) <> Тип("Строка") Или СтрДлина(Поле.Заголовок) = 0
            Или СтрДлина(Поле.Заголовок) > 80 Тогда
            ВызватьИсключение "Свой заголовок должен быть непустой строкой до 80 символов";
        КонецЕсли;
        СвоеПоле.Заголовок = Поле.Заголовок;
    КонецЦикла;
    Возврат СвояЧистая;
КонецФункции

Процедура ПрименитьЗаголовки85(Кнопка)
    ПроверитьСвойПустойСтенд();
    ПроверитьНетОткрытогоКонструктора85();
    Если КандидатЗаголовков85 = Неопределено Тогда
        ВызватьИсключение "Нет проверенного кандидата заголовков; отмена не создаёт принятую схему";
    КонецЕсли;
    Если ЗаписатьСвойXML85(СвояСхема85) <> СхемаДоДиалогаXML85 Тогда
        ВызватьИсключение "Принятая схема изменилась после открытия конструктора";
    КонецЕсли;
    НовыеНастройки = КандидатЗаголовков85.НастройкиПоУмолчанию;
    Результат = ПостроитьСвойРезультат85(КандидатЗаголовков85, НовыеНастройки, СвойСтиль85);
    СвояСхема85 = КандидатЗаголовков85;
    СвоиНастройки85 = НовыеНастройки;
    КандидатЗаголовков85 = Неопределено;
    ПоказатьСвойРезультат85(Результат);
    Состояние85 = "Приняты только заголовки трёх полей. Все прочие изменения конструктора отброшены; выбор полей вернулся к трём своим полям.";
КонецПроцедуры

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

Функция ПеренестиТолькоСвойВыбор85(Кандидат)
    Если ТипЗнч(Кандидат) <> Тип("НастройкиКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужны native настройки после настоящего OK";
    КонецЕсли;
    Если Кандидат.Структура.Количество() <> 1 Тогда
        ВызватьИсключение "В уроке разрешён только список с одной детальной группой";
    КонецЕсли;
    Детали = Кандидат.Структура.Получить(0);
    Если ТипЗнч(Детали) <> Тип("ГруппировкаКомпоновкиДанных") Тогда
        ВызватьИсключение "Таблица и диаграмма здесь не импортируются";
    КонецЕсли;
    Если Детали.ПоляГруппировки.Элементы.Количество() <> 0 Или Детали.Структура.Количество() <> 0 Тогда
        ВызватьИсключение "Для этого урока оставьте детальные записи без группировок";
    КонецЕсли;
    ЧистаяСхема = ПрочитатьСвойXML85(ЗаписатьСвойXML85(СвояСхема85), Тип("СхемаКомпоновкиДанных"));
    Чистые = ЧистаяСхема.НастройкиПоУмолчанию;
    Чистые.Выбор.Элементы.Очистить();
    Встреченные = Новый Массив;
    Для Каждого Поле Из Кандидат.Выбор.Элементы Цикл
        Если ТипЗнч(Поле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
            ВызватьИсключение "Выберите явные поля, не авто-поле или группу выбора";
        КонецЕсли;
        Если Поле.Использование Тогда
            Путь = Строка(Поле.Поле);
            Если Путь <> "Наименование" И Путь <> "Количество" И Путь <> "Цена" Тогда
                ВызватьИсключение "Разрешены только три поля собственного literal запроса";
            КонецЕсли;
            Если Встреченные.Найти(Путь) <> Неопределено Тогда
                ВызватьИсключение "Одно собственное поле нельзя выбирать дважды";
            КонецЕсли;
            Встреченные.Добавить(Путь);
            Выбранное = Чистые.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
            Выбранное.Поле = Новый ПолеКомпоновкиДанных(Путь);
            Выбранное.Использование = Истина;
        КонецЕсли;
    КонецЦикла;
    Если Встреченные.Найти("Наименование") = Неопределено Или Встреченные.Найти("Количество") = Неопределено Тогда
        ВызватьИсключение "Для readback оставьте Наименование и Количество; Цена — по желанию";
    КонецЕсли;
    Возврат Чистые;
КонецФункции

Процедура СоздатьОформление85(Кнопка)
    ПроверитьСвойПустойСтенд();
    ПроверитьНетОткрытогоКонструктора85();
    СтильДоДиалогаXML85 = ЗаписатьСвойXML85(СвойСтиль85);
    Копия = ПрочитатьСвойXML85(СтильДоДиалогаXML85, Тип("МакетОформленияКомпоновкиДанных"));
    КонструкторСтиля85 = Новый КонструкторМакетаОформленияКомпоновкиДанных();
    КонструкторСтиля85.УстановитьМакет(Копия);
    Состояние85 = "Настройте собственное оформление на основе копии Основной: ДетальныеЗаписи, уровень 0, ЦветФона=RGB(230,245,255), OK. Отмена ничего не применит.";
    КонструкторСтиля85.Редактировать(ЭтотОбъект);
КонецПроцедуры

Процедура ИзменитьОформление85(Кнопка)
    ПроверитьСвойПустойСтенд();
    ПроверитьНетОткрытогоКонструктора85();
    ПолучитьСвойЦветДеталей85(СвойСтиль85);
    СтильДоДиалогаXML85 = ЗаписатьСвойXML85(СвойСтиль85);
    Копия = ПрочитатьСвойXML85(СтильДоДиалогаXML85, Тип("МакетОформленияКомпоновкиДанных"));
    КонструкторСтиля85 = Новый КонструкторМакетаОформленияКомпоновкиДанных(Копия);
    Состояние85 = "Измените свою область ДетальныеЗаписи: уровень 0, ЦветФона=RGB(255,245,220). OK перестроит свой отчёт, Отмена оставит прежний.";
    КонструкторСтиля85.Редактировать(ЭтотОбъект);
КонецПроцедуры

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

Процедура ОтброситьКандидаты85(Кнопка)
    ПроверитьСвойПустойСтенд();
    Если КонструкторСхемы85 <> Неопределено И ЗаписатьСвойXML85(СвояСхема85) <> СхемаДоДиалогаXML85 Тогда
        ВызватьИсключение "Исходная схема должна остаться неизменной";
    КонецЕсли;
    Если КонструкторСтиля85 <> Неопределено И ЗаписатьСвойXML85(СвойСтиль85) <> СтильДоДиалогаXML85 Тогда
        ВызватьИсключение "Исходное оформление должно остаться неизменным";
    КонецЕсли;
    КонструкторСхемы85 = Неопределено;
    КонструкторСтиля85 = Неопределено;
    КандидатЗаголовков85 = Неопределено;
    Состояние85 = "Свои кандидаты отброшены. Старый native callback будет проигнорирован по Источник; принятые схема, настройки, оформление и результат не менялись.";
КонецПроцедуры

Процедура ПроверитьНетОткрытогоКонструктора85()
    Если КонструкторСхемы85 <> Неопределено Или КонструкторСтиля85 <> Неопределено Тогда
        ВызватьИсключение "Сначала закройте свой конструктор; после Отмены нажмите ОтброситьКандидаты85";
    КонецЕсли;
КонецПроцедуры

Процедура Сформировать85(Кнопка)
    ПроверитьСвойПустойСтенд();
    ПроверитьНетОткрытогоКонструктора85();
    Результат = ПостроитьСвойРезультат85(СвояСхема85, СвоиНастройки85, СвойСтиль85);
    ПоказатьСвойРезультат85(Результат);
    Состояние85 = "Реальный двойной вывод: таблица для числового readback и табличный документ со своим оформлением. Две строки, количество 6.";
КонецПроцедуры

Функция ПостроитьСвойРезультат85(Схема, Настройки, Стиль)
    Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКоллекции = Компоновщик.Выполнить(Схема, Настройки, , Стиль, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
    ПроцессорКоллекции = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКоллекции.Инициализировать(МакетКоллекции, , , Ложь);
    Таблица = Новый ТаблицаЗначений;
    ВыводКоллекции = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
    ВыводКоллекции.ОтображатьПроцентВывода = Ложь;
    ВыводКоллекции.УстановитьОбъект(Таблица);
    ВыводКоллекции.Вывести(ПроцессорКоллекции, Ложь);
    Если Таблица.Количество() <> 2 Или Таблица.Колонки.Найти("Наименование") = Неопределено
        Или Таблица.Колонки.Найти("Количество") = Неопределено Тогда
        ВызватьИсключение "Реальная компоновка должна вернуть ровно две свои строки с обязательными полями";
    КонецЕсли;
    Альфа = Таблица.Найти("Альфа85", "Наименование");
    Бета = Таблица.Найти("Бета85", "Наименование");
    Если Альфа = Неопределено Или Бета = Неопределено Тогда
        ВызватьИсключение "Результат не содержит обе собственные строки";
    КонецЕсли;
    Если Альфа.Количество <> 1 Или Бета.Количество <> 5 Или Таблица.Итог("Количество") <> 6 Тогда
        ВызватьИсключение "Числовой readback своих строк не совпал";
    КонецЕсли;
    Если Таблица.Колонки.Найти("Цена") <> Неопределено Тогда
        Если Альфа.Цена <> 100 Или Бета.Цена <> 250 Тогда
            ВызватьИсключение "Цена собственных строк не совпала";
        КонецЕсли;
    КонецЕсли;
    МакетДокумента = Компоновщик.Выполнить(Схема, Настройки, , Стиль);
    ПроцессорДокумента = Новый ПроцессорКомпоновкиДанных;
    ПроцессорДокумента.Инициализировать(МакетДокумента, , , Ложь);
    Документ = Новый ТабличныйДокумент;
    ВыводДокумента = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ВыводДокумента.ОтображатьПроцентВывода = Ложь;
    ВыводДокумента.УстановитьДокумент(Документ);
    ВыводДокумента.Вывести(ПроцессорДокумента, Ложь);
    Если Документ.ВысотаТаблицы = 0 Или Документ.ШиринаТаблицы = 0 Тогда
        ВызватьИсключение "Реальный табличный документ пуст";
    КонецЕсли;
    Возврат Новый Структура("Таблица,Документ", Таблица, Документ);
КонецФункции

Процедура ПоказатьСвойРезультат85(Результат)
    ЭлементыФормы.Таблица85.Значение = Результат.Таблица;
    ЭлементыФормы.Таблица85.СоздатьКолонки();
    Результат.Документ.Показать("Собственный отчёт конструкторов СКД85");
КонецПроцедуры

Функция ЗаписатьСвойXML85(Значение)
    Если ТипЗнч(Значение) <> Тип("СхемаКомпоновкиДанных") И ТипЗнч(Значение) <> Тип("НастройкиКомпоновкиДанных")
        И ТипЗнч(Значение) <> Тип("МакетОформленияКомпоновкиДанных") Тогда
        ВызватьИсключение "В этот собственный XML helper разрешены только три native типа СКД";
    КонецЕсли;
    Запись = Новый ЗаписьXML;
    Запись.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(Запись, Значение, НазначениеТипаXML.Явное);
    Возврат Запись.Закрыть();
КонецФункции

Функция ПрочитатьСвойXML85(Текст, ОжидаемыйТип)
    Чтение = Новый ЧтениеXML;
    Чтение.УстановитьСтроку(Текст);
    Копия = СериализаторXDTO.ПрочитатьXML(Чтение, ОжидаемыйТип);
    Чтение.Закрыть();
    Если ТипЗнч(Копия) <> ОжидаемыйТип Тогда
        ВызватьИсключение "Тип собственной XML копии не совпал";
    КонецЕсли;
    Возврат Копия;
КонецФункции

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

#КонецЕсли

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

  1. Сформировать85 выполняет настоящую компоновку дважды: в ТаблицаЗначений для readback и в ТабличныйДокумент для оформления. Таблица85 покажет свои две строки, отдельное native окно — отчёт. Это не ручное заполнение ожидаемого результата.

  2. ИзменитьЗаголовки85 передаёт независимую XML копию собственной схемы в КонструкторСхемыКомпоновкиДанных. В наборе МоиДвеСтроки85 на вкладке полей измените только Заголовок поля Количество на Количество штук, завершите конструктор. Native ОбработкаВыбора проверяет фактический тип и identity Источник, читает ПолучитьСхему и строит новую чистую собственную схему, импортируя лишь непустые заголовки до 80 символов.

  3. Callback конструктора схемы не считается доказательством OK: native справка обещает вызов при завершении, но отдельно не описывает отмену. Нажмите ПрименитьЗаголовки85 для явного принятия, либо ОтброситьКандидаты85 для отказа. Принятие сбрасывает выбор к трём своим полям. Ни чужой источник, ни изменённый запрос, ни вычисляемые поля кандидата не выполняются.

  4. ВыбратьПоля85 создаёт native источник доступных настроек из принятой собственной схемы, инициализирует КонструкторНастроекКомпоновкиДанных и передаёт XML копию настроек. Второй обязательный параметр УстановитьНастройки получает описание ограничения. Истина означает необходимость усечения: урок прекращает импорт, не открывая конструктор.

  5. Если усечения нет, в ОткрытьМодально выберите отчёт Список, оставьте Наименование и Количество, уберите Цена, не задавайте группировки. Подтвердите OK. Из реальных ПолучитьНастройки импортируется только верхнеуровневый явный выбор этих трёх собственных полей; после проверок чистые настройки реально компонуются. Иные фильтры, параметры, выражения и сортировки намеренно не импортируются. Повторно верните Цена и убедитесь, что она снова появится.

  6. СоздатьОформление85 использует настоящий default ctor и УстановитьМакет с независимой собственной копией. В редакторе выберите область ДетальныеЗаписи, уровень 0, включите ЦветФона и задайте RGB 230,245,255; если области/уровня нет, добавьте их средствами самого конструктора. Нажмите OK. Только родной Источник и native OK callback дают ПолучитьМакет; тип, область, включённый цвет и XML readback проверяются до принятия.

  7. ИзменитьОформление85 использует другой настоящий ctor На основании макета оформления: в него передаётся копия уже принятого собственного макета. Измените тот же фон на RGB 255,245,220 и подтвердите OK. Новый макет передаётся четвёртым аргументом КомпоновщикМакетаКомпоновкиДанных.Выполнить; именно tabular вывод предназначен для визуального оформления.

  8. После Отмены схемы или оформления закройте конструктор и нажмите ОтброситьКандидаты85. Это только забывает свои pending references и проверяет неизменность принятого объекта; оно не закрывает native окно насильно. Поздний callback старого конструктора игнорируется по identity Источник. Для настроек native modal Ложь обрабатывается немедленно как нормальная отмена.

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

  1. Начальная и каждая принятая компоновка должны дать именно Альфа85 с Количество=1 и Бета85 с Количество=5, итог количества 6. Если Цена выбрана, обязаны вернуться 100 и 250. Нарушение вызывает исключение до принятия кандидата.

  2. После принятия схемы в native табличном документе проверьте заголовок Количество штук; после OK выбора полей сравните число колонок 3→2→3. Числа и обе собственные строки должны остаться неизменны.

  3. После двух OK оформлений визуально сравните фон детальных строк: голубой, затем кремовый. XML readback подтверждает цвет native объекта; точный вид, тему и применение макета к выводу проверяет пользователь в учебном клиенте, эти static тесты не являются UI доказательством.

  4. Нажмите Отмена в настройках: ни XML принятых настроек, ни таблица, ни документ не должны поменяться. Отмените оформление: native OK callback не ожидается; после ручного ОтброситьКандидаты85 принятый XML оформления и прежний результат должны сохраниться.

  5. В конструкторе схемы попробуйте изменить literal запрос или имя Local: после завершения импорт должен быть отклонён ещё до компоновки, рабочая схема остаётся прежней. Не подставляйте реальную таблицу даже в учебный негативный тест: достаточно изменить literal число 1 на 2.

  6. В настройках выберите диаграмму, группировку или уберите Количество: импорт отклоняется до принятия. Закройте диалог, снова откройте его из принятого состояния и восстановите свой простой Список. При ошибке цвета оформление остаётся предыдущим: заново СоздатьОформление85 и задайте настоящую область, уровень и включённый ЦветФона.

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

Реальный учебный цикл native конструкторов с isolated кандидатами, явным принятием схемы, честной отменой, проверкой возвращённых объектов, числовым readback и табличным выводом своего оформления.

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

  1. Это ограниченный импорт: из конструктора схемы берутся только заголовки собственных полей; из конструктора настроек — только явный выбор полей. Остальные изменения намеренно не принимаются, поэтому пример нельзя выдавать за универсальный дизайнер любых отчётов.

  2. Для КонструкторНастроекКомпоновкиДанных.УстановитьНастройки Булево Истина означает необходимость усечения, а не успех. Для ОткрытьМодально Истина уже означает OK. Эти два результата имеют разный смысл.

  3. Schema constructor в exporter именуется По умолчанию, а native страница называется На основании схемы. Используем документированное отсутствие необязательного аргумента, затем реальный УстановитьСхему. Для оформления оба разных ctor используются в настоящих фазах первоначальной настройки и правки принятого макета.

  4. Схема/настройки/макет оформления документированно сериализуются в XML. XML строки создаются только этим модулем из своих объектов; helper не является загрузчиком недоверенного произвольного XML.

  5. Показать открывает только собственный табличный документ без имени файла. Не сохраняйте его вручную в рабочие каталоги и не печатайте на настоящий принтер. Выполнение приведённого кода в 1С и визуальная проверка не выполнялись агентом.

  6. После отмены немодального конструктора может остаться собственная pending ссылка, потому что нет документированного cancel callback. Ручная команда отказа не имитирует закрытие окна. Закройте сам native конструктор, затем отбросьте кандидата.

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

Область оформления: свои элементы, порядок и цвет настоящих строк отчёта

Берем полный Основной макет и создаем собственную независимую копию через XML-строку. В ее реальной области ДетальныеЗаписи проверяем очистку, добавление, вставку, индексы, получение, сдвиг и удаление. В итоговой области оставляем один элемент уровня0; настоящий отчет должен сохранить числа и получить фон14/178/222 в шести ячейках, затем вернуть исходные цвета.

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

Полный серверный общий модуль нового собственного стенда УчебныеЭлементыОформления85; отдельный модуль формы запуска ниже.

Подготовка

  1. Создать НОВУЮ отдельную пустую учебную базу ровно8.5.1.1343: конфигурация УчебныеЭлементыОформления85, совместимость Не использовать. Без бизнес-объектов, заданий, подписок и расширений; не рабочую базу и не ее копию.

  2. Конфигуратор → Общие → Общие модули → УчебныеЭлементыОформления85: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставить полный основной код урока и все его функции.

  3. Конфигуратор → Обработки → УчебныеЭлементыОформления85 → Формы → Пульт: управляемая форма, команда Выполнить, действие Выполнить и кнопка с этой командой. Отдельный полный модуль запуска приведен ниже; реквизиты не нужны.

  4. Сохранить и обновить свою базу данных (F7), открыть обработку в новом своем клиенте. Здесь F7 и1С не выполнялись: это будущая ручная проверка.

  5. Собственный Local-запрос содержит только Книга3/250/750 и Ручка1/50/50; выбранные поля Наименование, Количество, Цена, Сумма и одна группа деталей. Нет ресурсов, итоговых строк, собственного условного оформления или иных таблиц.

  6. Макет Основной только читается. Каждая изменяемая копия создается из полного XML в памяти; библиотечный объект, общие макеты и пользовательские настройки не изменяются.

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

  8. runtimeVerifiedScenarios=0. Числовые/цветовые проверки подготовлены в коде, но в1С здесь не выполнялись. Нет файлов, архивов, резервных копий, сети, печати или изменения production.

Функция ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    Схема = Новый СхемаКомпоновкиДанных;
    ЗаполнитьСвоиДанные(Схема);
    ЗаполнитьСвоиНачальныеНастройки(Схема.НастройкиПоУмолчанию);
    ТекстСхемы = СвойОбъектРасшифровкиВСтроку(Схема);
    ИсходныйМакет = БиблиотекаМакетовОформленияКомпоновкиДанных.Основной;
    ТекстИсходного = СвойОбъектРасшифровкиВСтроку(ИсходныйМакет);
    СвойМакет = СвойОбъектРасшифровкиИзСтроки(ТекстИсходного, Тип("МакетОформленияКомпоновкиДанных"));
    ТекстСвоегоДо = СвойОбъектРасшифровкиВСтроку(СвойМакет);
    ДокументДо = ПолучитьСвойОтчетСОформлением(Схема, СвойМакет);
    ФоныДо = ПолучитьСвоиФоныЧисел(ДокументДо, Ложь);
    Область = ПолучитьСвоюОбластьДеталей(СвойМакет);
    Область.Очистить();
    Если Область.Количество() <> 0 Тогда
        ВызватьИсключение "Очистилась только область деталей собственной копии, не вся библиотека";
    КонецЕсли;
    Основной = Область.Добавить();
    НастроитьСвойЭлементОбласти(Основной, Новый Цвет(14, 178, 222));
    Временный = Область.Вставить(0);
    НастроитьСвойЭлементОбласти(Временный, Новый Цвет(88, 98, 108));
    Если Область.Количество() <> 2 Или Область.Индекс(Временный) <> 0
        Или Область.Индекс(Основной) <> 1 Или Область.Получить(0) <> Временный Тогда
        ВызватьИсключение "В своей области должны быть два настоящих элемента в проверенном порядке";
    КонецЕсли;
    Область.Сдвинуть(Основной, -1);
    Если Область.Индекс(Основной) <> 0 Или Область.Индекс(Временный) <> 1
        Или Область.Получить(0) <> Основной Или Область.Получить(1) <> Временный Тогда
        ВызватьИсключение "Сдвиг на минус1 должен поменять реальные позиции элементов";
    КонецЕсли;
    Область.Удалить(Временный);
    Если Область.Количество() <> 1 Или Область.Индекс(Основной) <> 0
        Или Область.Получить(0) <> Основной Или Основной.Уровень <> 0 Тогда
        ВызватьИсключение "Перед компоновкой в области деталей оставляем только один свой элемент уровня0";
    КонецЕсли;
    ДокументПослеИзменения = ПолучитьСвойОтчетСОформлением(Схема, СвойМакет);
    ФоныПослеИзменения = ПолучитьСвоиФоныЧисел(ДокументПослеИзменения, Истина);
    Если ФоныПослеИзменения.Количество() <> 6 Тогда
        ВызватьИсключение "Подсветка должна подтвердиться в шести настоящих числовых ячейках двух товаров";
    КонецЕсли;
    ВосстановленныйМакет = СвойОбъектРасшифровкиИзСтроки(ТекстСвоегоДо, Тип("МакетОформленияКомпоновкиДанных"));
    Если СвойОбъектРасшифровкиВСтроку(ВосстановленныйМакет) <> ТекстСвоегоДо Тогда
        ВызватьИсключение "Восстанавливается весь свой макет со всеми областями, не один параметр цвета";
    КонецЕсли;
    ДокументВосстановления = ПолучитьСвойОтчетСОформлением(Схема, ВосстановленныйМакет);
    ФоныВосстановления = ПолучитьСвоиФоныЧисел(ДокументВосстановления, Ложь);
    Для Каждого ЗаписьФона Из ФоныДо Цикл
        Если ФоныВосстановления.Получить(ЗаписьФона.Ключ) <> ЗаписьФона.Значение Тогда
            ВызватьИсключение "Восстановление полного макета должно вернуть исходный реальный RGB каждой числовой ячейки";
        КонецЕсли;
    КонецЦикла;
    Если СвойОбъектРасшифровкиВСтроку(ИсходныйМакет) <> ТекстИсходного
        Или СвойОбъектРасшифровкиВСтроку(Схема) <> ТекстСхемы Тогда
        ВызватьИсключение "Своя правка не должна менять исходный библиотечный макет или схему";
    КонецЕсли;
    Возврат "Свой макет: вставка→сдвиг→удаление; шесть RGB14/178/222; исходные цвета восстановлены; количество4 и сумма800 во всех трех отчетах";
КонецФункции

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

Процедура ЗаполнитьСвоиДанные(Схема)
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "УчебныйИсточник";
    Источник.ТипИсточникаДанных = "Local";
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
    Набор.Имя = "УчебныеТовары";
    Набор.ИсточникДанных = Источник.Имя;
    Набор.АвтоЗаполнениеДоступныхПолей = Истина;
    Набор.Запрос = "ВЫБРАТЬ
    |    ""Книга"" КАК Наименование,
    |    3 КАК Количество,
    |    250 КАК Цена,
    |    750 КАК Сумма
    |ОБЪЕДИНИТЬ ВСЕ
    |ВЫБРАТЬ ""Ручка"", 1, 50, 50";
КонецПроцедуры

Процедура ЗаполнитьСвоиНачальныеНастройки(Настройки)
    Для Каждого ИмяПоля Из СтрРазделить("Наименование,Количество,Цена,Сумма", ",") Цикл
        Выбранное = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
        Выбранное.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
        Выбранное.Использование = Истина;
    КонецЦикла;
    Детали = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
    Детали.Использование = Истина;
    АвтоВыбор = Детали.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
    АвтоВыбор.Использование = Истина;
КонецПроцедуры

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

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

Функция ПолучитьСвойОтчетСОформлением(Схема, Оформление)
    Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
    Макет = Компоновщик.Выполнить(Схема, Схема.НастройкиПоУмолчанию, , Оформление, Тип("ГенераторМакетаКомпоновкиДанных"));
    Возврат ПолучитьСвойПроверенныйДокумент(Макет, "");
КонецФункции

Функция ПолучитьСвоиФоныЧисел(Документ, ПроверятьНовыйЦвет)
    Колонки = Новый Соответствие;
    Для НомерСтроки = 1 По Документ.ВысотаТаблицы Цикл
        Для НомерКолонки = 1 По Документ.ШиринаТаблицы Цикл
            Текст = СокрЛП(Документ.Область(НомерСтроки, НомерКолонки).Текст);
            Если Текст = "Наименование" Или Текст = "Количество" Или Текст = "Цена" Или Текст = "Сумма" Тогда
                Колонки.Вставить(Текст, НомерКолонки);
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    Если Колонки.Количество() <> 4 Тогда
        ВызватьИсключение "Цвет проверяется только по фактически найденным четырем колонкам своей таблицы";
    КонецЕсли;
    Фоны = Новый Соответствие;
    Для НомерСтроки = 1 По Документ.ВысотаТаблицы Цикл
        Товар = СокрЛП(Документ.Область(НомерСтроки, Колонки.Получить("Наименование")).Текст);
        Если Товар = "Книга" Или Товар = "Ручка" Тогда
            Для Каждого ИмяПоля Из СтрРазделить("Количество,Цена,Сумма", ",") Цикл
                Ячейка = Документ.Область(НомерСтроки, Колонки.Получить(ИмяПоля));
                Если ПрочитатьСвоеЧисло(Ячейка) = Неопределено Тогда
                    ВызватьИсключение "Цвет без настоящего числа не считается результатом опыта";
                КонецЕсли;
                Фон = Ячейка.ЦветФона.ПолучитьАбсолютный();
                Если ПроверятьНовыйЦвет И (Фон.Красный <> 14 Или Фон.Зеленый <> 178 Или Фон.Синий <> 222) Тогда
                    ВызватьИсключение "Реальный фон каждой числовой ячейки должен быть14/178/222";
                КонецЕсли;
                Ключ = Товар + ":" + ИмяПоля;
                Если Фоны.Получить(Ключ) <> Неопределено Тогда
                    ВызватьИсключение "Числовая ячейка собственного товара должна учитываться один раз";
                КонецЕсли;
                Фоны.Вставить(Ключ, Строка(Фон.Красный) + "/" + Строка(Фон.Зеленый) + "/" + Строка(Фон.Синий));
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
    Если Фоны.Количество() <> 6 Тогда
        ВызватьИсключение "Нужно проверить шесть реальных ячеек количества, цены и суммы Книги и Ручки";
    КонецЕсли;
    Возврат Фоны;
КонецФункции

Функция ПолучитьСвойПроверенныйДокумент(Макет, Заголовок)
    Копия = СвойОбъектРасшифровкиИзСтроки(СвойОбъектРасшифровкиВСтроку(Макет), Тип("МакетКомпоновкиДанных"));
    Документ = СформироватьСвойДокумент(Копия);
    Если Документ.ВысотаТаблицы = 0 Или Документ.ВысотаТаблицы > 200
        Или Документ.ШиринаТаблицы = 0 Или Документ.ШиринаТаблицы > 100 Тогда
        ВызватьИсключение "Ожидается только собственный небольшой табличный отчет";
    КонецЕсли;
    Колонки = Новый Соответствие;
    СтрокаЗаголовков = 0;
    ЗаголовокНайден = Заголовок = "";
    Для НомерСтроки = 1 По Документ.ВысотаТаблицы Цикл
        Кандидат = Новый Соответствие;
        Для НомерКолонки = 1 По Документ.ШиринаТаблицы Цикл
            Текст = СокрЛП(Документ.Область(НомерСтроки, НомерКолонки).Текст);
            Если Заголовок <> "" И Текст = Заголовок Тогда
                ЗаголовокНайден = Истина;
            КонецЕсли;
            Если Текст = "Наименование" Или Текст = "Количество" Или Текст = "Цена" Или Текст = "Сумма" Тогда
                Если Кандидат.Получить(Текст) <> Неопределено Тогда
                    ВызватьИсключение "В собственной строке заголовков не должно быть дублей поля";
                КонецЕсли;
                Кандидат.Вставить(Текст, НомерКолонки);
            КонецЕсли;
        КонецЦикла;
        Если Кандидат.Количество() = 4 Тогда
            Если СтрокаЗаголовков <> 0 Тогда
                ВызватьИсключение "В этом собственном опыте только одна четырехпольная таблица";
            КонецЕсли;
            СтрокаЗаголовков = НомерСтроки;
            Колонки = Кандидат;
        КонецЕсли;
    КонецЦикла;
    Если СтрокаЗаголовков = 0 Или Не ЗаголовокНайден Тогда
        ВызватьИсключение "Не найдены настоящий заголовок и все четыре заголовка полей";
    КонецЕсли;
    Книга = Ложь;
    Ручка = Ложь;
    ИтогКоличество = 0;
    ИтогСумма = 0;
    Для НомерСтроки = СтрокаЗаголовков + 1 По Документ.ВысотаТаблицы Цикл
        Наименование = СокрЛП(Документ.Область(НомерСтроки, Колонки.Получить("Наименование")).Текст);
        Количество = ПрочитатьСвоеЧисло(Документ.Область(НомерСтроки, Колонки.Получить("Количество")));
        Цена = ПрочитатьСвоеЧисло(Документ.Область(НомерСтроки, Колонки.Получить("Цена")));
        Сумма = ПрочитатьСвоеЧисло(Документ.Область(НомерСтроки, Колонки.Получить("Сумма")));
        Если Наименование <> "Книга" И Наименование <> "Ручка"
            И (Количество <> Неопределено Или Цена <> Неопределено Или Сумма <> Неопределено) Тогда
            ВызватьИсключение "В собственном отчете без итоговых строк не должно быть посторонних числовых строк";
        КонецЕсли;
        Если Наименование = "Книга" Или Наименование = "Ручка" Тогда
            Если Количество = Неопределено Или Цена = Неопределено Или Сумма = Неопределено Тогда
                ВызватьИсключение "В реальной строке товара должны находиться три настоящих числа";
            КонецЕсли;
            Если Наименование = "Книга" Тогда
                Если Книга Или Количество <> 3 Или Цена <> 250 Или Сумма <> 750 Тогда
                    ВызватьИсключение "Книга должна выводиться ровно один раз: 3, 250, 750";
                КонецЕсли;
                Книга = Истина;
            Иначе
                Если Ручка Или Количество <> 1 Или Цена <> 50 Или Сумма <> 50 Тогда
                    ВызватьИсключение "Ручка должна выводиться ровно один раз: 1, 50, 50";
                КонецЕсли;
                Ручка = Истина;
            КонецЕсли;
            ИтогКоличество = ИтогКоличество + Количество;
            ИтогСумма = ИтогСумма + Сумма;
        КонецЕсли;
    КонецЦикла;
    Если Не Книга Или Не Ручка Или ИтогКоличество <> 4 Или ИтогСумма <> 800 Тогда
        ВызватьИсключение "Настоящие строки должны сохранить количество4 и сумму800";
    КонецЕсли;
    Возврат Документ;
КонецФункции

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


Функция ПрочитатьСвоеЧисло(Ячейка)
    Если Ячейка.СодержитЗначение Тогда
        Значение = Ячейка.Значение;
        Если ТипЗнч(Значение) = Тип("Число") Тогда
            Возврат Значение;
        КонецЕсли;
        Возврат Неопределено;
    КонецЕсли;
    Текст = СтрЗаменить(СтрЗаменить(СокрЛП(Ячейка.Текст), Символ(160), ""), " ", "");
    Если Текст = "" Тогда
        Возврат Неопределено;
    КонецЕсли;
    ЕстьЦифра = Ложь;
    Для Позиция = 1 По СтрДлина(Текст) Цикл
        Знак = Сред(Текст, Позиция, 1);
        Если СтрНайти("0123456789", Знак) > 0 Тогда
            ЕстьЦифра = Истина;
        ИначеЕсли СтрНайти(",.-", Знак) = 0 Тогда
            Возврат Неопределено;
        КонецЕсли;
    КонецЦикла;
    Если Не ЕстьЦифра Тогда
        Возврат Неопределено;
    КонецЕсли;
    Возврат Число(Текст);
КонецФункции

Функция СвойОбъектРасшифровкиВСтроку(Объект)
    Запись = Новый ЗаписьXML;
    Запись.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(Запись, Объект);
    Возврат Запись.Закрыть();
КонецФункции

Функция СвойОбъектРасшифровкиИзСтроки(СтрокаXML, ТребуемыйТип)
    Чтение = Новый ЧтениеXML;
    Чтение.УстановитьСтроку(СтрокаXML);
    Попытка
        Объект = СериализаторXDTO.ПрочитатьXML(Чтение, ТребуемыйТип);
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Чтение.Закрыть();
    Если ТипЗнч(Объект) <> ТребуемыйТип Тогда
        ВызватьИсключение "Нужен полный собственный типизированный объект, не кусок ссылок";
    КонецЕсли;
    Возврат Объект;
КонецФункции
УчебныеЭлементыОформления85.Пульт

УчебныеЭлементыОформления85 → Обработки → УчебныеЭлементыОформления85 → Формы → Пульт → Модуль

Полный модуль собственной управляемой формы; здесь не выполнялся.

&НаКлиенте
Процедура Выполнить(Команда)
    Сообщить(ВыполнитьНаСервере());
КонецПроцедуры

&НаСервереБезКонтекста
Функция ВыполнитьНаСервере()
    Возврат УчебныеЭлементыОформления85.ВыполнитьПример();
КонецФункции

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

  1. Сформировать первый настоящий документ из собственной копии полного макета. Проверить четыре заголовка, две реальные строки и все шесть чисел; запомнить фактические RGB числовых ячеек по ключам Товар:ИмяПоля.

  2. МакетОформленияКомпоновкиДанных является коллекцией значений параметров: найти предопределенный параметр ДетальныеЗаписи, затем проверить тип его Значение. Это реальная ОбластьМакетаОформленияКомпоновкиДанных, не весь макет и не ЭлементОбласти.

  3. Очистить только эту область собственной копии. Добавить основной элемент с цветом14/178/222; вставить временный серый элемент на позицию0. Проверить количество2, реальные индексы0/1 и объект через Получить(0).

  4. Сдвинуть основной элемент на-1 и проверить оба новых индекса и оба результата Получить. Удалить именно временный объект. Промежуточные две записи не передаются компоновщику: перед формированием должен остаться один основной элемент уровня0.

  5. Уровень0 для ДетальныеЗаписи обязателен по установленной справке. Оформление readonly: не заменять объект, а проверить доступность ЦветФона и установить значение внутри него. Флаг использования и само значение дополнительно читать из реальной модели.

  6. Передать полный измененный макет четвертым аргументом Выполнить стандартному генератору табличного документа. Снова проверить обе строки3/250/750 и1/50/50, количество4, сумму800; затем читать реальные ЦветФона всех шести числовых ячеек.

  7. Восстановить весь собственный макет из исходного XML, а не сбросить одно свойство цвета. Третий новый отчет должен сохранить все числа и вернуть первоначальные RGB для каждого из шести ключей.

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

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

  1. Будущий запуск: операции коллекции меняют реальные позиции, после удаления остаются один элемент и уровень0. У измененного отчета именно шесть числовых ячеек имеют RGB14/178/222.

  2. Каждый из трех документов проверяется заново по настоящим данным: Книга3/250/750, Ручка1/50/50, количество4, сумма800. Проверяющий код не записывает ожидаемые числа или цвета в документ.

  3. После полного восстановления RGB каждого ключа должен совпасть с фактически прочитанным первым документом. Исходный цвет не зашит как белый и не считается известным заранее.

  4. Отрицательный опыт в своем коде: изменить основной цвет на15/178/222 при прежней проверке14/178/222. Проверка реальных ячеек должна отказать; совпадение значений только в модели макета не достаточно.

  5. Отдельный отрицательный опыт: изменить количество Книги на30 при прежних ожидаемых числах. Числовая проверка должна отказать независимо от цвета. runtimeVerifiedScenarios=0: это будущие условия приемки, не выполненный здесь тест1С.

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

Полный урок проверяет операции собственной области, три настоящих результата, шесть реальных RGB и восстановление всего макета. Здесь в1С не выполнялся.

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

  1. У ОбластьМакетаОформленияКомпоновкиДанных нет самостоятельного конструктора. Она получается как Значение настоящего параметра области полного макета; Добавить возвращает ее элемент, а не еще одну область.

  2. Очистить применяется только к области независимой копии. Не очищать библиотеку, чужой макет или весь макет вместо одной области. Копирование выполняется в памяти, новых резервных файлов нет.

  3. Для ДетальныеЗаписи всегда нужен уровень0. Этот опыт не создает положительные уровни и не проверяет иерархические группировки. Два временных элемента существуют только до компоновки; финальная область содержит один.

  4. Оформление элемента readonly, но его разрешенные параметры редактируются. Сначала проверить действительную доступность ЦветФона; не создавать параметр с произвольным именем.

  5. Цвет модели и цвет результата — разные проверки. Перед чтением RGB вызывается ПолучитьАбсолютный: у не абсолютного Цвет компоненты возвращают-1 и не различают реальные стили. Метод доступен с8.3.23 и разрешен на сервере8.5.1.1343. Это не доказательство экранного рендеринга, работы принтера или сохранения другим пользователям.

  6. Поиск координат и числовая проверка рассчитаны на собственную двухстрочную таблицу без ресурсов, итогов и объединенных числовых ячеек. Для другого отчета нужен другой контроль, а не отключение ошибок.

  7. Код работает на сервере, а клиент получает только текст итога. Не добавлять в этот модуль методы интерактивного конструктора макета оформления: они относятся к другому контексту и отдельному уроку.

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

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

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

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

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