Каталог макетов схемы СКД: полный состав областей и безопасное восстановление

Учебные задачи

Редактируем собственный черновик из шапки, строки и итога. Каждое описание содержит реальную область СКД со строкой, ячейкой и постоянным текстовым полем. Переставляем и переименовываем описания, удаляем строку, восстанавливаем её, очищаем каталог и заново создаём все области. Независимая модель сохраняет исходное содержимое.

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

Полный серверный общий модуль УчебныеЗадачи своей новой пустой конфигурации УчебныеМакетыСхемы85; в1С не запускался.

Подготовка

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

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

  3. Будущая ручная подготовка только вне опыта: завершить прежний собственный сеанс, сохранить конфигурацию, Конфигурация → Обновить конфигурацию базы данных (F7), затем свежий собственный клиент и своя обработка. F7, форма, BSL, печать и процессор отчёта здесь не запускались.

  4. Данные A01 и количество3 — буквально написанные собственные демонстрационные надписи, не результаты запроса. Каждая область создаётся в памяти: МакетОбластиКомпоновкиДанных → одна СтрокаТаблицыОбластиКомпоновкиДанных → одна ячейка → одно ПолеОбластиКомпоновкиДанных со строковым Значение. Параметров нет, потому что нет выражений и подстановок.

Процедура ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    Если ПривилегированныйРежим() Тогда
        ВызватьИсключение "Для собственного каталога не нужен привилегированный режим";
    КонецЕсли;
    Пусто = Новый Массив;
    ВсеИмена = СтрРазделить("УчебнаяШапка85,УчебнаяСтрока85,УчебныйИтог85", ",");
    ВсеТексты = СтрРазделить("Отчёт: учебные остатки|Код A01; количество 3|Итого: 3", "|");
    Схема = Новый СхемаКомпоновкиДанных;
    ПроверитьСвойКаталогМакетов(Схема, Пусто, Пусто);
    Описания = Схема.Макеты;
    Шапка = Описания.Добавить();
    ЗаполнитьСвойИменованныйМакет(Шапка, ВсеИмена[0], ВсеТексты[0]);
    ПроверитьСвойКаталогМакетов(Схема, СтрРазделить("УчебнаяШапка85", ","), СтрРазделить("Отчёт: учебные остатки", "|"));
    СтрокаМакета = Описания.Добавить();
    ЗаполнитьСвойИменованныйМакет(СтрокаМакета, ВсеИмена[1], ВсеТексты[1]);
    ПроверитьСвойКаталогМакетов(Схема, СтрРазделить("УчебнаяШапка85,УчебнаяСтрока85", ","), СтрРазделить("Отчёт: учебные остатки|Код A01; количество 3", "|"));
    Итог = Описания.Вставить(1);
    ЗаполнитьСвойИменованныйМакет(Итог, ВсеИмена[2], ВсеТексты[2]);
    ПроверитьСвойКаталогМакетов(Схема, СтрРазделить("УчебнаяШапка85,УчебныйИтог85,УчебнаяСтрока85", ","), СтрРазделить("Отчёт: учебные остатки|Итого: 3|Код A01; количество 3", "|"));
    Описания.Сдвинуть(Итог, 1);
    ПроверитьСвойКаталогМакетов(Схема, ВсеИмена, ВсеТексты);
    СтрокаМакета.Имя = "УчебнаяСтрокаПечати85";
    ПроверитьСвойКаталогМакетов(Схема, СтрРазделить("УчебнаяШапка85,УчебнаяСтрокаПечати85,УчебныйИтог85", ","), ВсеТексты);
    Если Описания.Найти("УчебнаяСтрока85") <> Неопределено Или Описания.Найти("УчебнаяСтрокаПечати85") <> СтрокаМакета Тогда
        ВызватьИсключение "Переименование должно изменить ключ поиска, не содержимое области";
    КонецЕсли;
    СтрокаМакета.Имя = ВсеИмена[1];
    ПроверитьСвойКаталогМакетов(Схема, ВсеИмена, ВсеТексты);
    Копия = Новый СхемаКомпоновкиДанных;
    ВосстановитьСвойКаталогМакетов(Копия, ВсеИмена, ВсеТексты);
    Описания.Удалить(СтрокаМакета);
    ПроверитьСвойКаталогМакетов(Схема, СтрРазделить("УчебнаяШапка85,УчебныйИтог85", ","), СтрРазделить("Отчёт: учебные остатки|Итого: 3", "|"));
    Если Описания.Найти("УчебнаяСтрока85") <> Неопределено Тогда
        ВызватьИсключение "Удалённое собственное описание не должно находиться";
    КонецЕсли;
    ПроверитьСвойКаталогМакетов(Копия, ВсеИмена, ВсеТексты);
    НоваяСтрока = Описания.Вставить(1);
    ЗаполнитьСвойИменованныйМакет(НоваяСтрока, ВсеИмена[1], ВсеТексты[1]);
    ПроверитьСвойКаталогМакетов(Схема, ВсеИмена, ВсеТексты);
    Описания.Очистить();
    ПроверитьСвойКаталогМакетов(Схема, Пусто, Пусто);
    ПроверитьСвойКаталогМакетов(Копия, ВсеИмена, ВсеТексты);
    ВосстановитьСвойКаталогМакетов(Схема, ВсеИмена, ВсеТексты);
    ПроверитьСвойКаталогМакетов(Схема, ВсеИмена, ВсеТексты);
    ПроверитьСвойКаталогМакетов(Копия, ВсеИмена, ВсеТексты);
    Сообщить("Каталог восстановлен: УчебнаяШапка85, УчебнаяСтрока85, УчебныйИтог85; полные тексты областей совпали с независимой моделью");
КонецПроцедуры

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

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

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

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

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

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

Своя внешняя обработка УчебныеМакетыСхемы85 → управляемая Форма → Модуль

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

&НаКлиенте
Процедура Выполнить(Команда)
    ВыполнитьНаСервере();
    Сообщить("Каталог макетов схемы, содержимое областей и независимое восстановление проверены");
КонецПроцедуры

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

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

  1. Создать свою СхемаКомпоновкиДанных. Её readonly Макеты — каталог ОписанияМакетовСхемыКомпоновкиДанных, не каталог областей скомпилированного макета и не ЭлементРезультатаКомпоновкиДанных.Макеты. Проверить исходный пустой каталог.

  2. Добавить шапку и строку, записать собственные Имя и Макет. Макет должен быть специальной областью СКД, не ТабличныйДокумент. Отдельная функция строит всю цепочку настоящих дочерних объектов с полным постоянным текстом.

  3. Вставить итог по абсолютному индексу1 между шапкой и строкой. Полностью проверить порядок, имена, тип каждого описания, поиск по имени, Получить, Индекс и[] по числу/имени. В каждой области проверить ровно одну строку/ячейку/поле, точные типы, строковое значение и весь текст, а также readonly Параметры с количеством0.

  4. Сдвинуть принимает именно объект Итог и относительное смещение+1, после чего итог становится последним. Переименовать собственную строку и проверить, что прежний ключ поиска отсутствует, а новый ведёт к текущему описанию; содержимое области неизменно. Вернуть прежнее имя.

  5. Создать независимую собственную схему и заново наполнить её по тем же собственным массивам имён/текстов. Не переносить дочерние описания или области между владельцами. Удалить строку через Удалить(СтрокаМакета): здесь нужен объект, не индекс1. Старый объект больше не использовать; копия сохраняет все три области.

  6. Восстановить строку новым Вставить(1), создать ей новую область. Очистить только каталог оригинала и проверить0; независимая копия всё ещё содержит шапку, строку и итог со всеми прежними текстами. Восстановить оригинал новыми описаниями и новыми областями.

  7. Одиннадцать контрольных состояний оригинала проверяют весь именованный состав, типы и полное содержимое. Итоговая проверка обеих независимых моделей использует один полный согласованный эталон имён и текстов, не только число3. Никакой отчёт не исполняется и не печатается.

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

  1. Будущий результат собственного каталога: порядок УчебнаяШапка85/УчебнаяСтрока85/УчебныйИтог85, тексты «Отчёт: учебные остатки»/«Код A01; количество 3»/«Итого: 3». У каждой области ровно1строка,1ячейка,1поле,0параметров; после полного восстановления обе модели соответствуют этим значениям.

  2. Будущий отрицательный контроль: сразу после ЗаполнитьСвойИменованныйМакет(Итог,...) перед первой проверкой вставить строку Итог.Макет.Получить(0).Ячейки.Получить(0).Элементы.Получить(0).Значение = "Итого: 4"; не меняя ВсеТексты. Полная проверка должна отказать при тех же именах, числе областей и типах. Вернуть код, сохранить/F7 вне опыта и открыть новый свой сеанс. Здесь контроль не выполнялся.

  3. runtimeVerifiedScenarios=0. Это проверенный по справке самостоятельный черновик каталога, не готовый действующий отчёт, не проверка дизайна печатной формы и не результат компиляции/вывода СКД.

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

Пример различает каталог схемы и другие каталоги СКД, показывает реальные области правильного типа и полный контроль восстановления без неизвестного объекта или простого getter.

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

  1. Свойства Схема.Макеты и Описание.Параметры readonly. Редактируются содержимое своей коллекции и writable Имя/Макет описания; новая коллекция этим readonly свойствам не присваивается.

  2. Вставить принимает абсолютный индекс. Сдвинуть — описание и относительное смещение. Удалить — описание, не число. Контракты соседних коллекций СКД и коллекций схемы запроса нельзя переносить сюда по аналогии.

  3. Макет — МакетОбластиКомпоновкиДанных. ТабличныйДокумент может быть конечным способом вывода отчёта, но не значением этого свойства. Полный путь строка/ячейка/поле проверен, не оставлен пустой областью.

  4. Это постоянные демонстрационные области: параметры0 — осмысленная проверка отсутствия подстановок. Урок не притворяется примером вычисления параметров, получения остатков или обработки данных отчёта.

  5. После удаления/очистки прежние описания не используются. Для независимой модели всё создано заново из примитивных собственных имён и текстов, не разделяет изменяемые области с оригиналом.

  6. Без согласованных наборов данных, настроек и привязок макетов к полям/группировкам каталог не является работающим отчётом. Здесь показана задача редактирования своей структуры в памяти; нет файлов, записей, сети, принтера и рабочей конфигурации.

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

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

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

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

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