Удаляет измерение из коллекции.
Синтаксис
Удалить(<Измерение>)Примеры платформы
Для Индекс=0 По ПостроительОтчета.ИзмеренияСтроки.Количество()-1 Цикл
ТекущаяСтрока=ПостроительОтчета.ИзмеренияСтроки[Индекс];
Если ТекущаяСтрока.Имя = ВыбИмя Тогда
ПутьКДанным = ТекущаяСтрока.ПутьКДанным;
ПостроительОтчета.ИзмеренияСтроки.Удалить(ТекущаяСтрока);
Прервать;
КонецЕсли;
КонецЦикла;
Если ПостроительОтчета.ИзмеренияКолонки.Количество()>0 Тогда
ТекущаяКолонка=ПостроительОтчета.ИзмеренияКолонки[0];
ПостроительОтчета.ИзмеренияКолонки.Удалить(ТекущаяКолонка);
КонецЕсли;Полное описание, параметры и ограничения
ИзмеренияПостроителяОтчета.Удалить (ReportBuilderDimensions.Delete)
ИзмеренияПостроителяОтчета (ReportBuilderDimensions)
Удалить (Delete)
Доступен, начиная с версии 8.0.
Синтаксис:
Удалить(<Измерение>)
Параметры:
<Измерение> (обязательный)
Тип: ИзмерениеПостроителяОтчета.
Удаляемое измерение.
Описание:
Удаляет измерение из коллекции.
Доступность:
Сервер, толстый клиент, внешнее соединение.
Пример:
// Пример 1
Для Индекс=0 По ПостроительОтчета.ИзмеренияСтроки.Количество()-1 Цикл
ТекущаяСтрока=ПостроительОтчета.ИзмеренияСтроки[Индекс];
Если ТекущаяСтрока.Имя = ВыбИмя Тогда
ПутьКДанным = ТекущаяСтрока.ПутьКДанным;
ПостроительОтчета.ИзмеренияСтроки.Удалить(ТекущаяСтрока);
Прервать;
КонецЕсли;
КонецЦикла;
// Пример 2
Если ПостроительОтчета.ИзмеренияКолонки.Количество()>0 Тогда
ТекущаяКолонка=ПостроительОтчета.ИзмеренияКолонки[0];
ПостроительОтчета.ИзмеренияКолонки.Удалить(ТекущаяКолонка);
КонецЕсли;
Использование в версии:
Доступен, начиная с версии 8.0.
Методическая информация
Практические примеры
ПостроительОтчета: свой иерархический справочник, порядок группировок и четыре макета измерения
Полный обычный клиентский маршрут читает только свой справочник: сначала Класс→элемент, затем реально переставляет измерения и выводит контрольный кандидат, удаляет Класс и строит полную иерархию. Числа и ссылки проверяются в настоящих ячейках результата до замены отображаемых документов.
Где и как запускать
Полный модуль обычной формы своей обработки; только толстый клиент в обычном приложении Windows8.5.1.1343. Supporting общий модуль — обычный клиент, не сервер.
Подготовка
ВРУЧНУЮ создайте НОВУЮ отдельную файловую базу только платформы8.5.1.1343 в C:\1C85_OwnHierarchyLab\6a7df6aa-5e73-41b5-bda1-8f9c86ee4164\Base. Имя конфигурации=УчебнаяИерархияПостроителя85; основной режим запуска=Обычное приложение. Ровно один собственный пользователь Иерархия85Ученик с полными правами в этом пустом стенде. Не копируйте рабочую базу. Нет расширений, документов, регистров, планов, бизнес-процессов, подписок, заданий и внешних источников. Автор НЕ создавал базу, не запускал1С, не записывал карточки, не менялGUI/файлы/настройки; actualruntime=0, новых backups/archives нет.
В Конфигураторе: Справочники→Добавить→УчебнаяНоменклатура85. Иерархический=Да, вид=ИерархияГруппИЭлементов, не ограничивайте число уровней; подчинения владельцу нет. Код=Строка6, наименование=Строка40; уникальность кода=Да. Нет предопределённых строк и табличных частей. Ровно3 собственных реквизита, использование ДляГруппыИЭлемента: Класс85=Строка8, Количество85 и Сумма85=Число(12,0). История данных отключена, обработчики объекта/менеджера отсутствуют. Ссылка, Родитель, ЭтоГруппа, ПометкаУдаления — реальные стандартные реквизиты, не добавляйте их заново.
После обновления ТОЛЬКО своего стенда вручную создайте группы: код000001 Корень85 с пустым родителем; код000002 Напитки85 и код000003 Расходники85 с родителем Корень85. У всех групп Класс85="", Количество85=0, Сумма85=0. Затем создайте элементы: 000004 Альфа85 внутри Напитки85, Класс85=А85, Количество85=2, Сумма85=200; 000005 Бета85 внутри Напитки85, Б85/3/450; 000006 Гамма85 внутри Расходники85, А85/5/1000. Ровно6 строк, все без пометки удаления и без предопределённости. Никаких придумываемых UUID ссылок: код сам получает реальные ссылки этой выборки.
Обработки→Добавить→УчебныйИерархическийОтчет85. Создайте ровно одну Обычную форму Основная. Её реквизиты: ИсходныйОтчет85 и ИтоговыйОтчет85 типа ТабличныйДокумент, Состояние85 типа Строка неограниченной длины. Значения при открытии не восстанавливать. Разместите два ПолеТабличногоДокумента с данными этих реквизитов и многострочное поле состояния только для просмотра. Не используйте управляемую форму и НЕ помещайте код внутрь другого обработчика.
В своей форме назначьте событию ПриОткрытии точную процедуру ПриОткрытии(). Разместите обычный элемент управления Кнопка с именем Сформировать85 и свяжите его событие Нажатие с Сформировать85(Кнопка). Native Кнопка.Нажатие() имеет0 payload-параметров, но ordinary расширение элемента, расположенного в форме, добавляет первый Элемент — здесь это Кнопка. Это НЕ кнопка командной панели и НЕ managed Команда. Других callbacks и обработчиков расшифровки не нужно. Весь основной код вставьте в модуль этой формы на уровне модуля. Сама кнопка вызывает процедуру; не вызывайте её вручную из ПриОткрытии.
ОбщиеМодули→Добавить→СтендИерархии85. Клиент(обычное приложение)=Да, Сервер=Нет, Клиент(управляемое приложение)=Нет, ВнешнееСоединение=Нет, Глобальный=Нет, Привилегированный=Нет. В модуль вставьте полный supportingModules код. Экспортная ПроверитьСвойСтенд85 вызывается формой перед чтением. Других общих модулей нет. Откройте свою обработку вручную толстым клиентом в обычном приложении, не запускайте урок в тонком/web/managed клиенте.
Строгий guard принимает СтрокаСоединенияИнформационнойБазы() ровно File="C:\1C85_OwnHierarchyLab\6a7df6aa-5e73-41b5-bda1-8f9c86ee4164\Base";. Он не выводит эту строку и не разрешает Srvr/Ref/другую базу. Если собственный запуск даёт иную строку соединения, сначала разберите её в своём тестовом стенде; не отключайте guard и не подставляйте рабочие пути. Пустой стенд назван так по происхождению, но содержит только перечисленные собственные6 строк.
Макет НЕ внешняя картинка и не чужой MXL: код строит в памяти6 областей1×4: Элементы85, Группы85, ПодвалЭлемента85, ПодвалГруппы85, Класс85, Общие85. Колонка1=уникальный текстовый маркер, колонка2=настоящая ссылка или строковый класс, колонка3=числовой параметр Количество, колонка4=числовой параметр Сумма. СодержитЗначение и точные допустимые типы заданы ДО native вывода; после вывода код только читает ячейки, не чинит их ожидаемыми значениями.
#Если ТолстыйКлиентОбычноеПриложение Тогда
Процедура ПриОткрытии()
СтендИерархии85.ПроверитьСвойСтенд85();
ПрочитатьСобственныеСтроки85();
ИсходныйОтчет85 = Новый ТабличныйДокумент;
ИтоговыйОтчет85 = Новый ТабличныйДокумент;
ИсходныйОтчет85.ТолькоПросмотр = Истина;
ИтоговыйОтчет85.ТолькоПросмотр = Истина;
Состояние85 = "Сформировать85: слева Класс→Номенклатура без групп; справа полная иерархия Номенклатуры. Все числа читаются из своих карточек.";
КонецПроцедуры
Процедура Сформировать85(Кнопка)
СтендИерархии85.ПроверитьСвойСтенд85();
Свои = ПрочитатьСобственныеСтроки85();
Построитель = СоздатьСобственныйПостроитель85(Свои);
Измерения = Построитель.ИзмеренияСтроки;
Номенклатура = Измерения.Добавить("Номенклатура", "Номенклатура", ТипИзмеренияПостроителяОтчета.Элементы);
Класс = Измерения.Вставить("Класс", "Класс", ТипИзмеренияПостроителяОтчета.Элементы, , , 0);
Если Измерения.Количество() <> 2 Или Измерения.Индекс(Класс) <> 0
Или Измерения.Индекс(Номенклатура) <> 1 Или Измерения.Получить(0) <> Класс
Или Измерения.Получить(1) <> Номенклатура Или Измерения.Найти("Класс") <> Класс
Или Измерения.Найти("Номенклатура") <> Номенклатура Тогда
ВызватьИсключение "Вставить должен создать свой Класс на позиции0, не перед первым аргументом";
КонецЕсли;
УстановитьСобственныеМакеты85(Номенклатура, Класс);
Построитель.Выполнить();
ПроверитьСобственныйЗапрос85(Построитель, Свои);
ПервыйКандидат = Новый ТабличныйДокумент;
Построитель.Вывести(ПервыйКандидат);
ПроверитьСобственныйВывод85(ПервыйКандидат, Свои, "КлассПервый");
СнимокПервого = СнимокСвоегоДокумента85(ПервыйКандидат);
Измерения.Сдвинуть(Класс, 1);
Если Измерения.Индекс(Номенклатура) <> 0 Или Измерения.Индекс(Класс) <> 1
Или Измерения.Получить(0) <> Номенклатура Или Измерения.Получить(1) <> Класс Тогда
ВызватьИсключение "Сдвиг должен реально поменять порядок собственных группировок";
КонецЕсли;
Построитель.Выполнить();
ПроверитьСобственныйЗапрос85(Построитель, Свои);
Переставленный = Новый ТабличныйДокумент;
Построитель.Вывести(Переставленный);
ПроверитьСобственныйВывод85(Переставленный, Свои, "КлассВторой");
Если СнимокСвоегоДокумента85(Переставленный) = СнимокПервого Тогда
ВызватьИсключение "После перестановки нужен реально иной native вывод, не только иной индекс";
КонецЕсли;
Измерения.Удалить(Класс);
Если Измерения.Количество() <> 1 Или Измерения.Индекс(Класс) <> -1
Или Измерения.Найти("Класс") <> Неопределено Или Измерения.Найти("НетТакогоИзмерения85") <> Неопределено
Или Измерения.Получить(0) <> Номенклатура Или Измерения.Индекс(Номенклатура) <> 0 Тогда
ВызватьИсключение "После удаления свой Класс отсутствует, собственная Номенклатура остаётся";
КонецЕсли;
Номенклатура.ТипИзмерения = ТипИзмеренияПостроителяОтчета.Иерархия;
Если Номенклатура.ТипИзмерения <> ТипИзмеренияПостроителяОтчета.Иерархия Тогда
ВызватьИсключение "Не прочиталось изменение native типа измерения";
КонецЕсли;
Построитель.Выполнить();
ПроверитьСобственныйЗапрос85(Построитель, Свои);
ВторойКандидат = Новый ТабличныйДокумент;
Построитель.Вывести(ВторойКандидат);
ПроверитьСобственныйВывод85(ВторойКандидат, Свои, "Иерархия");
СвоиПосле = ПрочитатьСобственныеСтроки85();
Для Каждого Пара Из Свои Цикл
ФактПосле = СвоиПосле.Получить(Пара.Ключ);
Если ФактПосле.Ссылка <> Пара.Значение.Ссылка Или ФактПосле.Родитель <> Пара.Значение.Родитель Тогда
ВызватьИсключение "До передачи результата изменились реальные собственные ссылки или их иерархия";
КонецЕсли;
КонецЦикла;
Если СнимокСвоегоДокумента85(ПервыйКандидат) <> СнимокПервого Тогда
ВызватьИсключение "Перестройка не должна изменять ранее выведенный самостоятельный документ";
КонецЕсли;
ПервыйКандидат.ТолькоПросмотр = Истина;
ВторойКандидат.ТолькоПросмотр = Истина;
ИсходныйОтчет85 = ПервыйКандидат;
ИтоговыйОтчет85 = ВторойКандидат;
Состояние85 = "Приняты проверенные свои отчёты: элементы3, группы3, количество10, сумма1650. База не записывалась.";
КонецПроцедуры
Функция ПрочитатьСобственныеСтроки85()
СтендИерархии85.ПроверитьСвойСтенд85();
Ожидания = Новый Соответствие;
Ожидания.Вставить("Корень85", Новый ФиксированнаяСтруктура("Код,Наименование,Родитель,ЭтоГруппа,Класс,Количество,Сумма", "000001", "Корень85", "", Истина, "", 0, 0));
Ожидания.Вставить("Напитки85", Новый ФиксированнаяСтруктура("Код,Наименование,Родитель,ЭтоГруппа,Класс,Количество,Сумма", "000002", "Напитки85", "Корень85", Истина, "", 0, 0));
Ожидания.Вставить("Расходники85", Новый ФиксированнаяСтруктура("Код,Наименование,Родитель,ЭтоГруппа,Класс,Количество,Сумма", "000003", "Расходники85", "Корень85", Истина, "", 0, 0));
Ожидания.Вставить("Альфа85", Новый ФиксированнаяСтруктура("Код,Наименование,Родитель,ЭтоГруппа,Класс,Количество,Сумма", "000004", "Альфа85", "Напитки85", Ложь, "А85", 2, 200));
Ожидания.Вставить("Бета85", Новый ФиксированнаяСтруктура("Код,Наименование,Родитель,ЭтоГруппа,Класс,Количество,Сумма", "000005", "Бета85", "Напитки85", Ложь, "Б85", 3, 450));
Ожидания.Вставить("Гамма85", Новый ФиксированнаяСтруктура("Код,Наименование,Родитель,ЭтоГруппа,Класс,Количество,Сумма", "000006", "Гамма85", "Расходники85", Ложь, "А85", 5, 1000));
Свои = Новый Соответствие;
Выборка = Справочники.УчебнаяНоменклатура85.Выбрать();
Если ТипЗнч(Выборка) <> Тип("СправочникВыборка.УчебнаяНоменклатура85") Тогда
ВызватьИсключение "Нужна настоящая выборка только своего справочника";
КонецЕсли;
Пока Выборка.Следующий() Цикл
Ожидается = Ожидания.Получить(Выборка.Наименование);
Если Ожидается = Неопределено Или Свои.Получить(Выборка.Наименование) <> Неопределено Тогда
ВызватьИсключение "В своём справочнике лишняя или повторяющаяся строка";
КонецЕсли;
Если ТипЗнч(Выборка.Ссылка) <> Тип("СправочникСсылка.УчебнаяНоменклатура85")
Или Выборка.Ссылка.Пустая() Или Выборка.ПометкаУдаления Или Выборка.Предопределенный
Или Выборка.Код <> Ожидается.Код Или Выборка.ЭтоГруппа <> Ожидается.ЭтоГруппа
Или ТипЗнч(Выборка.Класс85) <> Тип("Строка") Или Выборка.Класс85 <> Ожидается.Класс
Или ТипЗнч(Выборка.Количество85) <> Тип("Число") Или Выборка.Количество85 <> Ожидается.Количество
Или ТипЗнч(Выборка.Сумма85) <> Тип("Число") Или Выборка.Сумма85 <> Ожидается.Сумма Тогда
ВызватьИсключение "Фактические данные собственной строки не совпали с ручной учебной подготовкой";
КонецЕсли;
Свои.Вставить(Выборка.Наименование, Новый ФиксированнаяСтруктура("Ссылка,Родитель,Наименование,ЭтоГруппа,Класс,Количество,Сумма",
Выборка.Ссылка, Выборка.Родитель, Выборка.Наименование, Выборка.ЭтоГруппа, Выборка.Класс85, Выборка.Количество85, Выборка.Сумма85));
КонецЦикла;
Если Свои.Количество() <> 6 Тогда
ВызватьИсключение "Нужны ровно6 настоящих собственных ссылок: 3группы и3карточки";
КонецЕсли;
Для Каждого Пара Из Ожидания Цикл
Факт = Свои.Получить(Пара.Ключ);
Если Факт = Неопределено Тогда
ВызватьИсключение "Не найдена собственная строка " + Пара.Ключ;
КонецЕсли;
Если Пара.Значение.Родитель = "" Тогда
Родитель = Справочники.УчебнаяНоменклатура85.ПустаяСсылка();
Иначе
Родитель = Свои.Получить(Пара.Значение.Родитель).Ссылка;
КонецЕсли;
Если Факт.Родитель <> Родитель Тогда
ВызватьИсключение "Фактический родитель не совпал с собственной подготовленной иерархией";
КонецЕсли;
КонецЦикла;
Возврат Новый ФиксированноеСоответствие(Свои);
КонецФункции
Функция СоздатьСобственныйПостроитель85(Свои)
Карточки = Новый Массив;
Для Каждого Пара Из Свои Цикл
Если Не Пара.Значение.ЭтоГруппа Тогда
Карточки.Добавить(Пара.Значение.Ссылка);
КонецЕсли;
КонецЦикла;
Если Карточки.Количество() <> 3 Тогда
ВызватьИсключение "В запрос передаются только3 реально прочитанные свои карточки";
КонецЕсли;
Построитель = Новый ПостроительОтчета;
Построитель.Текст = "ВЫБРАТЬ Н.Ссылка КАК Номенклатура, Н.Класс85 КАК Класс,
| Н.Количество85 КАК Количество, Н.Сумма85 КАК Сумма
|ИЗ Справочник.УчебнаяНоменклатура85 КАК Н
|ГДЕ Н.Ссылка В (&Карточки85) И НЕ Н.ЭтоГруппа И НЕ Н.ПометкаУдаления
|ИТОГИ СУММА(Количество), СУММА(Сумма) ПО ОБЩИЕ
|{ИТОГИ ПО Номенклатура.*, Класс}";
Построитель.Параметры.Вставить("Карточки85", Карточки);
Построитель.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
Построитель.ЗаполнитьНастройки();
Построитель.ВыбранныеПоля.Очистить();
Для Каждого ИмяПоля Из СтрРазделить("Номенклатура,Класс,Количество,Сумма", ",") Цикл
Построитель.ВыбранныеПоля.Добавить(ИмяПоля, ИмяПоля);
КонецЦикла;
Построитель.ИзмеренияСтроки.Очистить();
Построитель.ИзмеренияКолонки.Очистить();
Построитель.АвтоДетальныеЗаписи = Ложь;
Построитель.ВыводитьДетальныеЗаписи = Ложь;
Построитель.ВыводитьОбщиеИтоги = Истина;
Построитель.ВыводитьЗаголовокОтчета = Ложь;
Построитель.ВыводитьШапкуТаблицы = Ложь;
Построитель.ВыводитьПодвалТаблицы = Ложь;
Построитель.ВыводитьПодвалОтчета = Ложь;
Построитель.ОтображатьСостояние = Ложь;
Построитель.ОбрабатыватьПрерываниеПользователя = Ложь;
Построитель.РазмещениеИтоговВСтроках = ТипРазмещенияИтогов.ЗаголовокИПодвал;
Построитель.Макет = СоздатьСобственныйМакет85();
Построитель.МакетОбщихИтогов = "Общие85";
Возврат Построитель;
КонецФункции
Функция СоздатьСобственныйМакет85()
Макет = Новый ТабличныйДокумент;
Макет.Область(1, 1, 6, 4).ШиринаКолонки = 24;
Области = СтрРазделить("Элементы85,Группы85,ПодвалЭлемента85,ПодвалГруппы85,Класс85,Общие85", ",");
Метки = СтрРазделить("ЭЛЕМЕНТ85,ГРУППА85,ПОДВАЛЭЛЕМЕНТА85,ПОДВАЛГРУППЫ85,КЛАСС85,ИТОГ85", ",");
Для Индекс = 0 По Области.Количество() - 1 Цикл
Номер = Индекс + 1;
Макет.Область(Номер, 1, Номер, 4).Имя = Области[Индекс];
Макет.Область(Номер, 1).Текст = Метки[Индекс];
Для Колонка = 2 По 4 Цикл
Ячейка = Макет.Область(Номер, Колонка);
Ячейка.СодержитЗначение = Истина;
Если Колонка = 2 Тогда
Если Индекс < 4 Тогда
Ячейка.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.УчебнаяНоменклатура85");
Ячейка.Параметр = "Номенклатура";
Ячейка.Значение = Справочники.УчебнаяНоменклатура85.ПустаяСсылка();
Иначе
Ячейка.ТипЗначения = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(8));
Ячейка.Значение = "";
Если Индекс = 4 Тогда
Ячейка.Параметр = "Класс";
КонецЕсли;
КонецЕсли;
Иначе
Ячейка.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(12, 0));
Ячейка.Значение = 0;
Ячейка.Параметр = ?(Колонка = 3, "Количество", "Сумма");
КонецЕсли;
Если Не (Индекс = 5 И Колонка = 2) Тогда
Ячейка.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Параметр;
КонецЕсли;
КонецЦикла;
Область = Макет.ПолучитьОбласть(Области[Индекс]);
Если ТипЗнч(Область) <> Тип("ТабличныйДокумент") Или Область.ВысотаТаблицы <> 1
Или Область.ШиринаТаблицы <> 4 Или Область.Область(1, 1).Текст <> Метки[Индекс] Тогда
ВызватьИсключение "Не создана собственная именованная область1×4";
КонецЕсли;
КонецЦикла;
Возврат Макет;
КонецФункции
Процедура УстановитьСобственныеМакеты85(Номенклатура, Класс)
Номенклатура.Макет = "Элементы85";
Номенклатура.МакетИерархии = "Группы85";
Номенклатура.МакетПодвала = "ПодвалЭлемента85";
Номенклатура.МакетПодвалаИерархии = "ПодвалГруппы85";
Класс.Макет = "Класс85";
Класс.МакетПодвала = "Класс85";
Если Номенклатура.Макет <> "Элементы85" Или Номенклатура.МакетИерархии <> "Группы85"
Или Номенклатура.МакетПодвала <> "ПодвалЭлемента85" Или Номенклатура.МакетПодвалаИерархии <> "ПодвалГруппы85"
Или Номенклатура.ТипИзмерения <> ТипИзмеренияПостроителяОтчета.Элементы
Или Класс.Макет <> "Класс85" Или Класс.МакетПодвала <> "Класс85" Тогда
ВызватьИсключение "Native значения своих макетов и первоначального типа измерения не прочитались обратно";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСобственныйЗапрос85(Построитель, Свои)
Результат = Построитель.Результат;
Если ТипЗнч(Результат) <> Тип("РезультатЗапроса") Тогда
ВызватьИсключение "Нужен настоящий результат именно этого собственного построителя";
КонецЕсли;
Строки = Результат.Выгрузить(ОбходРезультатаЗапроса.Прямой);
Если ТипЗнч(Строки) <> Тип("ТаблицаЗначений") Или Строки.Количество() <> 3
Или Строки.Итог("Количество") <> 10 Или Строки.Итог("Сумма") <> 1650 Тогда
ВызватьИсключение "Прямые собственные данные должны давать ровно3 строки и итог10/1650";
КонецЕсли;
Найденные = Новый Соответствие;
Для Каждого СтрокаДанных Из Строки Цикл
Факт = СвояСтрокаПоСсылке85(Свои, СтрокаДанных.Номенклатура);
Если Факт.ЭтоГруппа Или Найденные.Получить(Факт.Ссылка) <> Неопределено
Или СтрокаДанных.Класс <> Факт.Класс Или ТипЗнч(СтрокаДанных.Количество) <> Тип("Число")
Или ТипЗнч(СтрокаДанных.Сумма) <> Тип("Число") Или СтрокаДанных.Количество <> Факт.Количество
Или СтрокаДанных.Сумма <> Факт.Сумма Тогда
ВызватьИсключение "Реальная строка запроса не совпала со своей настоящей карточкой";
КонецЕсли;
Найденные.Вставить(Факт.Ссылка, Истина);
КонецЦикла;
КонецПроцедуры
Функция СвояСтрокаПоСсылке85(Свои, Ссылка)
Если ТипЗнч(Ссылка) <> Тип("СправочникСсылка.УчебнаяНоменклатура85") Тогда
ВызватьИсключение "Ожидалась настоящая ссылка своей metadata, не текст представления";
КонецЕсли;
Для Каждого Пара Из Свои Цикл
Если Пара.Значение.Ссылка = Ссылка Тогда
Возврат Пара.Значение;
КонецЕсли;
КонецЦикла;
ВызватьИсключение "В результат попала ссылка вне своих6 проверенных строк";
КонецФункции
Функция СвойИтогСтроки85(Свои, Факт)
Если Не Факт.ЭтоГруппа Тогда
Возврат Новый ФиксированнаяСтруктура("Количество,Сумма", Факт.Количество, Факт.Сумма);
КонецЕсли;
Количество = 0;
Сумма = 0;
Для Каждого Пара Из Свои Цикл
Карточка = Пара.Значение;
Если Карточка.ЭтоГруппа Тогда
Продолжить;
КонецЕсли;
Родитель = Карточка.Родитель;
Шаг = 0;
Пока Не Родитель.Пустая() Цикл
Шаг = Шаг + 1;
Если Шаг > 3 Тогда
ВызватьИсключение "Иерархия собственной подготовки повреждена или зациклена";
КонецЕсли;
Если Родитель = Факт.Ссылка Тогда
Количество = Количество + Карточка.Количество;
Сумма = Сумма + Карточка.Сумма;
Прервать;
КонецЕсли;
Родитель = СвояСтрокаПоСсылке85(Свои, Родитель).Родитель;
КонецЦикла;
КонецЦикла;
Возврат Новый ФиксированнаяСтруктура("Количество,Сумма", Количество, Сумма);
КонецФункции
Процедура ПроверитьСобственныйВывод85(Документ, Свои, Профиль)
Если Профиль <> "КлассПервый" И Профиль <> "КлассВторой" И Профиль <> "Иерархия" Тогда
ВызватьИсключение "Нет такого собственного профиля вывода";
КонецЕсли;
Если Документ.ВысотаТаблицы < 1 Или Документ.ВысотаТаблицы > 200 Или Документ.ШиринаТаблицы <> 4 Тогда
ВызватьИсключение "Native результат не соответствует маленькому собственному макету";
КонецЕсли;
Заголовки = Новый Соответствие;
Подвалы = Новый Соответствие;
Итогов = 0;
Классы = Новый Соответствие;
Для Номер = 1 По Документ.ВысотаТаблицы Цикл
Метка = Документ.Область(Номер, 1).Текст;
Если Метка = "" Тогда
Для Колонка = 1 По 4 Цикл
ПустаяЯчейка = Документ.Область(Номер, Колонка);
Если ПустаяЯчейка.Текст <> "" Или ПустаяЯчейка.СодержитЗначение Тогда
ВызватьИсключение "Нельзя пропускать неизвестные данные под видом пустой строки оформления";
КонецЕсли;
КонецЦикла;
Продолжить;
КонецЕсли;
Если СтрРазделить("ЭЛЕМЕНТ85,ГРУППА85,ПОДВАЛЭЛЕМЕНТА85,ПОДВАЛГРУППЫ85,КЛАСС85,ИТОГ85", ",").Найти(Метка) = Неопределено Тогда
ВызватьИсключение "В native выводе неизвестная область вместо своего маркера";
КонецЕсли;
ЯчейкаКоличества = Документ.Область(Номер, 3);
ЯчейкаСуммы = Документ.Область(Номер, 4);
Если Не ЯчейкаКоличества.СодержитЗначение Или Не ЯчейкаСуммы.СодержитЗначение Тогда
ВызватьИсключение "Native числовые ячейки не содержат значения; не подставляем ожидаемые числа";
КонецЕсли;
Количество = ЯчейкаКоличества.Значение;
Сумма = ЯчейкаСуммы.Значение;
Если ТипЗнч(Количество) <> Тип("Число") Или ТипЗнч(Сумма) <> Тип("Число") Тогда
ВызватьИсключение "Вычисленные значения нужно читать как числа, не превращать подпись в число";
КонецЕсли;
Если Метка = "ИТОГ85" Тогда
Если Количество <> 10 Или Сумма <> 1650 Тогда
ВызватьИсключение "Фактический общий итог native ячеек не равен10/1650";
КонецЕсли;
Итогов = Итогов + 1;
Продолжить;
КонецЕсли;
ЯчейкаКлюча = Документ.Область(Номер, 2);
Если Не ЯчейкаКлюча.СодержитЗначение Тогда
ВызватьИсключение "Native ключ строки должен быть значением, не угаданной подписью";
КонецЕсли;
Если Метка = "КЛАСС85" Тогда
Класс = ЯчейкаКлюча.Значение;
Если Профиль = "Иерархия" Или ТипЗнч(Класс) <> Тип("Строка") Или (Класс <> "А85" И Класс <> "Б85") Тогда
ВызватьИсключение "После удаления измерения его область не должна выводиться";
КонецЕсли;
Если Профиль = "КлассПервый" Тогда
Верно = (Класс = "А85" И Количество = 7 И Сумма = 1200) Или (Класс = "Б85" И Количество = 3 И Сумма = 450);
Иначе
Верно = (Класс = "А85" И ((Количество = 2 И Сумма = 200) Или (Количество = 5 И Сумма = 1000)))
Или (Класс = "Б85" И Количество = 3 И Сумма = 450);
КонецЕсли;
Если Не Верно Тогда
ВызватьИсключение "Native итог класса не соответствует фактическому уровню собственных группировок";
КонецЕсли;
Классы.Вставить(Класс, Истина);
Продолжить;
КонецЕсли;
Факт = СвояСтрокаПоСсылке85(Свои, ЯчейкаКлюча.Значение);
Группа = Метка = "ГРУППА85" Или Метка = "ПОДВАЛГРУППЫ85";
Если Группа <> Факт.ЭтоГруппа Или (Группа И Профиль <> "Иерархия") Тогда
ВызватьИсключение "Native роль строки не совпала с реально подготовленной собственной группой или элементом";
КонецЕсли;
Ожидается = СвойИтогСтроки85(Свои, Факт);
Если Количество <> Ожидается.Количество Или Сумма <> Ожидается.Сумма Тогда
ВызватьИсключение "Native итог элемента или группы не совпал с суммой своих настоящих потомков";
КонецЕсли;
Если Метка = "ЭЛЕМЕНТ85" Или Метка = "ГРУППА85" Тогда
Набор = Заголовки;
Иначе
Набор = Подвалы;
КонецЕсли;
Если Набор.Получить(Факт.Ссылка) <> Неопределено Тогда
ВызватьИсключение "Повторён собственный заголовок или подвал одной и той же ссылки";
КонецЕсли;
Набор.Вставить(Факт.Ссылка, Истина);
КонецЦикла;
ОжидаетсяСтрок = ?(Профиль = "Иерархия", 6, 3);
Если Итогов = 0 Или Заголовки.Количество() <> ОжидаетсяСтрок Или Подвалы.Количество() <> ОжидаетсяСтрок
Или Классы.Количество() <> ?(Профиль = "Иерархия", 0, 2) Тогда
ВызватьИсключение "Потеряны свои фактические элементы, группы, подвал или общий итог";
КонецЕсли;
КонецПроцедуры
Функция СнимокСвоегоДокумента85(Документ)
Если Документ.ВысотаТаблицы > 200 Или Документ.ШиринаТаблицы <> 4 Тогда
ВызватьИсключение "Снимок разрешён только для маленького собственного вывода";
КонецЕсли;
Части = Новый Массив;
Части.Добавить(Строка(Документ.ВысотаТаблицы));
Для Номер = 1 По Документ.ВысотаТаблицы Цикл
Для Колонка = 1 По 4 Цикл
Ячейка = Документ.Область(Номер, Колонка);
Части.Добавить(Ячейка.Текст);
Если Ячейка.СодержитЗначение Тогда
Части.Добавить(Строка(ТипЗнч(Ячейка.Значение)));
Части.Добавить(Строка(Ячейка.Значение));
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат СтрСоединить(Части, Символы.ПС);
КонецФункции
#КонецЕслиПолный общий модуль допуска собственного стенда
ОбщиеМодули.СтендИерархии85.Модуль
Клиент обычного приложения; КлиентОбычноеПриложение=Да, все остальные контексты=Нет, Глобальный=Нет, Привилегированный=Нет
Процедура ПроверитьСвойСтенд85() Экспорт
Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1C85_OwnHierarchyLab\6a7df6aa-5e73-41b5-bda1-8f9c86ee4164\Base"";"
Или ИмяПользователя() <> "Иерархия85Ученик" Тогда
ВызватьИсключение "Нужен только свой отдельный файловый стенд и собственный учебный пользователь";
КонецЕсли;
Если Метаданные.Справочники.Количество() <> 1 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.Обработки.Количество() <> 1 Или Метаданные.ОбщиеМодули.Количество() <> 1 Тогда
ВызватьИсключение "Разрешены только своя обработка и собственный общий модуль стенда";
КонецЕсли;
Обработка = Метаданные.Обработки.Найти("УчебныйИерархическийОтчет85");
Если Обработка = Неопределено Или Метаданные.ОбщиеМодули.Найти("СтендИерархии85") = Неопределено Тогда
ВызватьИсключение "Нет точно подготовленных собственной обработки и общего модуля";
КонецЕсли;
Если Обработка.Формы.Количество() <> 1 Или Обработка.Формы.Найти("Основная") = Неопределено Тогда
ВызватьИсключение "Нужна ровно своя обычная форма Основная";
КонецЕсли;
Описание = Метаданные.Справочники.Найти("УчебнаяНоменклатура85");
Если Описание = Неопределено Тогда
ВызватьИсключение "Нет собственного иерархического справочника";
КонецЕсли;
Если Не Описание.Иерархический Или Описание.ВидИерархии <> Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов
Или Описание.Владельцы.Количество() <> 0 Или Описание.Реквизиты.Количество() <> 3
Или Описание.ТабличныеЧасти.Количество() <> 0 Или Описание.ДлинаКода <> 6
Или Описание.ДлинаНаименования <> 40 Или Описание.ТипКода <> Метаданные.СвойстваОбъектов.ТипКодаСправочника.Строка Тогда
ВызватьИсключение "Метаданные справочника не совпали с собственной учебной схемой";
КонецЕсли;
Для Каждого ИмяРеквизита Из СтрРазделить("Класс85,Количество85,Сумма85", ",") Цикл
Реквизит = Описание.Реквизиты.Найти(ИмяРеквизита);
Если Реквизит = Неопределено Тогда
ВызватьИсключение "Отсутствует собственный реквизит " + ИмяРеквизита;
КонецЕсли;
Если Реквизит.Использование <> Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента Тогда
ВызватьИсключение "Все3 собственных реквизита должны существовать у групп и элементов";
КонецЕсли;
Типы = Реквизит.Тип.Типы();
Если Типы.Количество() <> 1 Тогда
ВызватьИсключение "Реквизит должен иметь ровно один подготовленный тип";
КонецЕсли;
Если ИмяРеквизита = "Класс85" Тогда
Если Типы[0] <> Тип("Строка") Или Реквизит.Тип.КвалификаторыСтроки.Длина <> 8 Тогда
ВызватьИсключение "Класс85 должен иметь тип Строка8";
КонецЕсли;
Иначе
Если Типы[0] <> Тип("Число") Или Реквизит.Тип.КвалификаторыЧисла.Разрядность <> 12
Или Реквизит.Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти <> 0 Тогда
ВызватьИсключение "Числовые реквизиты должны иметь тип Число(12,0)";
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыРазбор по шагам
Guard сначала сверяет путь, пользователя, состав своей конфигурации, метаданные3 реквизитов, расширения и отсутствие активной транзакции. Затем Выбрать() без отбора получает все6 строк своего каталога. Любая лишняя/дублированная/помеченная строка, неправильное число/класс/родитель означает отказ ДО запроса.
Свои — неизменяемый снимок фактических6 ссылок и значений. Ожидания задают только условия допуска стенда; итоговый отчёт берёт Количество85/Сумма85 из реальных карточек запросом. В параметр Карточки85 передаются только3 фактически прочитанные ссылки элементов, а не строковые идентификаторы.
ЗаполнитьНастройки работает с собственным текстом запроса и расширением {ИТОГИ ПО Номенклатура.*, Класс}. ИТОГИ суммируют оба ресурса; звёздочка разрешает доступные реквизиты ссылки при настройке. Фиксированного порядка native результата здесь не обещаем.
Добавить создаёт Номенклатуру. Вставить("Класс", "Класс", Элементы, , , 0) реально вставляет Класс первым: обязательная Позиция — ШЕСТОЙ слот. Найти обращается к имени измерения, Получить — к индексу0/1, Индекс получает само измерение и проверяет его принадлежность коллекции.
Четыре RW свойства Номенклатуры получают свои существующие имена областей и читаются обратно. Вначале ТипИзмерения=Элементы: группы не выводятся. РазмещениеИтоговВСтроках=ЗаголовокИПодвал включает оба вида областей. Детальные записи отключены: элемент здесь является измерением, а не произвольно добавленной строкой.
Первый native Вывести формирует самостоятельный кандидат Класс→Номенклатура. Проверяем фактические3 прямые строки запроса и3 ссылки элементов в заголовках/подвалах, значения каждой карточки, итоги классов А85=7/1200 и Б85=3/450, реальные числовые общие итоги10/1650.
Сдвинуть(Класс, 1) меняет коллекцию на Номенклатура→Класс. Снова Выполнить/Вывести, readback индексов и другой текстово-типовой снимок результата. У класса теперь сумма отдельной вышестоящей карточки: А85 даёт2/200 или5/1000, Б85=3/450. Контрольный документ остаётся в памяти, не сохраняется в файле/базе.
Удалить принимает настоящий элемент Класс, не его имя и не индекс. После удаления Найти возвращает Неопределено, Индекс старого элемента=-1, Количество=1. Оставшаяся Номенклатура — тот же реальный элемент. Честная отрицательная ветвь отсутствующего имени не считается ошибкой.
ТипИзмерения меняется на Иерархия и читается обратно. Новый native вывод должен реально содержать группы и элементы, каждый со своим заголовком и подвалом. Итог группы вычисляется для проверки из фактических собственных карточек проходом по реальным Родитель-ссылкам с ограничением длины; это не фиктивный числовой getter.
Все3 вывода проходят проверки до присваивания реквизитам формы. Повторное чтение допускает только тот же состав/значения и те же реальные6 ссылок/родителей, а не новые карточки с совпавшими именами. Ранее сформированный первый кандидат также должен сохранить снимок. Если что-то не совпало, показанные ранее два документа не присваиваются заново. Два последних присваивания UI не объявляются атомарной операцией/транзакцией; сбой самой передачи в форму требует отдельного разбора.
Как проверить результат
Начальная проверка допускает ровно6 своих строк: 3 группы и3 карточки. Реквизиты: один строковый и два numeric, все точных типов/квалификаторов. Попробуйте вручную в своём стенде изменить родителя Бета85, количество или добавить седьмую строку: на следующем запуске guard/fixture проверка должна отказать до запроса. Затем вручную восстановите ровно указанную собственную подготовку.
Слева фактические элементы Альфа85=2/200, Бета85=3/450, Гамма85=5/1000 и классы А85=7/1200, Б85=3/450. Группы Корень85/Напитки85/Расходники85 как измерения элементов слева не показываются. Справа тип Иерархия должен вывести все6 реальных ссылок.
Справа обе области группы должны дать Напитки85=5/650, Расходники85=5/1000, Корень85=10/1650. Оба ресурса читаются через Значение настоящих numeric ячеек, а не из текста и не из EXPECTATION_CODE. Порядок строк/номера строк заранее не фиксируются.
После Сдвинуть свой контрольный вывод должен отличаться от первого: суммы классов становятся вложенными под элементом. После Удалить области КЛАСС85 в итоговой иерархии должны отсутствовать. Исходный отдельный документ остаётся прежним.
Индекс удалённого своего Класс=-1, Найти("Класс") и Найти("НетТакогоИзмерения85")=Неопределено. Это проверка реального lifecycle измерения, не обращение к неизвестному объекту.
Измените имя своей области или тип numeric ячейки в КОПИИ учебного кода внутри своего отдельного стенда: построение/валидация должно честно отказать. Не включайте СодержитЗначение и не вставляйте10/1650 после вывода, чтобы скрыть несовпадение.
Автором выполнены только статические source/native проверки. Ожидаемые числа вычислены из явно описанной подготовки; фактическое поведение renderer/отображения на платформе8.5.1.1343 не запускалось. Все runtime контрольные шаги выполняет пользователь только на своём стенде.
Ожидаемый результат
Подготовлен полный самостоятельный учебный маршрут11 API: настоящая перестановка/удаление измерений, четыре разные области измерения и проверяемый иерархический отчёт на своих6 ссылках. Авторство и static/native проверка — не подтверждение runtime.
На что обратить внимание
Это старый ПостроительОтчета, не КомпоновщикМакета/Процессор СКД и не диаграмма. Нельзя переносить его обычную форму в thin/web или вставлять native ordinary сигнатуры в managed форму.
Форма.ПриОткрытии() не имеет Отказ и не позволяет отменить открытие формы; ошибка допуска не выдаётся за закрытие окна. Обработчик прекращает дальнейшее чтение/формирование исключением. У обычной Кнопка.Нажатие() первый Элемент появляется именно из ordinary расширения controls в форме; не копируйте0 payload как готовую сигнатуру обработчика на форме.
Запрос читает данные, не пишет их. Любые manualfixture изменения принадлежат только отдельному стенду; урок не подключается к предоставленным УТ/КА2/УНФ конфигурациям. История данных/предопределённые строки/автоматические обработчики выключены в подготовке.
Вставить имеет6 слотов с обязательным последним Позиция. Сдвинуть принимает ИзмерениеПостроителяОтчета плюс число, Удалить — это же измерение. Не переносите сигнатуры других коллекций с индексом первым.
Заголовок/подвал группы нельзя выдавать за сумму её единственного прямого реквизита0: собственные3 группы имеют0, их native итог должен быть суммой реальных элементов-потомков.
ИТОГИ/Иерархия не означают, что каждая строка всегда в фиксированной позиции. Проверки анализируют собственные маркеры и реальные ссылки/числа, не рисуют таблицу результата сами.
Если native вывод имеет другой shape, отсутствие подвала, пустую/чужую ссылку либо текст вместо Число, код отказывает, а не маскирует ошибку. Не обещаем, что статические тесты доказывают реальную работу renderer.
МакетыУровней и МакетыПодваловУровней НЕ цели урока: их семантика не подтверждена простым чтением readonly массива. Не добавляйте их в PRIMARY только ради покрытия.
Не сохраним результаты в файл/хранилище, не изменяем источники, не запускаем транзакции, внешние компоненты, сетевые соединения или произвольные вычисления. Не ловим исключение и не выводим ложный успех.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.