Каталог ресурсных макетов таблицы: действительные области, перестановка и полное восстановление

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

Из собственного отчета магазины × товары получаем настоящий непустой ресурсный макет строк. Редактируем независимый полный черновик, проверяем каждый исходный объект и затем реальные ячейки восстановленной таблицы.

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

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

Подготовка

  1. НОВАЯ пустая файловая база 8.5.1.1343: Имя=УчебныеСтруктурыИРесурсы85, управляемое приложение, совместимость НеИспользовать. Без бизнес-метаданных, расширений и заданий. Не рабочая конфигурация. Здесь не запускалось: runtimeVerifiedScenarios=0.

  2. Общий модуль УчебныеСтруктурыИРесурсы85: Сервер=Да, Клиент=Нет, Вызов сервера=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте весь код одного урока. ВыполнитьПример — ФУНКЦИЯ, возвращающая текст квитанции; не заменяйте ее процедурой.

  3. Обработка УчебныеСтруктурыИРесурсы85 → управляемая форма Пульт → команда Выполнить с одноименным действием и кнопкой. Полный отдельный модуль формы ниже. F7 и обновление только своего нового стенда перед будущим отдельно разрешенным запуском.

  4. Все источники, схемы, настройки и проверки создаются в памяти из собственных констант. Не нужен существующий отчет, входной объект, данные реальных продаж, сеть или внешний файл.

  5. Источник и настоящий вывод — разные проверки. Скопировать ожидаемые числа в приемник нельзя: процессор получает настоящий собственный скомпилированный макет, и проверки читают его действительный результат.

  6. Три константные продажи Север/Книга/750, Север/Ручка/50, Юг/Книга/500. Строки по Магазин, колонки по Наименование, выбран ресурс Сумма. Настройки компонуются обычным генератором ТабличногоДокумента.

  7. По фактическим типам в строковой оси обходятся обычные группы, их шапка/подвал и тело. Берется первая настоящая область с непустым МакетРесурсов; техническое имя и число областей не угадываются.

  8. Проверка результата ищет реальные подписи осей, читает настоящие ячейки 750/50/500, пустое Юг/Ручка и общий итог 1300. Это не сравнение только высоты документа.

Функция ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    Если ПривилегированныйРежим() Тогда
        ВызватьИсключение "Привилегированный режим не нужен";
    КонецЕсли;
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "УчебныеПродажи";
    Источник.ТипИсточникаДанных = "Local";
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
    Набор.Имя = "СвоиТриСтроки";
    Набор.ИсточникДанных = Источник.Имя;
    Набор.АвтоЗаполнениеДоступныхПолей = Истина;
    Набор.Запрос = "ВЫБРАТЬ
    |    ""Север"" КАК Магазин,
    |    ""Книга"" КАК Наименование,
    |    3 КАК Количество,
    |    750 КАК Сумма
    |ОБЪЕДИНИТЬ ВСЕ
    |ВЫБРАТЬ ""Север"", ""Ручка"", 1, 50
    |ОБЪЕДИНИТЬ ВСЕ
    |ВЫБРАТЬ ""Юг"", ""Книга"", 2, 500";
    Для Каждого ИмяРесурса Из СтрРазделить("Сумма,Количество", ",") Цикл
        Ресурс = Схема.ПоляИтога.Добавить();
        Ресурс.ПутьКДанным = ИмяРесурса;
        Ресурс.Выражение = "Сумма(" + ИмяРесурса + ")";
    КонецЦикла;
    Настройки = Схема.НастройкиПоУмолчанию;
    ТаблицаНастроек = Настройки.Структура.Добавить(Тип("ТаблицаКомпоновкиДанных"));
    ТаблицаНастроек.Имя = "УчебныеМагазиныПоТоварам";
    ТаблицаНастроек.Использование = Истина;
    Выбор = ТаблицаНастроек.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
    Выбор.Поле = Новый ПолеКомпоновкиДанных("Сумма");
    Выбор.Использование = Истина;
    СтрокаНастроек = ТаблицаНастроек.Строки.Добавить();
    СтрокаНастроек.Имя = "Магазины";
    СтрокаНастроек.Использование = Истина;
    ПолеМагазина = СтрокаНастроек.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
    ПолеМагазина.Поле = Новый ПолеКомпоновкиДанных("Магазин");
    ПолеМагазина.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
    ПолеМагазина.Использование = Истина;
    КолонкаНастроек = ТаблицаНастроек.Колонки.Добавить();
    КолонкаНастроек.Имя = "Товары";
    КолонкаНастроек.Использование = Истина;
    ПолеТовара = КолонкаНастроек.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
    ПолеТовара.Поле = Новый ПолеКомпоновкиДанных("Наименование");
    ПолеТовара.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
    ПолеТовара.Использование = Истина;
    КонтрольныйЗапрос = Новый Запрос;
    КонтрольныйЗапрос.Текст = Набор.Запрос;
    ИсходныеСтроки = КонтрольныйЗапрос.Выполнить().Выгрузить();
    Если ИсходныеСтроки.Количество() <> 3 Или ИсходныеСтроки.Итог("Сумма") <> 1300 Тогда
        ВызватьИсключение "Изменились собственные учебные данные";
    КонецЕсли;
    Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
    Макет = Компоновщик.Выполнить(Схема, Настройки);
    ИсходнаяОбласть = ПолучитьСвойРесурсныйМакетТаблицы(Макет);
    ПроверитьСвоиРесурсныеСсылки(Макет, ИсходнаяОбласть);
    ПроверитьСвоюМатрицу(СформироватьСвойДокумент(Макет));
    ТекстМакета = СвойМакетВСтроку(Макет);
    Черновик = СвойМакетИзСтроки(ТекстМакета);
    ОбластьКопии = ПолучитьСвойРесурсныйМакетТаблицы(Черновик);
    Каталог = ОбластьКопии.МакетРесурсов;
    ИсходноеКоличество = Каталог.Количество();
    Если ИсходноеКоличество < 1 Тогда
        ВызватьИсключение "Нужен непустой реальный ресурсный каталог";
    КонецЕсли;
    Образец = Каталог.Получить(0);
    Первичные = Новый Массив;
    Для Каждого Элемент Из Каталог Цикл
        Первичные.Добавить(Элемент);
    КонецЦикла;
    ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 0);
    Первый = Каталог.Добавить();
    ЗаполнитьСвойЧерновойРесурс(Первый, Образец);
    Второй = Каталог.Вставить(0);
    ЗаполнитьСвойЧерновойРесурс(Второй, Образец);
    Если Каталог.Количество() <> ИсходноеКоличество + 2
        Или Каталог.Индекс(Второй) <> 0 Или Каталог.Индекс(Первый) <> ИсходноеКоличество + 1
        Или Каталог.Получить(0) <> Второй Тогда
        ВызватьИсключение "Не совпали фабричные объекты и позиции ресурсных макетов";
    КонецЕсли;
    ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 1);
    Каталог.Сдвинуть(Первый, -(ИсходноеКоличество + 1));
    Если Каталог.Получить(0) <> Первый Или Каталог.Индекс(Второй) <> 1 Тогда
        ВызватьИсключение "Переместился не тот собственный ресурсный макет";
    КонецЕсли;
    ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 2);
    Каталог.Удалить(Второй);
    Если Каталог.Количество() <> ИсходноеКоличество + 1 Или Каталог.Получить(0) <> Первый Тогда
        ВызватьИсключение "Удаление должно затронуть лишь второй собственный дубль";
    КонецЕсли;
    ПроверитьСвоиПервичныеЭлементы(Каталог, Первичные, 1);
    Каталог.Очистить();
    Если Каталог.Количество() <> 0 Тогда
        ВызватьИсключение "Не очищен ресурсный каталог только черновика";
    КонецЕсли;
    Если ПолучитьСвойРесурсныйМакетТаблицы(Макет) <> ИсходнаяОбласть
        Или СвойМакетВСтроку(Макет) <> ТекстМакета Тогда
        ВызватьИсключение "Правка независимой копии изменила исходный полный макет";
    КонецЕсли;
    Восстановленный = СвойМакетИзСтроки(ТекстМакета);
    ВосстановленнаяОбласть = ПолучитьСвойРесурсныйМакетТаблицы(Восстановленный);
    Если ВосстановленнаяОбласть.МакетРесурсов.Количество() <> ИсходноеКоличество Тогда
        ВызватьИсключение "Не восстановлен полный ресурсный каталог таблицы";
    КонецЕсли;
    ПроверитьСвоиРесурсныеСсылки(Восстановленный, ВосстановленнаяОбласть);
    ПроверитьСвоиРесурсныеСсылки(Макет, ИсходнаяОбласть);
    ПроверитьСвоюМатрицу(СформироватьСвойДокумент(Восстановленный));
    ПроверитьСвоюМатрицу(СформироватьСвойДокумент(Макет));
    Возврат "Макеты ресурсов таблицы: черновик очищен, реальные 750/50/500 и общий итог 1300 сохранены.";
КонецФункции

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

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

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

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

Процедура ДобавитьСвоюРесурснуюОбласть(Область, Найденные)
    Если ТипЗнч(Область) = Тип("МакетГруппировкиТаблицыМакетаКомпоновкиДанных") Тогда
        Если Область.МакетРесурсов.Количество() > 0 Тогда
            Найденные.Добавить(Область);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

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

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

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

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

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


Процедура ПроверитьМалыйДокумент(Документ)
    Если ТипЗнч(Документ) <> Тип("ТабличныйДокумент") Или Документ.ВысотаТаблицы < 1
        Или Документ.ШиринаТаблицы < 1 Или Документ.ВысотаТаблицы > 200 Или Документ.ШиринаТаблицы > 100 Тогда
        ВызватьИсключение "Проверка рассчитана только на свой небольшой документ";
    КонецЕсли;
КонецПроцедуры

Функция НайтиСвоюКоординату(Документ, Подпись, ПоСтроке)
    ПроверитьМалыйДокумент(Документ);
    Найдено = 0;
    Для НомерСтроки = 1 По Документ.ВысотаТаблицы Цикл
        Для НомерКолонки = 1 По Документ.ШиринаТаблицы Цикл
            Ячейка = Документ.Область(НомерСтроки, НомерКолонки);
            Если СокрЛП(Ячейка.Текст) = Подпись Тогда
                Координата = ?(ПоСтроке, НомерСтроки, НомерКолонки);
                Если Найдено <> 0 И Найдено <> Координата Тогда
                    ВызватьИсключение "Неоднозначная подпись своей оси: " + Подпись;
                КонецЕсли;
                Найдено = Координата;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    Если Найдено = 0 Тогда
        ВызватьИсключение "В реальном документе не найдена подпись " + Подпись;
    КонецЕсли;
    Возврат Найдено;
КонецФункции

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

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

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

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

Процедура ПроверитьСвоюМатрицу(Документ)
    Север = НайтиСвоюКоординату(Документ, "Север", Истина);
    Юг = НайтиСвоюКоординату(Документ, "Юг", Истина);
    Книга = НайтиСвоюКоординату(Документ, "Книга", Ложь);
    Ручка = НайтиСвоюКоординату(Документ, "Ручка", Ложь);
    Если Север = Юг Или Книга = Ручка Тогда
        ВызватьИсключение "Свои магазины и товары должны занимать разные позиции";
    КонецЕсли;
    ПроверитьСвоюЯчейку(Документ, Север, Книга, 750);
    ПроверитьСвоюЯчейку(Документ, Север, Ручка, 50);
    ПроверитьСвоюЯчейку(Документ, Юг, Книга, 500);
    ПроверитьСвоеПустоеПересечение(Документ, Юг, Ручка);
    ПроверитьСвойОбщийИтог(Документ);
КонецПроцедуры

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

УчебныеСтруктурыИРесурсы85 → Обработки → УчебныеСтруктурыИРесурсы85 → Формы → Пульт → Модуль

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

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

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

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

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

  2. Каждое настоящее Макет/МакетГруппировки — строковое имя; непустые ссылки разрешаются через Макет.Макеты.Найти с проверкой Неопределено. Необязательная пустая ссылка явно допускается.

  3. Первый полный настоящий документ проверяется до изменений. Две оси должны быть различны; реальные пересечения 750/50/500 и общий итог 1300.

  4. Полный XDTO-черновик собственного макета создается в строке памяти. Снимок каждого старого объекта каталога сохраняет относительный порядок.

  5. Добавить() и Вставить(0) НЕ получают Тип, возвращают МакетТелаТаблицыМакетаКомпоновкиДанных. Оба действительных имени областей копируются из собственного образца.

  6. Проверяем N+2 элементов, индексы 0 и N+1 и каждый старый объект с позиции 1. Сдвинуть первого в начало дает смещение старых 2; Удалить второго возвращает смещение 1.

  7. Очистить затрагивает лишь ресурсный каталог копии. Оригинальная область сохраняется тем же объектом, вся исходная сериализация — той же строкой. Каркасы/очищенный черновик никогда не исполняются.

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

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

  1. Размеры каталога N → N+2 → N+2 → N+1 → 0. Идентичность и порядок каждого старого элемента проверены на всех стадиях.

  2. Три независимых полных табличных документа содержат Север/Юг, Книга/Ручка, настоящие 750/50/500, отсутствующее сочетание Юг/Ручка и общий итог 1300.

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

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

Независимый ресурсный черновик очищен; полные оригинал и восстановление сохраняют реальные пересечения 750/50/500 и общий итог 1300. Здесь не запускалось в 1С.

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

  1. МакетТелаТаблицыМакетаКомпоновкиДанных не равен МакетТелаДиаграммыМакетаКомпоновкиДанных. Фабрика каталога ресурсов не равна разнородной фабрике тела группировки.

  2. МакетРесурсов — readonly-ссылка на изменяемый каталог. Макет и МакетГруппировки его элемента — строки имен областей, не ТабличныйДокумент.

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

  4. Черновые дубли могут быть неполными/избыточными: их не выводим. После очистки не используем старые ссылки; восстанавливаем весь связанный макет, не два поля.

  5. Смысл и расположение заголовков/итогов не подтверждены запуском в 1С. Здесь только статические проверки кода; нет бизнес-записей, сети, файлов, печати или резервных копий.

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

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

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

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

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