Описание области макета для определенного уровня иерархии.
Полное описание, параметры и ограничения
ЭлементОбластиМакетаОформленияКомпоновкиДанных (DataCompositionAppearanceTemplateAreaItem)
ЭлементОбластиМакетаОформленияКомпоновкиДанных (DataCompositionAppearanceTemplateAreaItem)
Доступен, начиная с версии 8.1.
Свойства:
Оформление (Appearance)
Уровень (Level)
Описание:
Описание области макета для определенного уровня иерархии.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Данный объект может быть сериализован в/из XML. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен {http://v8.1c.ru/8.1/data-composition-system/appearance-template}. Имя типа XDTO: AppearanceTemplateAreaItem.
См. также:
ОбластьМакетаОформленияКомпоновкиДанных, метод Добавить
ОбластьМакетаОформленияКомпоновкиДанных, метод Вставить
ОбластьМакетаОформленияКомпоновкиДанных, метод Получить
ОбластьМакетаОформленияКомпоновкиДанных, метод Сдвинуть
ОбластьМакетаОформленияКомпоновкиДанных, метод Удалить
ОбластьМакетаОформленияКомпоновкиДанных, метод Индекс
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Счёт: собственный элемент области, реальные цвета и восстановление
Полный учебный процесс на своей новой базе: исходные данные счёта, compiled макеты, настоящие native фабрики и отдельные проверки модели, документа и профиля. Все необходимые модули и видимая спецификация приведены целиком.
Где и как запускать
Серверный неглобальный общий модуль собственной новой FileCF 8.5.1.1343; native объекты локальны, на клиент передаётся только строка результата.
Подготовка
Создайте НОВУЮ пустую файловую базу, не рабочую базу и не её копию: C:\1CStudy\OwnReportAppearance85_6d4f472b-b7d2-4266-a960-ad45450fe2cf\IB. Имя конфигурации УчебныеПрофилиОформления85, платформа строго 8.5.1.1343, совместимость Не использовать, основной режим Управляемое приложение, интерфейс Такси. Код требует точную native строку File="...\IB"; и остановится при другом формате регистрации. Marker пути не является UUID базы или пользователя.
Состав конфигурации: три общих модуля, два общих макета и одна обработка с одной управляемой формой Пульт. Не создавайте прикладные данные, справочники, документы, регистры, планы, бизнес-процессы, задания, подписки, общие формы или расширения. Роль и пользователь нужны только для своего стенда.
Конфигуратор → Общие → Общие модули: ПрофилиСчетаСлужебный85, ПрофилиСчетаМакет85 и ПрофилиСчетаНастройки85. У всех Сервер=Да, Глобальный=Нет, Привилегированный=Нет, Клиент (управляемое приложение)=Нет, Клиент (обычное приложение)=Нет, Внешнее соединение=Нет, Повторное использование возвращаемых значений=Не использовать. Вызов сервера=Нет только у Служебный; у двух остальных Да. Повторные проверки не должны читаться из кэша.
Основной код первого урока целиком вставьте в ПрофилиСчетаМакет85. Основной код второго урока целиком вставьте в ПрофилиСчетаНастройки85. Полную общую часть вставьте в ПрофилиСчетаСлужебный85; модуль формы вставьте в Пульт. Все необходимые части показаны в supporting modules каждой карточки: другой основной модуль, служебный модуль, форма и JSON-спецификация макетов.
Конфигуратор → Общие → Общие макеты: создайте СвойСпокойный85 и СвойКонтраст85, выберите в конструкторе именно тип Макет оформления компоновки данных. Не Табличный документ. Выберите область ДетальныеЗаписи и включите параметры ЦветФона, ЦветТекста, Формат по видимой JSON-спецификации. Не добавляйте уровни для деталей; нужен уровень 0. RGB вводится в свойствах цвета, Формат — ЧДЦ=0;ЧГ=0. Это ручная спецификация, не файл автоматического импорта.
Обработки → УчебныеПрофилиОформления85 → Формы → Пульт: управляемая форма. Реквизиты Согласие85, Остановка85, ПрофилиВыполнены85 — Булево, начальные значения Ложь; Результат85 — Строка неограниченной длины. Добавьте поле-флажок Согласие85 и поле результата только для просмотра. Две команды ПроверитьМакет85 и Профили85, действия одноимённых процедур; две кнопки с этими командами. Остановка85 и ПрофилиВыполнены85 не выводите как редактируемые поля.
Общие → Роли: создайте одну собственную роль Профили85ПолныеПрава с правами Администрирование данных, Администрирование, Активные пользователи, запуска выбранного клиента, режима технического специалиста и доступом к обработке. Администрирование → Пользователи: создайте одного собственного пользователя Профили85Ученик и назначьте ему эту роль. Код проверяет наличие и полное имя роли, её назначение текущему пользователю, настоящий UUID текущего/единственного пользователя и пользователя единственного соединения. РольДоступна подтверждает только назначение роли, не содержание её прав. Сам native SetCommon проверяет требуемое Администрирование данных. UUID-шаблон редактировать не нужно.
Сохраните и обновите свою базу F7 вручную, затем закройте Конфигуратор и другие сеансы. Откройте один свой управляемый клиент под Профили85Ученик и форму обработки через Все функции. Если native список соединений содержит второй сеанс, опыт остановится до установки профиля.
В новой базе не задавайте пользовательский и общий профили заранее. Перед первым setter оба native getter должны вернуть пустые строки. Не очищайте чужие или неизвестные настройки ради прохождения урока: если исходное имя непустое, урок откажется. Только после проверки новой базы отметьте Согласие85.
Сначала выполните ПроверитьМакет85: изменяется только независимая копия в памяти. Затем Профили85: будущие установки затронут имя общего профиля своей новой базы и профиль только текущего собственного пользователя. Этот опыт не запускается автоматически. Здесь CF, F7, пользователь, профиль, 1С и GUI не создавались и не запускались: runtimeVerifiedScenarios=0.
Функция Выполнить85(Согласие) Экспорт
Паспорт = ПрофилиСчетаСлужебный85.ПроверитьСтенд85(Согласие);
Снимки = ПрофилиСчетаСлужебный85.Снимки85();
Схема = ПрофилиСчетаСлужебный85.СоздатьСхему85();
ТекстСхемы = ПрофилиСчетаСлужебный85.Сериализовать85(Схема);
СвойМакет = ПрофилиСчетаСлужебный85.ИзСтроки85(Снимки.Спокойный, Тип("МакетОформленияКомпоновкиДанных"));
До = ПрофилиСчетаСлужебный85.ПроверитьДокумент85(ПрофилиСчетаСлужебный85.Вывести85(Схема, СвойМакет), Новый Цвет(14, 178, 222));
ПараметрОбласти = СвойМакет.Найти("ДетальныеЗаписи");
Если ПараметрОбласти = Неопределено Тогда
ВызватьИсключение "В собственном полном макете нет реальной области деталей";
КонецЕсли;
Область = ПараметрОбласти.Значение;
Если ТипЗнч(Область) <> Тип("ОбластьМакетаОформленияКомпоновкиДанных") Тогда
ВызватьИсключение "Значение параметра должно быть настоящей коллекцией области";
КонецЕсли;
ПрофилиСчетаСлужебный85.ПроверитьСнимки85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы);
Область.Очистить();
Элемент = Область.Добавить();
Если ТипЗнч(Элемент) <> Тип("ЭлементОбластиМакетаОформленияКомпоновкиДанных") Тогда
ВызватьИсключение "Добавить должно вернуть реальный элемент своей независимой области";
КонецЕсли;
Элемент.Уровень = 0;
Оформление = Элемент.Оформление;
Если ТипЗнч(Оформление) <> Тип("ОформлениеКомпоновкиДанных") Тогда
ВызватьИсключение "Readonly Оформление имеет документированный базовый тип";
КонецЕсли;
Для Каждого ИмяПараметра Из СтрРазделить("ЦветФона,ЦветТекста,Формат", ",") Цикл
Ключ = Новый ПараметрКомпоновкиДанных(ИмяПараметра);
Если Оформление.ДоступныеПараметры.НайтиПараметр(Ключ) = Неопределено Тогда
ВызватьИсключение "Недоступен необходимый параметр собственного оформления";
КонецЕсли;
Если ИмяПараметра = "ЦветФона" Тогда
Значение = Новый Цвет(245, 229, 170);
ИначеЕсли ИмяПараметра = "ЦветТекста" Тогда
Значение = Новый Цвет(0, 0, 0);
Иначе
Значение = "ЧДЦ=0;ЧГ=0";
КонецЕсли;
Оформление.УстановитьЗначениеПараметра(Ключ, Значение);
Установленное = Оформление.НайтиЗначениеПараметра(Ключ);
Если Установленное = Неопределено Тогда
ВызватьИсключение "Реальное установленное значение не найдено";
КонецЕсли;
Если Не Установленное.Использование Или Установленное.Значение <> Значение Тогда
ВызватьИсключение "Параметр не сохранил своё значение и использование";
КонецЕсли;
КонецЦикла;
Если Область.Количество() <> 1 Или Область.Получить(0) <> Элемент Или Элемент.Уровень <> 0 Тогда
ВызватьИсключение "Перед выводом в своей области нужен один собственный элемент уровня 0";
КонецЕсли;
После = ПрофилиСчетаСлужебный85.ПроверитьДокумент85(ПрофилиСчетаСлужебный85.Вывести85(Схема, СвойМакет), Новый Цвет(245, 229, 170));
ПрофилиСчетаСлужебный85.ПроверитьСнимки85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы);
Восстановленный = ПрофилиСчетаСлужебный85.ИзСтроки85(Снимки.Спокойный, Тип("МакетОформленияКомпоновкиДанных"));
Если ПрофилиСчетаСлужебный85.Сериализовать85(Восстановленный) <> Снимки.Спокойный Тогда
ВызватьИсключение "Не восстановилась полная независимая копия макета";
КонецЕсли;
Снова = ПрофилиСчетаСлужебный85.ПроверитьДокумент85(ПрофилиСчетаСлужебный85.Вывести85(Схема, Восстановленный), Неопределено);
Для Каждого Фон Из До.Фоны Цикл
Если Снова.Фоны.Получить(Фон.Ключ) <> Фон.Значение Тогда
ВызватьИсключение "Не вернулся фактически прочитанный исходный RGB каждой числовой ячейки";
КонецЕсли;
КонецЦикла;
ПрофилиСчетаСлужебный85.ПроверитьСнимки85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы);
Возврат "Модель и три документа проверены: 3 товара, 9 чисел, количество " + Формат(После.Количество, "ЧДЦ=0;ЧГ=0")
+ ", сумма " + Формат(После.Сумма, "ЧДЦ=0;ЧГ=0") + "; реальные RGB восстановлены";
КонецФункцииПрофилиСчетаСлужебный85
Конфигуратор → Общие → Общие модули → ПрофилиСчетаСлужебный85 → Модуль
Серверный неглобальный общий модуль собственной новой FileCF 8.5.1.1343; native объекты локальны, на клиент передаётся только строка результата.
Функция ПроверитьСтенд85(Согласие) Экспорт
Если ТипЗнч(Согласие) <> Тип("Булево") Или Не Согласие Тогда
ВызватьИсключение "Сначала подтвердите согласие на работу только в своём новом учебном стенде";
КонецЕсли;
Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1CStudy\OwnReportAppearance85_6d4f472b-b7d2-4266-a960-ad45450fe2cf\IB"";" Тогда
ВызватьИсключение "Не совпала точная платформа, конфигурация, совместимость или строка регистрации своей FileCF";
КонецЕсли;
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0
Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0
Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0
Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0
Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0
Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0
Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0
Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0
Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ОбщиеФормы.Количество() <> 0
Или Метаданные.ОбщиеМодули.Количество() <> 3 Или Метаданные.ОбщиеМакеты.Количество() <> 2
Или Метаданные.Обработки.Количество() <> 1 Или Метаданные.Отчеты.Количество() <> 0
Или Метаданные.Роли.Количество() <> 1 Тогда
ВызватьИсключение "Состав новой учебной конфигурации должен точно соответствовать подготовке";
КонецЕсли;
Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0
Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() <> 0
Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0
Или ТранзакцияАктивна() Тогда
ВызватьИсключение "Нужен сеанс без расширений и без чужой транзакции";
КонецЕсли;
Для Каждого Модуль Из Метаданные.ОбщиеМодули Цикл
Если Модуль.Имя <> "ПрофилиСчетаСлужебный85" И Модуль.Имя <> "ПрофилиСчетаМакет85"
И Модуль.Имя <> "ПрофилиСчетаНастройки85" Тогда
ВызватьИсключение "Найден чужой общий модуль";
КонецЕсли;
Если Модуль.Глобальный Или Не Модуль.Сервер Или Модуль.КлиентУправляемоеПриложение
Или Модуль.КлиентОбычноеПриложение Или Модуль.ВнешнееСоединение Или Модуль.Привилегированный Тогда
ВызватьИсключение "Нужны только собственные неглобальные непривилегированные серверные модули";
КонецЕсли;
Если Модуль.ПовторноеИспользованиеВозвращаемыхЗначений <> Метаданные.СвойстваОбъектов.ПовторноеИспользованиеВозвращаемыхЗначений.НеИспользовать
Или Модуль.ВызовСервера <> (Модуль.Имя <> "ПрофилиСчетаСлужебный85") Тогда
ВызватьИсключение "Не совпал доступ с клиента или отключённое повторное использование значений";
КонецЕсли;
КонецЦикла;
Если Метаданные.Обработки.УчебныеПрофилиОформления85.Формы.Количество() <> 1
Или Метаданные.Обработки.УчебныеПрофилиОформления85.Формы.Найти("Пульт") = Неопределено Тогда
ВызватьИсключение "Нужна одна собственная управляемая форма Пульт";
КонецЕсли;
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Текущий = Неопределено Или Пользователи.Количество() <> 1 Тогда
ВызватьИсключение "Нужен единственный реальный пользователь новой учебной базы";
КонецЕсли;
Если Текущий.Имя <> "Профили85Ученик" Или Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор Тогда
ВызватьИсключение "Не совпала настоящая идентичность своего пользователя";
КонецЕсли;
Соединения = ПолучитьСоединенияИнформационнойБазы();
Если Соединения.Количество() <> 1 Тогда
ВызватьИсключение "Закройте Конфигуратор и другие сеансы: требуется одно собственное соединение";
КонецЕсли;
Соединение = Соединения[0];
Если ТипЗнч(Соединение) <> Тип("СоединениеИнформационнойБазы")
Или ТипЗнч(Соединение.Пользователь) <> Тип("ПользовательИнформационнойБазы") Тогда
ВызватьИсключение "Неизвестный тип описания собственного соединения";
КонецЕсли;
РольСтенда = Метаданные.Роли.Найти("Профили85ПолныеПрава");
Если РольСтенда = Неопределено Тогда
ВызватьИсключение "Не найдена собственная учебная роль";
КонецЕсли;
Если РольСтенда.ПолноеИмя() <> "Роль.Профили85ПолныеПрава" Тогда
ВызватьИсключение "Не совпало полное имя собственной роли";
КонецЕсли;
Если Соединение.НомерСоединения <> НомерСоединенияИнформационнойБазы()
Или Соединение.Пользователь.УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
Или Не РольДоступна("Профили85ПолныеПрава") Тогда
ВызватьИсключение "Нужно текущее собственное соединение и назначенная собственная учебная роль";
КонецЕсли;
Возврат Новый ФиксированнаяСтруктура("Пользователь,Имя,Соединение", Текущий.УникальныйИдентификатор, Текущий.Имя, Соединение.НомерСоединения);
КонецФункции
Функция Сериализовать85(Значение) Экспорт
Запись = Новый ЗаписьXML;
ОшибкаЗаписи = "";
Попытка
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, Значение);
Исключение
ОшибкаЗаписи = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
ТекстXML = "";
ОшибкаЗакрытия = "";
Попытка
ТекстXML = Запись.Закрыть();
Исключение
ОшибкаЗакрытия = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если ОшибкаЗаписи <> "" Тогда
ВызватьИсключение "Первичная ошибка записи XML: " + ОшибкаЗаписи + "; ошибка завершения: " + ОшибкаЗакрытия;
КонецЕсли;
Если ОшибкаЗакрытия <> "" Тогда
ВызватьИсключение "Ошибка завершения записи XML: " + ОшибкаЗакрытия;
КонецЕсли;
Если ТипЗнч(ТекстXML) <> Тип("Строка") Или ТекстXML = "" Тогда
ВызватьИсключение "Не получена полная собственная XML-строка";
КонецЕсли;
Возврат ТекстXML;
КонецФункции
Функция ИзСтроки85(ТекстXML, ОжидаемыйТип) Экспорт
Чтение = Новый ЧтениеXML;
Объект = Неопределено;
ОшибкаЧтения = "";
Попытка
Чтение.УстановитьСтроку(ТекстXML);
Объект = СериализаторXDTO.ПрочитатьXML(Чтение, ОжидаемыйТип);
Исключение
ОшибкаЧтения = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
ОшибкаЗакрытия = "";
Попытка
Чтение.Закрыть();
Исключение
ОшибкаЗакрытия = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если ОшибкаЧтения <> "" Тогда
ВызватьИсключение "Первичная ошибка чтения XML: " + ОшибкаЧтения + "; ошибка завершения: " + ОшибкаЗакрытия;
КонецЕсли;
Если ОшибкаЗакрытия <> "" Тогда
ВызватьИсключение "Ошибка завершения чтения XML: " + ОшибкаЗакрытия;
КонецЕсли;
Если ТипЗнч(Объект) <> ОжидаемыйТип Тогда
ВызватьИсключение "Не совпал фактический тип полной независимой копии";
КонецЕсли;
Возврат Объект;
КонецФункции
Функция ПолучитьМакет85(Имя) Экспорт
Если Имя = "СвойСпокойный85" Тогда
Описание = Метаданные.ОбщиеМакеты.СвойСпокойный85;
ИначеЕсли Имя = "СвойКонтраст85" Тогда
Описание = Метаданные.ОбщиеМакеты.СвойКонтраст85;
Иначе
ВызватьИсключение "Профиль не указывает на один из двух собственных compiled макетов";
КонецЕсли;
Если Описание.ПолноеИмя() <> "ОбщийМакет." + Имя Тогда
ВызватьИсключение "Не совпало полное имя собственного общего макета";
КонецЕсли;
Макет = ПолучитьОбщийМакет(Описание);
Если ТипЗнч(Макет) <> Тип("МакетОформленияКомпоновкиДанных") Тогда
ВызватьИсключение "В Конфигураторе нужен реальный макет оформления компоновки данных, не табличный документ";
КонецЕсли;
Возврат Макет;
КонецФункции
Функция Снимки85() Экспорт
Спокойный = ПолучитьМакет85("СвойСпокойный85");
Контраст = ПолучитьМакет85("СвойКонтраст85");
Библиотека = БиблиотекаМакетовОформленияКомпоновкиДанных.Основной;
Если ТипЗнч(Библиотека) <> Тип("МакетОформленияКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен реальный библиотечный макет; библиотеку не изменяем";
КонецЕсли;
Возврат Новый ФиксированнаяСтруктура("Спокойный,Контраст,Библиотека", Сериализовать85(Спокойный), Сериализовать85(Контраст), Сериализовать85(Библиотека));
КонецФункции
Процедура ПроверитьСнимки85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы) Экспорт
Сейчас = ПроверитьСтенд85(Согласие);
Если Сейчас.Пользователь <> Паспорт.Пользователь Или Сейчас.Имя <> Паспорт.Имя Или Сейчас.Соединение <> Паспорт.Соединение Тогда
ВызватьИсключение "Изменилось собственное соединение или пользователь";
КонецЕсли;
МакетыСейчас = Снимки85();
Если МакетыСейчас.Спокойный <> Снимки.Спокойный Или МакетыСейчас.Контраст <> Снимки.Контраст
Или МакетыСейчас.Библиотека <> Снимки.Библиотека Или Сериализовать85(Схема) <> ТекстСхемы Тогда
ВызватьИсключение "Изменился полный исходный макет или собственная схема; продолжение запрещено";
КонецЕсли;
КонецПроцедуры
Функция СоздатьСхему85() Экспорт
Схема = Новый СхемаКомпоновкиДанных;
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "УчебныйИсточник";
Источник.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Набор.Имя = "СвойСчет";
Набор.ИсточникДанных = Источник.Имя;
Набор.АвтоЗаполнениеДоступныхПолей = Истина;
Набор.Запрос = "ВЫБРАТЬ
| ""BOOK"" КАК Код, ""Книга"" КАК Наименование,
| 2 КАК Количество, 250 КАК Цена, 500 КАК Сумма
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""PAPER"", ""Бумага"", 5, 50, 250
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""TEA"", ""Чай"", 3, 100, 300";
Настройки = Схема.НастройкиПоУмолчанию;
Для Каждого Имя Из СтрРазделить("Код,Наименование,Количество,Цена,Сумма", ",") Цикл
Поле = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
Поле.Поле = Новый ПолеКомпоновкиДанных(Имя);
Поле.Использование = Истина;
КонецЦикла;
Группа = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Группа.Использование = Истина;
Выбор = Группа.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Выбор.Использование = Истина;
Возврат Схема;
КонецФункции
Функция Вывести85(Схема, Оформление) Экспорт
Если ТипЗнч(Оформление) <> Тип("МакетОформленияКомпоновкиДанных") Тогда
ВызватьИсключение "Четвёртый аргумент компоновщика — реальный полный макет, не его имя";
КонецЕсли;
Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = Компоновщик.Выполнить(Схема, Схема.НастройкиПоУмолчанию, , Оформление, Тип("ГенераторМакетаКомпоновкиДанных"));
Процессор = Новый ПроцессорКомпоновкиДанных;
Процессор.Инициализировать(Макет);
Документ = Новый ТабличныйДокумент;
Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
Вывод.ОтображатьПроцентВывода = Ложь;
Вывод.УстановитьДокумент(Документ);
Результат = Вывод.Вывести(Процессор, Ложь);
Если ТипЗнч(Результат) <> Тип("ТабличныйДокумент") Тогда
ВызватьИсключение "Не получен настоящий табличный документ";
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЧислоЯчейки85(Ячейка)
Если Ячейка.СодержитЗначение Тогда
Если ТипЗнч(Ячейка.Значение) <> Тип("Число") Тогда
ВызватьИсключение "Числовая ячейка содержит другое значение";
КонецЕсли;
Возврат Ячейка.Значение;
КонецЕсли;
Текст = СтрЗаменить(СтрЗаменить(СокрЛП(Ячейка.Текст), Символ(160), ""), " ", "");
Если Текст = "" Тогда
ВызватьИсключение "Нет фактического числа в собственной числовой ячейке";
КонецЕсли;
Для Позиция = 1 По СтрДлина(Текст) Цикл
Если СтрНайти("0123456789", Сред(Текст, Позиция, 1)) = 0 Тогда
ВызватьИсключение "Для этого собственного целочисленного счёта задан формат ЧДЦ=0;ЧГ=0";
КонецЕсли;
КонецЦикла;
Возврат Число(Текст);
КонецФункции
Функция ПроверитьДокумент85(Документ, ОжидаемыйФон) Экспорт
Если Документ.ВысотаТаблицы < 4 Или Документ.ВысотаТаблицы > 100
Или Документ.ШиринаТаблицы < 5 Или Документ.ШиринаТаблицы > 30 Тогда
ВызватьИсключение "Ожидается только собственный небольшой счёт";
КонецЕсли;
Колонки = Новый Соответствие;
СтрокаЗаголовков = 0;
Для Строка = 1 По Документ.ВысотаТаблицы Цикл
Кандидат = Новый Соответствие;
Для Колонка = 1 По Документ.ШиринаТаблицы Цикл
Текст = СокрЛП(Документ.Область(Строка, Колонка).Текст);
Если Текст = "Код" Или Текст = "Наименование" Или Текст = "Количество" Или Текст = "Цена" Или Текст = "Сумма" Тогда
Если Кандидат.Получить(Текст) <> Неопределено Тогда
ВызватьИсключение "Повторился заголовок собственного поля";
КонецЕсли;
Кандидат.Вставить(Текст, Колонка);
КонецЕсли;
КонецЦикла;
Если Кандидат.Количество() = 5 Тогда
Если СтрокаЗаголовков <> 0 Тогда
ВызватьИсключение "В счёте нужна одна таблица с пятью полями";
КонецЕсли;
СтрокаЗаголовков = Строка;
Колонки = Кандидат;
КонецЕсли;
КонецЦикла;
Если СтрокаЗаголовков = 0 Тогда
ВызватьИсключение "Не найдены все реальные заголовки";
КонецЕсли;
Ожидания = Новый Соответствие;
Ожидания.Вставить("BOOK", Новый ФиксированнаяСтруктура("Наименование,Количество,Цена,Сумма", "Книга", 2, 250, 500));
Ожидания.Вставить("PAPER", Новый ФиксированнаяСтруктура("Наименование,Количество,Цена,Сумма", "Бумага", 5, 50, 250));
Ожидания.Вставить("TEA", Новый ФиксированнаяСтруктура("Наименование,Количество,Цена,Сумма", "Чай", 3, 100, 300));
Найдены = Новый Соответствие;
Фоны = Новый Соответствие;
КоличествоИтого = 0;
СуммаИтого = 0;
Для Строка = СтрокаЗаголовков + 1 По Документ.ВысотаТаблицы Цикл
Код = СокрЛП(Документ.Область(Строка, Колонки.Получить("Код")).Текст);
Ожидание = Ожидания.Получить(Код);
Если Ожидание = Неопределено Тогда
Для Каждого ИмяПоля Из СтрРазделить("Код,Наименование,Количество,Цена,Сумма", ",") Цикл
Посторонняя = Документ.Область(Строка, Колонки.Получить(ИмяПоля));
Если СокрЛП(Посторонняя.Текст) <> "" Или Посторонняя.СодержитЗначение Тогда
ВызватьИсключение "Посторонняя строка или итоговая строка не относится к своему счёту";
КонецЕсли;
КонецЦикла;
Продолжить;
КонецЕсли;
Если Найдены.Получить(Код) <> Неопределено
Или СокрЛП(Документ.Область(Строка, Колонки.Получить("Наименование")).Текст) <> Ожидание.Наименование Тогда
ВызватьИсключение "Не совпало реальное наименование или товар повторился";
КонецЕсли;
Найдены.Вставить(Код, Истина);
Для Каждого ИмяПоля Из СтрРазделить("Количество,Цена,Сумма", ",") Цикл
Ячейка = Документ.Область(Строка, Колонки.Получить(ИмяПоля));
Значение = ЧислоЯчейки85(Ячейка);
Если ИмяПоля = "Количество" Тогда
Требуется = Ожидание.Количество;
КоличествоИтого = КоличествоИтого + Значение;
ИначеЕсли ИмяПоля = "Цена" Тогда
Требуется = Ожидание.Цена;
Иначе
Требуется = Ожидание.Сумма;
СуммаИтого = СуммаИтого + Значение;
КонецЕсли;
Если Значение <> Требуется Тогда
ВызватьИсключение "Не совпало фактическое число " + Код + ":" + ИмяПоля;
КонецЕсли;
Фон = Ячейка.ЦветФона.ПолучитьАбсолютный();
Если ОжидаемыйФон <> Неопределено Тогда
Если Фон.Красный <> ОжидаемыйФон.Красный Или Фон.Зеленый <> ОжидаемыйФон.Зеленый
Или Фон.Синий <> ОжидаемыйФон.Синий Тогда
ВызватьИсключение "Цвет модели не подтвердился в настоящей ячейке " + Код + ":" + ИмяПоля;
КонецЕсли;
КонецЕсли;
Фоны.Вставить(Код + ":" + ИмяПоля, Строка(Фон.Красный) + "/" + Строка(Фон.Зеленый) + "/" + Строка(Фон.Синий));
КонецЦикла;
КонецЦикла;
Если Найдены.Количество() <> 3 Или Фоны.Количество() <> 9 Или КоличествоИтого <> 10 Или СуммаИтого <> 1050 Тогда
ВызватьИсключение "Нужны все три товара, девять чисел, количество 10 и сумма 1050";
КонецЕсли;
Возврат Новый ФиксированнаяСтруктура("Фоны,Количество,Сумма", Новый ФиксированноеСоответствие(Фоны), КоличествоИтого, СуммаИтого);
КонецФункцииПрофилиСчетаНастройки85
Конфигуратор → Общие → Общие модули → ПрофилиСчетаНастройки85 → Модуль
Серверный неглобальный общий модуль собственной новой FileCF 8.5.1.1343; native объекты локальны, на клиент передаётся только строка результата.
Функция Выполнить85(Согласие) Экспорт
Паспорт = ПрофилиСчетаСлужебный85.ПроверитьСтенд85(Согласие);
Снимки = ПрофилиСчетаСлужебный85.Снимки85();
Схема = ПрофилиСчетаСлужебный85.СоздатьСхему85();
ТекстСхемы = ПрофилиСчетаСлужебный85.Сериализовать85(Схема);
Менеджер = ОформлениеОтчетов;
Если ТипЗнч(Менеджер) <> Тип("МенеджерОформленияОтчетов") Тогда
ВызватьИсключение "Нужен настоящий менеджер из readonly глобального свойства";
КонецЕсли;
ПроверитьСостояние85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы, Менеджер, "", "");
Менеджер.УстановитьОбщийМакетОформления("СвойСпокойный85");
ПроверитьСостояние85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы, Менеджер, "СвойСпокойный85", "");
Менеджер.УстановитьМакетОформленияПользователя("СвойКонтраст85", Паспорт.Имя);
ПроверитьСостояние85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы, Менеджер, "СвойСпокойный85", "СвойКонтраст85");
Общий = Сформировать85(Менеджер, Паспорт, Схема, "ОБЩИЙ");
Персональный = Сформировать85(Менеджер, Паспорт, Схема, "ПЕРСОНАЛЬНЫЙ");
Если Общий.Количество <> Персональный.Количество Или Общий.Сумма <> Персональный.Сумма Тогда
ВызватьИсключение "Два реальных оформления не должны изменять числа счёта";
КонецЕсли;
ПроверитьСостояние85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы, Менеджер, "СвойСпокойный85", "СвойКонтраст85");
Менеджер.УстановитьМакетОформленияПользователя("", Паспорт.Имя);
ПроверитьСостояние85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы, Менеджер, "СвойСпокойный85", "");
Менеджер.УстановитьОбщийМакетОформления("");
ПроверитьСостояние85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы, Менеджер, "", "");
Возврат "Оба реальных профиля проверены и сброшены пустыми именами: общий и персональный. Два документа: количество "
+ Формат(Персональный.Количество, "ЧДЦ=0;ЧГ=0") + ", сумма " + Формат(Персональный.Сумма, "ЧДЦ=0;ЧГ=0")
+ ". Пустое имя означает системный макет, не угаданный приоритет";
КонецФункции
Процедура ПроверитьСостояние85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы, Менеджер, Общий, Персональный)
ПрофилиСчетаСлужебный85.ПроверитьСнимки85(Согласие, Паспорт, Снимки, Схема, ТекстСхемы);
Если ТипЗнч(Менеджер) <> Тип("МенеджерОформленияОтчетов") Тогда
ВызватьИсключение "Получен неизвестный менеджер профилей";
КонецЕсли;
ОбщийСейчас = Менеджер.ПолучитьОбщийМакетОформления();
ПерсональныйСейчас = Менеджер.ПолучитьМакетОформленияПользователя(Паспорт.Имя);
Если ТипЗнч(ОбщийСейчас) <> Тип("Строка") Или ТипЗнч(ПерсональныйСейчас) <> Тип("Строка")
Или ОбщийСейчас <> Общий Или ПерсональныйСейчас <> Персональный Тогда
ВызватьИсключение "Не совпали оба фактических имени: неизвестное состояние не меняем и не восстанавливаем";
КонецЕсли;
КонецПроцедуры
Функция Сформировать85(Менеджер, Паспорт, Схема, Режим)
Если ТипЗнч(Менеджер) <> Тип("МенеджерОформленияОтчетов") Тогда
ВызватьИсключение "Нужен собственный native менеджер";
КонецЕсли;
Если Режим = "ОБЩИЙ" Тогда
Имя = Менеджер.ПолучитьОбщийМакетОформления();
Если Имя <> "СвойСпокойный85" Тогда
ВызватьИсключение "Общий consumer допускает только свой подтверждённый спокойный профиль";
КонецЕсли;
Фон = Новый Цвет(14, 178, 222);
ИначеЕсли Режим = "ПЕРСОНАЛЬНЫЙ" Тогда
Имя = Менеджер.ПолучитьМакетОформленияПользователя(Паспорт.Имя);
Если Имя <> "СвойКонтраст85" Тогда
ВызватьИсключение "Персональный consumer допускает только свой подтверждённый контрастный профиль";
КонецЕсли;
Фон = Новый Цвет(245, 229, 170);
Иначе
ВызватьИсключение "Режим собственного consumer задан явно; системный приоритет не угадываем";
КонецЕсли;
Исходный = ПрофилиСчетаСлужебный85.ПолучитьМакет85(Имя);
Текст = ПрофилиСчетаСлужебный85.Сериализовать85(Исходный);
Копия = ПрофилиСчетаСлужебный85.ИзСтроки85(Текст, Тип("МакетОформленияКомпоновкиДанных"));
Результат = ПрофилиСчетаСлужебный85.ПроверитьДокумент85(ПрофилиСчетаСлужебный85.Вывести85(Схема, Копия), Фон);
Если ПрофилиСчетаСлужебный85.Сериализовать85(Исходный) <> Текст Тогда
ВызватьИсключение "Consumer изменил исходный compiled макет";
КонецЕсли;
Возврат Результат;
КонецФункцииУчебныеПрофилиОформления85.Пульт
Конфигуратор → Обработки → УчебныеПрофилиОформления85 → Формы → Пульт → Модуль
Клиентский модуль собственной управляемой формы. Никаких metadata/server-only вызовов на клиенте; две реальные native команды.
&НаКлиенте
Процедура ПроверитьМакет85(Команда)
Если Остановка85 Или Не Согласие85 Тогда
Остановка85 = Истина;
ВызватьИсключение "После отказа этот экземпляр формы больше не выполняет опыт";
КонецЕсли;
Попытка
Результат85 = ПрофилиСчетаМакет85.Выполнить85(Согласие85);
Исключение
Остановка85 = Истина;
Результат85 = "ОСТАНОВКА: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура Профили85(Команда)
Если Остановка85 Или Не Согласие85 Или ПрофилиВыполнены85 Тогда
Остановка85 = Истина;
ВызватьИсключение "Нет согласия, уже была ошибка или опыт профилей ранее выполнен";
КонецЕсли;
Попытка
Результат85 = ПрофилиСчетаНастройки85.Выполнить85(Согласие85);
ПрофилиВыполнены85 = Истина;
Исключение
Остановка85 = Истина;
Результат85 = "ОСТАНОВКА: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ВызватьИсключение;
КонецПопытки;
КонецПроцедурыСпецификация собственных compiled макетов
Общие → Общие макеты → constructor Макет оформления компоновки данных
Ручная подготовка в Конфигураторе, не исполняемый BSL/автоматический импорт
{
"configuration": "УчебныеПрофилиОформления85",
"manualOnly": true,
"kind": "Макет оформления компоновки данных",
"templates": [
{
"name": "СвойСпокойный85",
"area": "ДетальныеЗаписи",
"level": 0,
"enabled": {
"ЦветФона": {
"type": "Цвет",
"RGB": [
14,
178,
222
]
},
"ЦветТекста": {
"type": "Цвет",
"RGB": [
20,
45,
60
]
},
"Формат": {
"type": "Строка",
"value": "ЧДЦ=0;ЧГ=0"
}
}
},
{
"name": "СвойКонтраст85",
"area": "ДетальныеЗаписи",
"level": 0,
"enabled": {
"ЦветФона": {
"type": "Цвет",
"RGB": [
245,
229,
170
]
},
"ЦветТекста": {
"type": "Цвет",
"RGB": [
0,
0,
0
]
},
"Формат": {
"type": "Строка",
"value": "ЧДЦ=0;ЧГ=0"
}
}
}
],
"rows": [
[
"BOOK",
"Книга",
2,
250,
500
],
[
"PAPER",
"Бумага",
5,
50,
250
],
[
"TEA",
"Чай",
3,
100,
300
]
],
"nativeOutputsExpected": {
"rows": 3,
"numericCells": 9,
"quantity": 10,
"amount": 1050
},
"notAnImportFile": true
}Разбор по шагам
Получить независимую полную копию своего compiled спокойного макета. Первый native документ проверяет BOOK 2/250/500, PAPER 5/50/250, TEA 3/100/300 и исходные RGB всех девяти числовых ячеек.
Найти реальный параметр ДетальныеЗаписи и проверить тип его Значение. После полного guard очистить только область независимой копии; native Добавить возвращает настоящий AreaItem, не область и не выдуманный конструктор.
Установить уровень 0, получить readonly Оформление базового типа и проверить доступные параметры. SetParameterValue меняет значение внутри объекта и включает Использование; FindParameterValue должен вернуть реально установленное значение.
Второй native документ заново читает все девять чисел, количество 10, сумму 1050 и абсолютный RGB 245/229/170 каждой числовой ячейки. Только совпадение модели недостаточно.
После подтверждения всех исходных snapshots восстановить полную независимую копию из полного XML. Третий документ возвращает реальную исходную RGB-карту; исходные compiled макеты, схема и библиотека неизменны.
Как проверить результат
Исходные данные фиксированы, но проверяющий код читает реальные native ячейки: все три кода и наименования, девять чисел, сумму и количество. Числа/RGB в результат не записываются.
Отрицательный ручной опыт в отдельном своём коде: изменить BOOK на 20 при прежней проверке 2 — ошибка независимо от правильного оформления.
Отрицательный опыт: неправильный compiled kind или отсутствующая область/доступный параметр — отказ, без самостоятельного создания неизвестного extension/area.
Чужой пользователь, второе соединение, другой literal путь/суффикс, неизвестное непустое имя профиля или снятое согласие должны отказать до следующего setter.
Ошибку сериализации сохраняем до единственной попытки Close. Не повторяем failed Close; первичная ошибка не маскируется cleanup ошибкой. Не возвращаем результат после ошибки cleanup.
runtimeVerifiedScenarios=0: это будущий протокол проверки в 1С. Здесь подтверждены исходники и installed native, не выполнение UI/настроек.
Ожидаемый результат
При будущем ручном запуске три native документа сохранят три товара, девять чисел, количество 10 и сумму 1050; фактическая RGB-карта вернётся к первоначальной. Здесь 1С не запускалась.
На что обратить внимание
ОформлениеОтчетов readonly и доступно на сервере/толстом клиенте. В уроке менеджер и все макеты серверные; через RPC передаются только согласие и итоговая строка.
Оформление элемента readonly: свойство не заменять. Реальные доступные параметры изменяются внутри base ОформлениеКомпоновкиДанных. Contextual имя ОформлениеМакетаОформленияКомпоновкиДанных не используем как отдельную доказанную factory.
Native SetUser/SetCommon с пустым именем означает использовать системный макет. Native getter empty означает отсутствие установленного имени. Это не доказательство наследования общего профиля пользователем или системного приоритета.
Наш consumer сам выбирает один из двух явных режимов и передаёт реальный макет компоновщику. Он не доказывает, как любой стандартный отчёт конфигурации применит настройки по умолчанию.
Фактический RGB ячейки табличного документа — не pixel proof браузера, печати, экспорта или RLS. Имена/параметры/ячейки проверяются раздельно.
После partial failure форма остаётся STOP; автоматического повтора, удаления настроек или catch-restore нет. Не открывайте новую форму ради обхода ошибки; сначала вручную разберите состояние только своего стенда.
JSON-спецификация видима и копируема, но не автоматический импорт. Wizard и F7 — будущая ручная подготовка; агент не создавал CF/ИБ/пользователя/сеть/архивы.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.