Тип: ПоляНабораДанныхМакетаКомпоновкиДанных. Описания полей набора данных.
Полное описание, параметры и ограничения
ВложенныйНаборДанныхМакетаКомпоновкиДанных.Поля (DataCompositionTemplateNestedDataSet.Fields)
ВложенныйНаборДанныхМакетаКомпоновкиДанных (DataCompositionTemplateNestedDataSet)
Поля (Fields)
Доступен, начиная с версии 8.2.
Использование:
Только чтение.
Описание:
Тип: ПоляНабораДанныхМакетаКомпоновкиДанных.
Описания полей набора данных.
Доступность:
Сервер, внешнее соединение.
Использование в версии:
Доступен, начиная с версии 8.2.
Методическая информация
Практические примеры
Вложенные позиции заказов: настоящий макет СКД, поля и проверенный вывод
На собственной модели O1/O2 получаем скомпилированный вложенный набор, исследуем его настоящие свойства и проверяем принадлежность трёх позиций заказам, а не только сумму.
Где и как запускать
Полный серверный общий модуль УчебныеВложенныеМакеты85 собственной новой базы; отдельный полный модуль управляемой формы ниже.
Подготовка
Только НОВАЯ пустая учебная база 8.5.1.1343: корневое Имя=УчебныеВложенныеМакеты85, совместимость НеИспользовать, управляемое приложение. Не копия рабочей КА2/УНФ/УТ/БП. Без бизнес-метаданных, расширений, подписок, заданий и внешних действий. Здесь база не создаётся и пример не выполняется: runtimeVerifiedScenarios=0.
Создайте общий модуль УчебныеВложенныеМакеты85: Сервер=Да, Клиент=Нет, Вызов сервера=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте целиком основной код ОДНОГО урока. Он включает создание всех данных, защиту стенда и проверку результата; неизвестных входных объектов нет.
В своей новой конфигурации создайте обработку УчебныйРазборПозиций85 → управляемая форма Пульт → команда Выполнить с действием Выполнить и кнопкой. Отдельный полный модуль формы ниже. Выполните F7 и обновление только собственной учебной базы перед будущим отдельно разрешённым тестом.
Стенд создаёт в памяти таблицу Заказы85: O1 содержит свою таблицу A01/3 и B02/5, O2 — другую таблицу C03/9. Никаких документов заказов создавать не нужно. Колонка Позиции85 без ограничения типа; её фактические значения и все вложенные примитивные колонки полностью проверяются.
В исходной схеме четыре описания в одном каталоге: Номер85, вложенное поле Позиции85, Позиции85.Код, Позиции85.Количество. У поля исходной схемы нет собственного каталога Поля. Настройки выбирают только номер заказа и два вложенных значения, структура — детальные записи без таблиц и диаграмм.
Макет компилируется генератором для коллекции значений. Настоящие внешние данные передаются ВТОРЫМ аргументом Процессор.Инициализировать, не третьим аргументом расшифровки. Таблицы и макеты не возвращаются в тонкий клиент; весь опыт остаётся серверным.
В редакторском уроке XDTO переносит весь собственный макет в строку памяти и читает её обратно. Файлы, архивы и резервные копии не создаются. Неполный черновой каталог с именами отсутствующих внешних полей НИКОГДА не подаётся в процессор; исполняются только исходный и полностью восстановленный макеты.
Для будущего разрешённого теста поставьте серверные точки останова в ПроверитьСвоиВложенныеОпределения и ПроверитьСвойВыводПозиций. Статические проверки не подтверждают реальную компиляцию макета, его XDTO round-trip или фактическое разворачивание вложенных строк на платформе.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
Если ПривилегированныйРежим() Тогда
ВызватьИсключение "Привилегированный режим не нужен";
КонецЕсли;
Стенд = СоздатьСвойСтендПозиций();
ПроверитьСвойСтендПозиций(Стенд, Истина, "Позиции заказа", 5);
Схема = Стенд.Схема;
Настройки = Схема.НастройкиПоУмолчанию;
Для Каждого Путь Из СтрРазделить("Номер85,Позиции85.Код,Позиции85.Количество", ",") Цикл
Выбранное = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
Выбранное.Поле = Новый ПолеКомпоновкиДанных(Путь);
Выбранное.Использование = Истина;
КонецЦикла;
Детали = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Детали.Использование = Истина;
ВыборДеталей = Детали.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
ВыборДеталей.Использование = Истина;
Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = Компоновщик.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
Вложенный = ПроверитьСвоиВложенныеОпределения(Макет);
ПроверитьСвойВыводПозиций(Макет, Стенд.ВнешниеДанные);
КонецПроцедуры
Функция СвойТипКоличества()
Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный));
КонецФункции
Процедура ПроверитьСвойТип(Описание, ИмяТипа)
Если ТипЗнч(Описание) <> Тип("ОписаниеТипов") Тогда
ВызватьИсключение "Нужно собственное описание типа";
КонецЕсли;
ПолныеТипы = Описание.Типы();
Если ПолныеТипы.Количество() <> 1 Или ПолныеТипы[0] <> Тип(ИмяТипа) Тогда
ВызватьИсключение "Не совпал полный набор допустимых примитивных типов";
КонецЕсли;
Если ИмяТипа = "Число" Тогда
Квалификаторы = Описание.КвалификаторыЧисла;
Если ТипЗнч(Квалификаторы) <> Тип("КвалификаторыЧисла") Или Квалификаторы.Разрядность <> 10
Или Квалификаторы.РазрядностьДробнойЧасти <> 0
Или Квалификаторы.ДопустимыйЗнак <> ДопустимыйЗнак.Неотрицательный Тогда
ВызватьИсключение "Количество должно быть неотрицательным целым числом до десяти разрядов";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ЗаполнитьСвоиОписанияПолей(Набор)
Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Или Набор.Поля.Количество() <> 0 Тогда
ВызватьИсключение "Заполняется только пустой каталог своего объектного набора";
КонецЕсли;
Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно собственное простое поле номера";
КонецЕсли;
Поле.Поле = "Номер85";
Поле.ПутьКДанным = "Номер85";
Поле.ТипЗначения = Новый ОписаниеТипов("Строка");
ВложенноеПоле = Набор.Поля.Добавить(Тип("ВложенныйНаборДанныхСхемыКомпоновкиДанных"));
Если ТипЗнч(ВложенноеПоле) <> Тип("ВложенныйНаборДанныхСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно описание настоящего поля с вложенными данными";
КонецЕсли;
ВложенноеПоле.Поле = "Позиции85";
ВложенноеПоле.ПутьКДанным = "Позиции85";
ВложенноеПоле.Заголовок = "Позиции заказа";
Имена = СтрРазделить("Код,Количество", ",");
Для Индекс = 0 По 1 Цикл
Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно собственное простое поле внутри позиций";
КонецЕсли;
Поле.Поле = ВложенноеПоле.ПутьКДанным + "." + Имена[Индекс];
Поле.ПутьКДанным = ВложенноеПоле.ПутьКДанным + "." + Имена[Индекс];
Если Индекс = 0 Тогда
Поле.ТипЗначения = Новый ОписаниеТипов("Строка");
Иначе
Поле.ТипЗначения = СвойТипКоличества();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция СоздатьСвойСтендПозиций()
Заказы = Новый ТаблицаЗначений;
Заказы.Колонки.Добавить("Номер85", Новый ОписаниеТипов("Строка"));
Заказы.Колонки.Добавить("Позиции85");
Для ИндексЗаказа = 0 По 1 Цикл
Позиции = Новый ТаблицаЗначений;
Позиции.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
Позиции.Колонки.Добавить("Количество", СвойТипКоличества());
СтрокаПозиции = Позиции.Добавить();
Если ИндексЗаказа = 0 Тогда
СтрокаПозиции.Код = "A01";
СтрокаПозиции.Количество = 3;
СтрокаПозиции = Позиции.Добавить();
СтрокаПозиции.Код = "B02";
СтрокаПозиции.Количество = 5;
Иначе
СтрокаПозиции.Код = "C03";
СтрокаПозиции.Количество = 9;
КонецЕсли;
СтрокаЗаказа = Заказы.Добавить();
Если ИндексЗаказа = 0 Тогда
СтрокаЗаказа.Номер85 = "O1";
Иначе
СтрокаЗаказа.Номер85 = "O2";
КонецЕсли;
СтрокаЗаказа.Позиции85 = Позиции;
КонецЦикла;
Схема = Новый СхемаКомпоновкиДанных;
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "СвоиЗаказы85";
Источник.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен собственный объектный набор";
КонецЕсли;
Набор.Имя = "Заказы85";
Набор.ИмяОбъекта = "Заказы85";
Набор.ИсточникДанных = "СвоиЗаказы85";
ЗаполнитьСвоиОписанияПолей(Набор);
ВнешниеДанные = Новый Структура;
ВнешниеДанные.Вставить("Заказы85", Заказы);
Стенд = Новый Структура;
Стенд.Вставить("Схема", Схема);
Стенд.Вставить("ВнешниеДанные", ВнешниеДанные);
Возврат Стенд;
КонецФункции
Процедура ПроверитьСвойСтендПозиций(Стенд, ЕстьПоля, Заголовок, КоличествоB02)
Если ТипЗнч(Стенд) <> Тип("Структура") Или Стенд.Количество() <> 2 Тогда
ВызватьИсключение "Нужна собственная структура схемы и внешних данных";
КонецЕсли;
Схема = Неопределено;
ВнешниеДанные = Неопределено;
Если Не Стенд.Свойство("Схема", Схема) Или Не Стенд.Свойство("ВнешниеДанные", ВнешниеДанные) Тогда
ВызватьИсключение "Не совпали оба ключа собственного стенда";
КонецЕсли;
Если ТипЗнч(Схема) <> Тип("СхемаКомпоновкиДанных") Или Схема.ИсточникиДанных.Количество() <> 1
Или Схема.НаборыДанных.Количество() <> 1 Тогда
ВызватьИсключение "Нужен единственный собственный источник и объектный набор";
КонецЕсли;
Если ТипЗнч(ВнешниеДанные) <> Тип("Структура") Или ВнешниеДанные.Количество() <> 1 Тогда
ВызватьИсключение "Нужен единственный собственный внешний объект";
КонецЕсли;
Заказы = Неопределено;
Если Не ВнешниеДанные.Свойство("Заказы85", Заказы) Тогда
ВызватьИсключение "Не найдена настоящая собственная таблица заказов";
КонецЕсли;
Если ТипЗнч(Заказы) <> Тип("ТаблицаЗначений") Или Заказы.Количество() <> 2 Или Заказы.Колонки.Количество() <> 2 Тогда
ВызватьИсключение "Нужно ровно два заказа и две колонки";
КонецЕсли;
Колонка = Заказы.Колонки.Получить(0);
Если ТипЗнч(Колонка) <> Тип("КолонкаТаблицыЗначений") Или Колонка.Имя <> "Номер85" Тогда
ВызватьИсключение "Не совпала первая колонка заказа";
КонецЕсли;
ПроверитьСвойТип(Колонка.ТипЗначения, "Строка");
Колонка = Заказы.Колонки.Получить(1);
Если ТипЗнч(Колонка) <> Тип("КолонкаТаблицыЗначений") Или Колонка.Имя <> "Позиции85"
Или ТипЗнч(Колонка.ТипЗначения) <> Тип("ОписаниеТипов") Тогда
ВызватьИсключение "Не совпала собственная колонка вложенных значений";
КонецЕсли;
Для ИндексЗаказа = 0 По 1 Цикл
СтрокаЗаказа = Заказы.Получить(ИндексЗаказа);
Если ТипЗнч(СтрокаЗаказа) <> Тип("СтрокаТаблицыЗначений") Или ТипЗнч(СтрокаЗаказа.Номер85) <> Тип("Строка") Тогда
ВызватьИсключение "Не совпал тип строки заказа или номера";
КонецЕсли;
Если ИндексЗаказа = 0 Тогда
Номер = "O1";
ЧислоПозиций = 2;
Иначе
Номер = "O2";
ЧислоПозиций = 1;
КонецЕсли;
Если СтрокаЗаказа.Номер85 <> Номер Тогда
ВызватьИсключение "Не совпал полный номер заказа";
КонецЕсли;
Позиции = СтрокаЗаказа.Позиции85;
Если ТипЗнч(Позиции) <> Тип("ТаблицаЗначений") Или Позиции.Количество() <> ЧислоПозиций
Или Позиции.Колонки.Количество() <> 2 Тогда
ВызватьИсключение "Ячейка должна содержать настоящую собственную таблицу позиций";
КонецЕсли;
Имена = СтрРазделить("Код,Количество", ",");
Типы = СтрРазделить("Строка,Число", ",");
Для Индекс = 0 По 1 Цикл
Колонка = Позиции.Колонки.Получить(Индекс);
Если ТипЗнч(Колонка) <> Тип("КолонкаТаблицыЗначений") Или Колонка.Имя <> Имена[Индекс] Тогда
ВызватьИсключение "Не совпали порядок и имена обеих вложенных колонок";
КонецЕсли;
ПроверитьСвойТип(Колонка.ТипЗначения, Типы[Индекс]);
КонецЦикла;
Для Индекс = 0 По ЧислоПозиций - 1 Цикл
СтрокаПозиции = Позиции.Получить(Индекс);
Если ИндексЗаказа = 1 Тогда
Код = "C03";
Количество = 9;
ИначеЕсли Индекс = 0 Тогда
Код = "A01";
Количество = 3;
Иначе
Код = "B02";
Количество = КоличествоB02;
КонецЕсли;
Если ТипЗнч(СтрокаПозиции) <> Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(СтрокаПозиции.Код) <> Тип("Строка") Или СтрокаПозиции.Код <> Код
Или ТипЗнч(СтрокаПозиции.Количество) <> Тип("Число") Или СтрокаПозиции.Количество <> Количество Тогда
ВызватьИсключение "Не совпали все вложенные ячейки, коды, количества и их типы";
КонецЕсли;
КонецЦикла;
КонецЦикла;
Источник = Схема.ИсточникиДанных.Получить(0);
Если ТипЗнч(Источник) <> Тип("ИсточникДанныхСхемыКомпоновкиДанных")
Или Источник.Имя <> "СвоиЗаказы85" Или Источник.ТипИсточникаДанных <> "Local" Тогда
ВызватьИсключение "Не совпал собственный логический источник";
КонецЕсли;
Набор = Схема.НаборыДанных.Получить(0);
Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Или Набор.Имя <> "Заказы85"
Или Набор.ИмяОбъекта <> "Заказы85" Или Набор.ИсточникДанных <> "СвоиЗаказы85"
Или Схема.НаборыДанных.Найти("Заказы85") <> Набор
Или ТипЗнч(Набор.Поля) <> Тип("ПоляНабораДанныхСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Не совпала связь своего набора с реальным внешним объектом";
КонецЕсли;
ЧислоПолей = 0;
Если ЕстьПоля Тогда
ЧислоПолей = 4;
КонецЕсли;
Если Набор.Поля.Количество() <> ЧислоПолей Тогда
ВызватьИсключение "Не совпал полный размер своего каталога описаний";
КонецЕсли;
Если Не ЕстьПоля Тогда
Возврат;
КонецЕсли;
ВложенноеПоле = Набор.Поля.Получить(1);
Если ТипЗнч(ВложенноеПоле) <> Тип("ВложенныйНаборДанныхСхемыКомпоновкиДанных")
Или ТипЗнч(ВложенноеПоле.Поле) <> Тип("Строка") Или ВложенноеПоле.Поле <> "Позиции85"
Или ТипЗнч(ВложенноеПоле.ПутьКДанным) <> Тип("Строка") Или ВложенноеПоле.ПутьКДанным <> "Позиции85"
Или ТипЗнч(ВложенноеПоле.Заголовок) <> Тип("Строка") Или ВложенноеПоле.Заголовок <> Заголовок Тогда
ВызватьИсключение "Не совпали тип, реальное исходное поле, полный путь и заголовок вложенных данных";
КонецЕсли;
Пути = СтрРазделить("Номер85,Позиции85.Код,Позиции85.Количество", ",");
Типы = СтрРазделить("Строка,Строка,Число", ",");
Для Индекс = 0 По 2 Цикл
ИндексПоля = Индекс;
Если Индекс > 0 Тогда
ИндексПоля = Индекс + 1;
КонецЕсли;
Поле = Набор.Поля.Получить(ИндексПоля);
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")
Или Поле.Поле <> Пути[Индекс] Или Поле.ПутьКДанным <> Пути[Индекс] Тогда
ВызватьИсключение "Не совпали все простые исходные поля и полные составные пути";
КонецЕсли;
ПроверитьСвойТип(Поле.ТипЗначения, Типы[Индекс]);
КонецЦикла;
КонецПроцедуры
Функция ПроверитьСвоиВложенныеОпределения(Макет)
Если ТипЗнч(Макет) <> Тип("МакетКомпоновкиДанных") Или Макет.НаборыДанных.Количество() <> 1 Тогда
ВызватьИсключение "В своей модели нужен один полный настоящий макет и один корневой набор";
КонецЕсли;
Родитель = Макет.НаборыДанных.Получить(0);
Если ТипЗнч(Родитель) <> Тип("НаборДанныхОбъектМакетаКомпоновкиДанных") Или Родитель.ИмяОбъекта <> "Заказы85" Тогда
ВызватьИсключение "Нужен настоящий объектный набор для своего внешнего ключа Заказы85";
КонецЕсли;
Каталог = Родитель.ВложенныеНаборыДанных;
Если ТипЗнч(Каталог) <> Тип("ВложенныеНаборыДанныхМакетаКомпоновкиДанных") Или Каталог.Количество() <> 1 Тогда
ВызватьИсключение "Нужен один настоящий вложенный набор, не вложенная схема или поле исходной схемы";
КонецЕсли;
Вложенный = Каталог.Получить(0);
Если ТипЗнч(Вложенный) <> Тип("ВложенныйНаборДанныхМакетаКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен настоящий скомпилированный вложенный набор";
КонецЕсли;
Найденный = Каталог.Найти("Позиции85");
Если Найденный = Неопределено Тогда
ВызватьИсключение "Вложенный набор должен извлекаться из своего поля Позиции85";
КонецЕсли;
Если Найденный <> Вложенный Или Вложенный.Имя <> "Позиции85" Или Вложенный.ПутьКДанным = "" Тогда
ВызватьИсключение "Имя, фактический путь и найденный элемент должны соответствовать своему вложенному набору";
КонецЕсли;
Если Каталог.Найти("НетТакогоВложенного85") <> Неопределено Тогда
ВызватьИсключение "Отсутствующее имя должно дать Неопределено, не первый элемент";
КонецЕсли;
Сообщить("Вложенное поле=" + Вложенный.Имя + "; путь=" + Вложенный.ПутьКДанным + "; отбор=" + Вложенный.Отбор);
Поля = Вложенный.Поля;
Если ТипЗнч(Поля) <> Тип("ПоляНабораДанныхМакетаКомпоновкиДанных") Или Поля.Количество() < 2 Тогда
ВызватьИсключение "Нужен настоящий readonly-каталог как минимум двух выбранных вложенных полей";
КонецЕсли;
Для Номер = 0 По Поля.Количество() - 1 Цикл
Поле = Поля.Получить(Номер);
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхМакетаКомпоновкиДанных") Или Поле.Имя = "" Или Поле.ПутьКДанным = "" Тогда
ВызватьИсключение "Внутри каталога нужны реальные описания полей с именем и путём";
КонецЕсли;
Если Поля.Найти(Поле.Имя) <> Поле Тогда
ВызватьИсключение "Поиск должен возвращать то же настоящее поле";
КонецЕсли;
Сообщить("Поле вложенного набора=" + Поле.Имя + "; путь=" + Поле.ПутьКДанным);
КонецЦикла;
Возврат Вложенный;
КонецФункции
Функция НайтиСвоюКолонкуПоЗначениям(Таблица, Вариант)
Если Вариант <> "Заказ" И Вариант <> "Код" И Вариант <> "Количество" Тогда
ВызватьИсключение "У своей узкой модели только три непересекающихся области значений";
КонецЕсли;
Найденная = Неопределено;
Для Каждого Колонка Из Таблица.Колонки Цикл
Подходит = Истина;
Для Каждого СтрокаРезультата Из Таблица Цикл
Значение = СтрокаРезультата[Колонка.Имя];
Если Вариант = "Заказ" Тогда
Подходит = Подходит И ТипЗнч(Значение) = Тип("Строка") И (Значение = "O1" Или Значение = "O2");
ИначеЕсли Вариант = "Код" Тогда
Подходит = Подходит И ТипЗнч(Значение) = Тип("Строка") И (Значение = "A01" Или Значение = "B02" Или Значение = "C03");
Иначе
Подходит = Подходит И ТипЗнч(Значение) = Тип("Число") И (Значение = 3 Или Значение = 5 Или Значение = 9);
КонецЕсли;
КонецЦикла;
Если Подходит Тогда
Если Найденная <> Неопределено Тогда
ВызватьИсключение "Роль колонки не должна определяться неоднозначно";
КонецЕсли;
Найденная = Колонка;
КонецЕсли;
КонецЦикла;
Если Найденная = Неопределено Тогда
ВызватьИсключение "В настоящем выводе не найдена колонка своей роли " + Вариант;
КонецЕсли;
Возврат Найденная;
КонецФункции
Процедура ПроверитьСвойВыводПозиций(Макет, ВнешниеДанные)
Процессор = Новый ПроцессорКомпоновкиДанных;
Процессор.Инициализировать(Макет, ВнешниеДанные);
Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
Приемник = Новый ТаблицаЗначений;
Вывод.ОтображатьПроцентВывода = Ложь;
Вывод.УстановитьОбъект(Приемник);
Результат = Вывод.Вывести(Процессор, Ложь);
Если ТипЗнч(Результат) <> Тип("ТаблицаЗначений") Или Результат.Количество() <> 3 Или Результат.Колонки.Количество() <> 3 Тогда
ВызватьИсключение "Настоящий детальный вывод должен дать три позиции и три колонки";
КонецЕсли;
КолонкаЗаказа = НайтиСвоюКолонкуПоЗначениям(Результат, "Заказ");
КолонкаКода = НайтиСвоюКолонкуПоЗначениям(Результат, "Код");
КолонкаКоличества = НайтиСвоюКолонкуПоЗначениям(Результат, "Количество");
Если КолонкаЗаказа = КолонкаКода Или КолонкаЗаказа = КолонкаКоличества Или КолонкаКода = КолонкаКоличества Тогда
ВызватьИсключение "Три разные роли должны иметь три разные настоящие колонки";
КонецЕсли;
ЕстьA01 = Ложь;
ЕстьB02 = Ложь;
ЕстьC03 = Ложь;
Итог = 0;
Для Каждого СтрокаРезультата Из Результат Цикл
Заказ = СтрокаРезультата[КолонкаЗаказа.Имя];
Код = СтрокаРезультата[КолонкаКода.Имя];
Количество = СтрокаРезультата[КолонкаКоличества.Имя];
Если Код = "A01" Тогда
Если ЕстьA01 Или Заказ <> "O1" Или Количество <> 3 Тогда
ВызватьИсключение "Нужна ровно одна позиция O1/A01/3";
КонецЕсли;
ЕстьA01 = Истина;
ИначеЕсли Код = "B02" Тогда
Если ЕстьB02 Или Заказ <> "O1" Или Количество <> 5 Тогда
ВызватьИсключение "Нужна ровно одна позиция O1/B02/5";
КонецЕсли;
ЕстьB02 = Истина;
ИначеЕсли Код = "C03" Тогда
Если ЕстьC03 Или Заказ <> "O2" Или Количество <> 9 Тогда
ВызватьИсключение "Нужна ровно одна позиция O2/C03/9";
КонецЕсли;
ЕстьC03 = Истина;
Иначе
ВызватьИсключение "Лишняя позиция в настоящем выводе";
КонецЕсли;
Итог = Итог + Количество;
Сообщить(Заказ + "/" + Код + "/" + Строка(Количество));
КонецЦикла;
Если Не ЕстьA01 Или Не ЕстьB02 Или Не ЕстьC03 Или Итог <> 17 Или Результат.Итог(КолонкаКоличества.Имя) <> 17 Тогда
ВызватьИсключение "Все три собственные позиции и итог количества 17 должны сохраниться";
КонецЕсли;
Сообщить("Реальные три позиции связаны со своими заказами, количество=17.");
КонецПроцедуры
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыУчебныйРазборПозиций85.Пульт
УчебныеВложенныеМакеты85 → Обработки → УчебныйРазборПозиций85 → Формы → Пульт → Модуль
Полный модуль собственной управляемой формы Пульт; не выполнялся.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныеВложенныеМакеты85.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
СоздатьСвойСтендПозиций формирует два отдельных вложенных объекта ТаблицаЗначений, явные типы Код/Количество и числовые квалификаторы 10/0/Неотрицательный. ПроверитьСвойСтендПозиций сверяет каждую исходную ячейку, тип, имя и путь, а не только размер таблиц.
Компоновщик строит настоящий макет по своей схеме и трём выбранным путям. НаборДанныхОбъектМакетаКомпоновкиДанных — уже описание исполнения, не исходный набор схемы; его ВложенныеНаборыДанных содержит настоящие ВложенныйНаборДанныхМакетаКомпоновкиДанных.
Каталог.Получить(0) даёт элемент; Каталог.Найти("Позиции85") обязан вернуть тот же элемент. Отсутствующее имя проверяется на Неопределено. Имя означает исходное поле со вложенной таблицей; фактические ПутьКДанным и Отбор печатаются из макета и не подменяются выдуманными значениями.
Поля у скомпилированного вложения — readonly-ссылка на настоящий каталог описаний. Код читает элементы, их имена/пути и сверяет поиск по фактическому имени. Нельзя писать Вложенный.Поля=Новый... или переносить это свойство на вложенное поле исходной схемы.
Вывод.Вывести создаёт настоящий результат компоновки в ТаблицаЗначений. Проверка требует три строки и три колонки. Имя колонки составного пути может задаваться генератором: вместо догадки о точках/подчёркиваниях проверка просматривает все фактические колонки по всем строкам.
Только для данного малого стенда роли колонок однозначны: O1/O2, A01/B02/C03 и числа 3/5/9 не пересекаются. Затем проверяются три точные пары заказ/позиция/количество, отсутствие повторов и лишних строк, независимая сумма и ТаблицаЗначений.Итог по фактическому имени колонки. Одна сумма 17 не обнаружила бы перепривязку позиции к чужому заказу.
Как проверить результат
Будущий ожидаемый вывод: O1/A01/3, O1/B02/5, O2/C03/9 в любом порядке; ровно три настоящие строки, три колонки и количество 17. Флаги ЕстьA01/ЕстьB02/ЕстьC03 запрещают повторные позиции даже при сохранённом общем размере.
Отрицательный ручной контроль в отдельно разрешённом опыте: передать в проверку полученный реальный результат с C03, перепривязанным к O1. Сумма может остаться 17, но точная проверка O2/C03/9 должна отказать. Здесь этот контроль не выполнялся.
Если компоновка вернула таблицу с вложенными объектами вместо ожидаемых трёх плоских детальных строк, урок должен остановиться на проверке. Не создавайте сами три строки эталона вместо настоящего вывода и не объявляйте такой обход успешной работой СКД.
Ожидаемый результат
Ожидается настоящий вывод O1/A01/3, O1/B02/5, O2/C03/9; ровно три позиции, итог количества 17. Здесь в 1С не запускалось.
На что обратить внимание
Это подробный учебный проект ожидаемого опыта, не результат запуска в 1С: runtimeVerifiedScenarios=0. Нужна будущая проверка в собственной пустой базе; не исправляйте рабочие конфигурации ради примера.
Типы вложенного элемента и поля исходной схемы доступны на сервере и во внешнем соединении. Толстый клиент указан для части методов коллекции, но это не разрешение переносить туда весь урок с серверными элементами. Отдельный модуль формы только вызывает серверный обработчик.
Не путайте вложенный набор макета с объединением наборов, вложенной схемой или группировкой настроек. В корневой native-странице вложенного элемента XDTO-имя названо DataSetUnion; из этой неоднозначной строки не выводится XML-тип. Здесь сериализуется весь настоящий МакетКомпоновкиДанных.
Назначение ролей колонок по непересекающимся буквальным значениям применимо только к этому маленькому стенду. Это не универсальный способ разбора производственных отчётов: повторяющиеся значения и дополнительные колонки требуют отдельного явно согласованного контракта.
Добавить() и Вставить(Индекс) вложенного каталога не принимают параметр Тип. Сдвинуть и Удалить получают собственный элемент этой же коллекции. Поля можно редактировать через его каталог, но readonly-свойство Поля нельзя заменять; неполные черновики не являются готовыми отчётами.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.