Настройка компоновки данных в целом. Может быть основной либо вложенной.
Полное описание, параметры и ограничения
НастройкиКомпоновкиДанных (DataCompositionSettings)
НастройкиКомпоновкиДанных (DataCompositionSettings)
Доступен, начиная с версии 8.1.
Свойства:
Выбор (Selection)
ДополнительныеСвойства (AdditionalProperties)
ДоступныеОбъекты (AvailableObjects)
ДоступныеПоляВыбора (SelectionAvailableFields)
ДоступныеПоляГруппировок (GroupAvailableFields)
ДоступныеПоляДополнительныхОтборов (AdditionalFilterAvailableFields)
ДоступныеПоляОтбора (FilterAvailableFields)
ДоступныеПоляОтбораЭлементовСтруктуры (StructureItemsFilterAvailableFields)
ДоступныеПоляПараметровДанных (DataParametersAvailableFields)
ДоступныеПоляПорядка (OrderAvailableFields)
Отбор (Filter)
ПараметрыВывода (OutputParameters)
ПараметрыДанных (DataParameters)
ПользовательскиеПоля (UserFields)
Порядок (Order)
Родитель (Parent)
Структура (Structure)
УсловноеОформление (ConditionalAppearance)
Методы:
НаличиеВыбораУЭлемента (HasItemSelection)
НаличиеОтбораУЭлемента (HasItemFilter)
НаличиеПараметровВыводаУЭлемента (HasItemOutputParameters)
НаличиеПорядкаУЭлемента (HasItemOrder)
НаличиеУсловногоОформленияУЭлемента (HasItemConditionalAppearance)
НастройкиЭлемента (ItemSettings)
ОчиститьВыборЭлемента (ClearItemSelection)
ОчиститьОтборЭлемента (ClearItemFilter)
ОчиститьПараметрыВыводаЭлемента (ClearItemOutputParameters)
ОчиститьПорядокЭлемента (ClearItemOrder)
ОчиститьУсловноеОформлениеЭлемента (ClearItemConditionalAppearance)
ПолучитьИдентификаторПоОбъекту (GetIDByObject)
ПолучитьОбъектПоИдентификатору (GetObjectByID)
Конструкторы:
По умолчанию
Описание:
Настройка компоновки данных в целом.
Может быть основной либо вложенной.
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.
Сериализуется. Данный объект может быть сериализован в/из XML. Может использоваться в реквизитах управляемой формы. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен {http://v8.1c.ru/8.1/data-composition-system/settings}. Имя типа XDTO: Settings.
См. также:
КомпоновщикНастроекКомпоновкиДанных, свойство Настройки
НастройкиВложенногоОбъектаКомпоновкиДанных, свойство Настройки
КомпоновщикМакетаКомпоновкиДанных, метод Выполнить
КомпоновщикНастроекКомпоновкиДанных, метод ЗагрузитьНастройки
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Параметр связи СКД: объявление строковых кодов и согласованные режимы = / В
Создаём свой источник A01/3 и приёмник с буквальными строками A01/500, B01/700 внутри настоящего вложенного запроса. Объявляем КодыСвязи85 в схеме, связываем его с полем источника, переключаем полное условие запроса и Булево разрешения списка вместе, проверяем восстановление и независимую копию без исполнения.
Где и как запускать
Полный серверный общий модуль УчебныеЗадачи новой пустой конфигурации УчебныеПараметрыСвязи85; в1С не запускался.
Подготовка
НОВАЯ отдельная учебная база, не копия рабочей: точно8.5.1.1343, конфигурация УчебныеПараметрыСвязи85, совместимость Не использовать. Нет бизнес-объектов, расширений, подписок и фоновых заданий; модули вручную пустые, кроме данного общего модуля.
Конфигуратор → Общие → Общие модули → УчебныеЗадачи: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставить весь основной модуль. Создать свою внешнюю обработку УчебныеПараметрыСвязи85 → управляемая Форма: команда/кнопка Выполнить с действием Выполнить. Отдельный полный модуль формы дан ниже; реквизиты не нужны.
Будущая ручная подготовка вне опыта: завершить прежний свой сеанс, сохранить, Конфигурация → Обновить конфигурацию базы данных (F7), открыть свежий собственный клиент и свою обработку. Здесь F7, BSL, запросы, компоновщик и процессор не запускались.
Источник и приёмник объявлены самим кодом: четыре уникальных пути, в каждом наборе Строка/Число. Приёмник использует вложенный запрос как таблицу-источник, объединяющую две собственные буквальные строки; рабочих таблиц и неизвестных параметров нет.
Числовые поля имеют разные явные учебные контракты: КоличествоИсточника — целое 0–9, ЦенаПриемника — целое 0–999. Собственные буквальные значения3,500,700 укладываются в них. КвалификаторыЧисла передаются вторым аргументом ОписаниеТипов; это не утверждение, что рабочие цены всегда целые или ограничены999.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
Если ПривилегированныйРежим() Тогда
ВызватьИсключение "Привилегированный режим не нужен";
КонецЕсли;
Схема = СоздатьСвоюОсновуПараметра();
ПроверитьСвойРежимСвязи(Схема, Ложь, Ложь);
ДобавитьСвоюПараметрическуюСвязь(Схема);
ПроверитьСвойРежимСвязи(Схема, Истина, Ложь);
Копия = СоздатьСвоюОсновуПараметра();
ДобавитьСвоюПараметрическуюСвязь(Копия);
УстановитьСвойРежимСвязи(Схема, Истина);
ПроверитьСвойРежимСвязи(Схема, Истина, Истина);
ПроверитьСвойРежимСвязи(Копия, Истина, Ложь);
УстановитьСвойРежимСвязи(Схема, Ложь);
ПроверитьСвойРежимСвязи(Схема, Истина, Ложь);
Каталог = Схема.СвязиНаборовДанных;
Связь = Каталог.Получить(0);
Каталог.Удалить(Связь);
ПроверитьСвойРежимСвязи(Схема, Ложь, Ложь);
ПроверитьСвойРежимСвязи(Копия, Истина, Ложь);
ДобавитьСвоюПараметрическуюСвязь(Схема);
ПроверитьСвойРежимСвязи(Схема, Истина, Ложь);
Каталог.Очистить();
ПроверитьСвойРежимСвязи(Схема, Ложь, Ложь);
ПроверитьСвойРежимСвязи(Копия, Истина, Ложь);
ДобавитьСвоюПараметрическуюСвязь(Схема);
ПроверитьСвойРежимСвязи(Схема, Истина, Ложь);
ПроверитьСвойРежимСвязи(Копия, Истина, Ложь);
Сообщить("КодыСвязи85 объявлен, запрос приёмника и скалярный флаг полностью восстановлены");
КонецПроцедуры
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
Функция СвоеПолеВXML(Поле)
Если ТипЗнч(Поле) <> Тип("ПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Сериализуется только собственное поле СКД, не объект или записи базы";
КонецЕсли;
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
Попытка
СериализаторXDTO.ЗаписатьXML(Запись, Поле);
Возврат Запись.Закрыть();
Исключение
Запись.Закрыть();
ВызватьИсключение;
КонецПопытки;
КонецФункции
Функция СвойТипПоляПараметра(ИмяПоля)
Если ИмяПоля = "КодИсточника" Или ИмяПоля = "КодПриемника" Тогда
Возврат Новый ОписаниеТипов("Строка");
ИначеЕсли ИмяПоля = "КоличествоИсточника" Тогда
Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли ИмяПоля = "ЦенаПриемника" Тогда
Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Неотрицательный));
КонецЕсли;
ВызватьИсключение "В собственной связи используются только четыре явно заданных поля";
КонецФункции
Процедура ПроверитьСвоиКвалификаторыПараметра(Описание, Разрядность)
Если ТипЗнч(Описание) <> Тип("ОписаниеТипов") Тогда
ВызватьИсключение "Нужно собственное описание числового поля параметрической связи";
КонецЕсли;
Квалификаторы = Описание.КвалификаторыЧисла;
Если ТипЗнч(Квалификаторы) <> Тип("КвалификаторыЧисла") Или Квалификаторы.Разрядность <> Разрядность
Или Квалификаторы.РазрядностьДробнойЧасти <> 0
Или Квалификаторы.ДопустимыйЗнак <> ДопустимыйЗнак.Неотрицательный Тогда
ВызватьИсключение "Не совпал полный собственный числовой контракт количества или цены";
КонецЕсли;
КонецПроцедуры
Функция СвойЗапросПриемника(СписокРазрешен)
Если СписокРазрешен Тогда
Возврат "ВЫБРАТЬ Данные.Код КАК КодПриемника, Данные.Цена КАК ЦенаПриемника ИЗ (ВЫБРАТЬ ""A01"" КАК Код, 500 КАК Цена ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""B01"" КАК Код, 700 КАК Цена) КАК Данные ГДЕ Данные.Код В (&КодыСвязи85)";
КонецЕсли;
Возврат "ВЫБРАТЬ Данные.Код КАК КодПриемника, Данные.Цена КАК ЦенаПриемника ИЗ (ВЫБРАТЬ ""A01"" КАК Код, 500 КАК Цена ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""B01"" КАК Код, 700 КАК Цена) КАК Данные ГДЕ Данные.Код = &КодыСвязи85";
КонецФункции
Функция СоздатьСвоюОсновуПараметра()
Схема = Новый СхемаКомпоновкиДанных;
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "СвоиПараметры85";
Источник.ТипИсточникаДанных = "Local";
ИменаНаборов = СтрРазделить("Источник85,Приемник85", ",");
Запросы = Новый Массив;
Запросы.Добавить("ВЫБРАТЬ ""A01"" КАК КодИсточника, 3 КАК КоличествоИсточника");
Запросы.Добавить(СвойЗапросПриемника(Ложь));
ПоляНаборов = Новый Массив;
ПоляНаборов.Добавить(СтрРазделить("КодИсточника,КоличествоИсточника", ","));
ПоляНаборов.Добавить(СтрРазделить("КодПриемника,ЦенаПриемника", ","));
Для ИндексНабора = 0 По 1 Цикл
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Если ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен собственный набор запроса";
КонецЕсли;
Набор.Имя = ИменаНаборов[ИндексНабора];
Набор.ИсточникДанных = "СвоиПараметры85";
Набор.АвтоЗаполнениеДоступныхПолей = Ложь;
Набор.Запрос = Запросы[ИндексНабора];
ИменаПолей = ПоляНаборов[ИндексНабора];
Для Индекс = 0 По 1 Цикл
Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно собственное простое объявление поля";
КонецЕсли;
Поле.Поле = ИменаПолей[Индекс];
Поле.ПутьКДанным = ИменаПолей[Индекс];
Поле.ТипЗначения = СвойТипПоляПараметра(ИменаПолей[Индекс]);
КонецЦикла;
КонецЦикла;
Параметр = Схема.Параметры.Добавить();
Если ТипЗнч(Параметр) <> Тип("ПараметрСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен настоящий собственный параметр схемы";
КонецЕсли;
Параметр.Имя = "КодыСвязи85";
Параметр.ТипЗначения = Новый ОписаниеТипов("Строка");
Параметр.Значение = "";
Параметр.Использование = ИспользованиеПараметраКомпоновкиДанных.Авто;
ВыбираемыеПоля = СтрРазделить("КодИсточника,КоличествоИсточника,ЦенаПриемника", ",");
Для Каждого Путь Из ВыбираемыеПоля Цикл
Выбор = Схема.НастройкиПоУмолчанию.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
Если ТипЗнч(Выбор) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно собственное явно выбранное поле";
КонецЕсли;
Выбор.Поле = Новый ПолеКомпоновкиДанных(Путь);
Выбор.Использование = Истина;
КонецЦикла;
ПроверитьСвоюОсновуПараметра(Схема, Ложь);
Возврат Схема;
КонецФункции
Процедура ПроверитьСвоюОсновуПараметра(Схема, СписокРазрешен)
Если ТипЗнч(Схема) <> Тип("СхемаКомпоновкиДанных")
Или Схема.ИсточникиДанных.Количество() <> 1 Или Схема.НаборыДанных.Количество() <> 2
Или Схема.Параметры.Количество() <> 1 Или Схема.НастройкиПоУмолчанию.Выбор.Элементы.Количество() <> 3 Тогда
ВызватьИсключение "Нужны прежние свои источник, два набора, параметр и три выбранных поля";
КонецЕсли;
Источник = Схема.ИсточникиДанных.Получить(0);
Если ТипЗнч(Источник) <> Тип("ИсточникДанныхСхемыКомпоновкиДанных")
Или Источник.Имя <> "СвоиПараметры85" Или Источник.ТипИсточникаДанных <> "Local" Тогда
ВызватьИсключение "Не совпал полный собственный источник";
КонецЕсли;
ИменаНаборов = СтрРазделить("Источник85,Приемник85", ",");
Запросы = Новый Массив;
Запросы.Добавить("ВЫБРАТЬ ""A01"" КАК КодИсточника, 3 КАК КоличествоИсточника");
Запросы.Добавить(СвойЗапросПриемника(СписокРазрешен));
ПоляНаборов = Новый Массив;
ПоляНаборов.Добавить(СтрРазделить("КодИсточника,КоличествоИсточника", ","));
ПоляНаборов.Добавить(СтрРазделить("КодПриемника,ЦенаПриемника", ","));
Типы = СтрРазделить("Строка,Число", ",");
Для ИндексНабора = 0 По 1 Цикл
Набор = Схема.НаборыДанных.Получить(ИндексНабора);
Если ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен собственный набор запроса";
КонецЕсли;
Если Набор.Имя <> ИменаНаборов[ИндексНабора] Или Набор.ИсточникДанных <> "СвоиПараметры85"
Или Набор.АвтоЗаполнениеДоступныхПолей Или Набор.Запрос <> Запросы[ИндексНабора]
Или Набор.Поля.Количество() <> 2 Или Схема.НаборыДанных.Найти(Набор.Имя) <> Набор Тогда
ВызватьИсключение "Не совпали полный запрос, имя, порядок и поля своего набора";
КонецЕсли;
ИменаПолей = ПоляНаборов[ИндексНабора];
Для Индекс = 0 По 1 Цикл
Поле = Набор.Поля.Получить(Индекс);
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")
Или Поле.Поле <> ИменаПолей[Индекс] Или Поле.ПутьКДанным <> ИменаПолей[Индекс]
Или ТипЗнч(Поле.ТипЗначения) <> Тип("ОписаниеТипов") Тогда
ВызватьИсключение "Не совпали все полные собственные пути и типы полей";
КонецЕсли;
ПолныеТипы = Поле.ТипЗначения.Типы();
Если ПолныеТипы.Количество() <> 1 Или ПолныеТипы[0] <> Тип(Типы[Индекс]) Тогда
ВызватьИсключение "Не совпал полный тип собственного поля";
КонецЕсли;
Если Индекс = 1 Тогда
Разрядность = 1;
Если ИндексНабора = 1 Тогда
Разрядность = 3;
КонецЕсли;
ПроверитьСвоиКвалификаторыПараметра(Поле.ТипЗначения, Разрядность);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Параметр = Схема.Параметры.Получить(0);
Если ТипЗнч(Параметр) <> Тип("ПараметрСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен собственный параметр схемы";
КонецЕсли;
Если Параметр.Имя <> "КодыСвязи85" Или Схема.Параметры.Найти("КодыСвязи85") <> Параметр
Или ТипЗнч(Параметр.ТипЗначения) <> Тип("ОписаниеТипов") Или ТипЗнч(Параметр.Значение) <> Тип("Строка")
Или Параметр.Значение <> "" Или Параметр.Использование <> ИспользованиеПараметраКомпоновкиДанных.Авто Тогда
ВызватьИсключение "Не совпали имя, тип, значение по умолчанию и использование своего параметра";
КонецЕсли;
ПолныеТипы = Параметр.ТипЗначения.Типы();
Если ПолныеТипы.Количество() <> 1 Или ПолныеТипы[0] <> Тип("Строка") Тогда
ВызватьИсключение "Параметр связи относится к собственным строковым кодам";
КонецЕсли;
Если Схема.Параметры.Найти("НетТакогоПараметра85") <> Неопределено Тогда
ВызватьИсключение "Отсутствующий собственный параметр не должен находиться";
КонецЕсли;
ВыбираемыеПоля = СтрРазделить("КодИсточника,КоличествоИсточника,ЦенаПриемника", ",");
Для Индекс = 0 По 2 Цикл
Выбор = Схема.НастройкиПоУмолчанию.Выбор.Элементы.Получить(Индекс);
Если ТипЗнч(Выбор) <> Тип("ВыбранноеПолеКомпоновкиДанных") Или Не Выбор.Использование Тогда
ВызватьИсключение "Нужно используемое собственное выбранное поле";
КонецЕсли;
Если СвоеПолеВXML(Выбор.Поле) <> СвоеПолеВXML(Новый ПолеКомпоновкиДанных(ВыбираемыеПоля[Индекс])) Тогда
ВызватьИсключение "Не совпали полные пути и порядок выбранных полей";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьСвоюПараметрическуюСвязь(Схема)
ПроверитьСвоюОсновуПараметра(Схема, Ложь);
Если Схема.СвязиНаборовДанных.Количество() <> 0 Тогда
ВызватьИсключение "Связь добавляется в пустой собственный каталог";
КонецЕсли;
Связь = Схема.СвязиНаборовДанных.Добавить();
Если ТипЗнч(Связь) <> Тип("СвязьНаборовДанныхСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужна собственная параметрическая связь";
КонецЕсли;
Связь.НаборДанныхИсточник = "Источник85";
Связь.НаборДанныхПриемник = "Приемник85";
Связь.ВыражениеИсточник = "КодИсточника";
Связь.ВыражениеПриемник = "КодПриемника";
Связь.Обязательная = Истина;
Связь.Параметр = "КодыСвязи85";
Связь.РазрешенСписокПараметров = Ложь;
КонецПроцедуры
Процедура УстановитьСвойРежимСвязи(Схема, СписокРазрешен)
Если Схема.СвязиНаборовДанных.Количество() <> 1 Тогда
ВызватьИсключение "Нужна единственная текущая собственная связь";
КонецЕсли;
Приемник = Схема.НаборыДанных.Найти("Приемник85");
Если ТипЗнч(Приемник) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен свой существующий набор запроса приемника";
КонецЕсли;
Приемник.Запрос = СвойЗапросПриемника(СписокРазрешен);
Связь = Схема.СвязиНаборовДанных.Получить(0);
Связь.РазрешенСписокПараметров = СписокРазрешен;
ПроверитьСвойРежимСвязи(Схема, Истина, СписокРазрешен);
КонецПроцедуры
Процедура ПроверитьСвойРежимСвязи(Схема, ЕстьСвязь, СписокРазрешен)
ПроверитьСвоюОсновуПараметра(Схема, СписокРазрешен);
Каталог = Схема.СвязиНаборовДанных;
Ожидается = 0;
Если ЕстьСвязь Тогда
Ожидается = 1;
КонецЕсли;
Если Каталог.Количество() <> Ожидается Тогда
ВызватьИсключение "Не совпал полный размер собственных связей";
КонецЕсли;
Если Не ЕстьСвязь Тогда
Возврат;
КонецЕсли;
Связь = Каталог.Получить(0);
Если ТипЗнч(Связь) <> Тип("СвязьНаборовДанныхСхемыКомпоновкиДанных")
Или Связь.НаборДанныхИсточник <> "Источник85" Или Связь.НаборДанныхПриемник <> "Приемник85"
Или Связь.ВыражениеИсточник <> "КодИсточника" Или Связь.ВыражениеПриемник <> "КодПриемника"
Или Не Связь.Обязательная Или Связь.Параметр <> "КодыСвязи85"
Или ТипЗнч(Связь.РазрешенСписокПараметров) <> Тип("Булево")
Или Связь.РазрешенСписокПараметров <> СписокРазрешен
Или Каталог.Индекс(Связь) <> 0 Или Каталог[0] <> Связь Тогда
ВызватьИсключение "Не совпали стороны, ключи, имя параметра, флаг списка и порядок своей связи";
КонецЕсли;
КонецПроцедурыУчебныеПараметрыСвязи85.Форма
Своя внешняя обработка УчебныеПараметрыСвязи85 → управляемая Форма → Модуль
Полный отдельный модуль своей формы с серверным вызовом; здесь не запускался.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Объявление параметра, полный запрос приёмника и скалярный/списочный режим связи проверены");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныеЗадачи.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Полностью объявить свой параметр Схема.Параметры.Добавить(): имя КодыСвязи85, ОписаниеТипов("Строка"), строковое значение по умолчанию пустое, использование Авто. В КА2 АнализСчета настоящий параметр связи Ссылки также объявлен в схеме, тип соответствует полю источника.
Не устанавливать Всегда механически: по справке этот режим всегда использует значение настройки. В своём опыте проверяется Авто и передача кода через Параметр связи; пустой default не выдаётся за полученное значение источника.
Параметр свойства связи — имя без амперсанда: КодыСвязи85. В запросе используется &КодыСвязи85. Значение определяется ВыражениеИсточник="КодИсточника"; ВыражениеПриемник="КодПриемника" указывает реальный ключ приёмника. ЦенаПриемника нужна в выборе; источник кода также выбран.
Скалярная версия запроса содержит Данные.Код = &КодыСвязи85 и РазрешенСписокПараметров=Ложь. Списочная версия содержит Данные.Код В (&КодыСвязи85) и флаг Истина. СвойЗапросПриемника возвращает полный точный запрос режима, а УстановитьСвойРежимСвязи меняет запрос и флаг согласованно.
Условие находится во внешнем запросе с настоящим ИЗ (вложенный запрос) КАК Данные, не в выдуманном ГДЕ без источника. Вложенные источники документированы установленной справкой; поля Данные.Код/Цена объявлены внутренним списком выборки.
Восемь контрольных состояний оригинала проверяют полный источник, оба текста запросов, все поля/типы/порядок, весь параметр, его положительный/отрицательный поиск, выбор, обе стороны связи, имя параметра, реальный Булево и каталог. Флаг списка не считается доказанным только по названию свойства.
Копия создаётся заново со своим параметром и исходным запросом =. Во время режима В оригинала копия остаётся скалярной. После возврата режима удалить текущую связь как объект, не индекс, подтвердить0 при сохранённом объявлении параметра и запросах, создать новую; очистить оригинальный каталог и восстановить снова.
Списочный режим разрешает обработку списка, но код не присваивает Массив строковому ТипЗначения параметра и не запускает движок. Конкретная упаковка значений компоновщиком и данные результата остаются будущей runtime-проверкой.
СвойТипПоляПараметра различает все четыре настоящих имени поля: коды Строка, количество Число(1,0,Неотрицательный), цена Число(3,0,Неотрицательный). Проверка каждого числового поля сверяет все три квалификатора, а не только наличие Число в Типы(). Строковый параметр КодыСвязи85, запросы и переключение = / В остаются прежними.
Как проверить результат
Будущий итог проверки модели: единственный строковый КодыСвязи85 с пустым default/Авто; два исходных набора и полный скалярный запрос; одна связь Источник85→Приемник85, КодИсточника→КодПриемника, Параметр=КодыСвязи85, флаг списка Ложь. Копия сохраняет то же исходное состояние.
Буквальные строки задают A01/500 и B01/700. По математической логике = для A01 выбирает первый код, а В для списка A01/B01 допускает оба кода, но здесь список источников не формировался и запрос не выполнялся: это объяснение режимов, не полученные строки или обещание производительности.
Будущий отрицательный контроль: после согласованного перехода в режим В вручную заменить только Связь.РазрешенСписокПараметров на Ложь, не меняя эталон Истина и полный запрос. Проверка должна отказать. Альтернативно заменить имя параметра связи на НетТакогоПараметра85 при прежних запросах. Вернуть код, сохранить/F7 вне опыта и открыть новый свой сеанс; здесь контроль не выполнялся.
runtimeVerifiedScenarios=0. Сохранность прежних материалов и native-контракты проверяются статически. Нет выполнения 1С, запросов, записи, сети, реального компоновщика, печати или изменения конфигураций пользователя.
Ожидаемый результат
Полный осмысленный пример двух режимов параметрической связи: реальное объявление параметра, настоящий запрос приёмника и согласованные проверки всех определений.
На что обратить внимание
Параметр связи хранит имя параметра, не его значение и не текст &КодыСвязи85. Амперсанд нужен в языке запроса; строка свойства задаётся без него. Полный текст запроса не сводится к поиску подстроки В.
Список допустим при использовании параметра в операции В. Не включайте Истина при сохранённом сравнении = и не подменяйте ОписаниеТипов строкового элемента типом Массив без документированного основания.
Авто и Всегда имеют разный смысл. Этот урок не утверждает, что default пустой станет A01 сам по себе: это работа будущего компоновщика при использовании связи, здесь ни её исполнение, ни фактическая передача не проверялись.
Буквальный вложенный запрос позволяет изучать контракты без чужих таблиц. Наличие параметрической связи не обещает выполненный SQL, количество обращений или готовый визуальный отчёт.
Копия содержит новые собственные объекты. После Удалить и Очистить старые ссылки связи не используются; объявление параметра и оба набора сохраняются. XML получает только собственное ПолеКомпоновкиДанных и пишет строку в памяти.
Методы жизненного цикла каталога параметров и параметры функциональных опций не привязываются как бессмысленные заглушки: им нужны отдельные содержательные задачи.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Макеты группировки СКД: именованная группа, enum типа области и два независимых каталога
На собственной схеме с объявленным полем Склад создаём реальную группировку ПоСкладу85 в обычных настройках. Привязываем существующие области к её заголовку/подвалу и отдельному каталогу заголовков, меняем ссылку, удаляем и восстанавливаем описания. Полностью контролируем источник, поля, группы, enum, области и независимую копию без выполнения отчёта.
Где и как запускать
Полный серверный общий модуль УчебныеЗадачи новой пустой конфигурации УчебныеМакетыГруппировок85; в1С не запускался.
Подготовка
Нужна НОВАЯ отдельная учебная база, не копия рабочей: точно8.5.1.1343, имя конфигурации УчебныеМакетыГруппировок85, совместимость Не использовать. Нет бизнес-объектов, расширений, подписок и фоновых заданий; модули вручную пустые, кроме данного общего модуля.
Общий модуль УчебныеЗадачи: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте весь основной модуль. Своя внешняя обработка УчебныеМакетыГруппировок85 → управляемая Форма: команда/кнопка Выполнить с действием Выполнить; реквизиты не нужны. Полный отдельный модуль формы дан ниже.
Будущая ручная подготовка только вне опыта: завершить прежний собственный сеанс, сохранить конфигурацию, Конфигурация → Обновить конфигурацию базы данных (F7), затем свежий собственный клиент и своя обработка. Здесь F7, BSL, отчёты, запросы и печать не запускались.
Собственная основа создаётся целиком: один Local-источник, один набор с буквальным запросом A01/3/Учебный, вручную объявленные поля КодТовара Строка/Количество Число/Склад Строка, четыре именованные области со своими постоянными текстами. Это объявления в модели, не полученные записи.
Обычные НастройкиПоУмолчанию содержат одну включённую группировку ПоСкладу85 по явно заданному Склад, тип группировки Элементы. Не использовать пользовательские настройки: у их элементов Имя и ПоляГруппировки недоступны.
Количество в буквальном запросе равно3. Его собственное описание — Число(1,0), неотрицательное: один общий разряд, ноль дробных, допустимые целые0–9. Это предел учебного исходного поля, не диапазон количества рабочего отчёта и не описание типа агрегата Сумма(Количество).
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
Если ПривилегированныйРежим() Тогда
ВызватьИсключение "Привилегированный режим не нужен";
КонецЕсли;
Пусто = Новый Массив;
Типы = Новый Массив;
Типы.Добавить(ТипМакетаОбластиКомпоновкиДанных.Заголовок);
Типы.Добавить(ТипМакетаОбластиКомпоновкиДанных.Подвал);
ОдинТип = Новый Массив;
ОдинТип.Добавить(ТипМакетаОбластиКомпоновкиДанных.Заголовок);
ОдинПодвал = Новый Массив;
ОдинПодвал.Добавить(ТипМакетаОбластиКомпоновкиДанных.Подвал);
Имена = СтрРазделить("Склад,Количество", ",");
Схема = СоздатьСвоюОсновуГруппировок();
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Пусто, Пусто);
ПроверитьСвоиМакетыГруппировки(Схема, Истина, Пусто, Пусто);
Основной = ПолучитьСвойКаталогГруппировок(Схема, Ложь);
Заголовки = ПолучитьСвойКаталогГруппировок(Схема, Истина);
Шапка = Основной.Добавить();
ЗаполнитьСвойМакетГруппировки(Схема, Шапка, "Склад", Типы[0]);
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, СтрРазделить("Склад", ","), ОдинТип);
ОтдельныйЗаголовок = Заголовки.Добавить();
ЗаполнитьСвойМакетГруппировки(Схема, ОтдельныйЗаголовок, "КодТовара", Типы[0]);
ПроверитьСвоиМакетыГруппировки(Схема, Истина, СтрРазделить("КодТовара", ","), ОдинТип);
Подвал = Основной.Вставить(0);
ЗаполнитьСвойМакетГруппировки(Схема, Подвал, "Количество", Типы[1]);
ОбратныеТипы = Новый Массив;
ОбратныеТипы.Добавить(Типы[1]);
ОбратныеТипы.Добавить(Типы[0]);
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, СтрРазделить("Количество,Склад", ","), ОбратныеТипы);
Основной.Сдвинуть(Подвал, 1);
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Имена, Типы);
Шапка.Макет = "КоличествоВыделено85";
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, СтрРазделить("КоличествоВыделено85,Количество", ","), Типы);
Шапка.Макет = "Склад";
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Имена, Типы);
Копия = СоздатьСвоюОсновуГруппировок();
ВосстановитьСвоиМакетыГруппировки(Копия);
ЗаголовокКопии = Копия.МакетыЗаголовковГруппировок.Добавить();
ЗаполнитьСвойМакетГруппировки(Копия, ЗаголовокКопии, "КодТовара", Типы[0]);
Основной.Удалить(Шапка);
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, СтрРазделить("Количество", ","), ОдинПодвал);
ПроверитьСвоиМакетыГруппировки(Схема, Истина, СтрРазделить("КодТовара", ","), ОдинТип);
ПроверитьСвоиМакетыГруппировки(Копия, Ложь, Имена, Типы);
НоваяШапка = Основной.Вставить(0);
ЗаполнитьСвойМакетГруппировки(Схема, НоваяШапка, "Склад", Типы[0]);
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Имена, Типы);
Основной.Очистить();
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Пусто, Пусто);
ПроверитьСвоиМакетыГруппировки(Схема, Истина, СтрРазделить("КодТовара", ","), ОдинТип);
ПроверитьСвоиМакетыГруппировки(Копия, Ложь, Имена, Типы);
ВосстановитьСвоиМакетыГруппировки(Схема);
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Имена, Типы);
Заголовки.Удалить(ОтдельныйЗаголовок);
ПроверитьСвоиМакетыГруппировки(Схема, Истина, Пусто, Пусто);
НовыйЗаголовок = Заголовки.Добавить();
ЗаполнитьСвойМакетГруппировки(Схема, НовыйЗаголовок, "КодТовара", Типы[0]);
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Имена, Типы);
ПроверитьСвоиМакетыГруппировки(Схема, Истина, СтрРазделить("КодТовара", ","), ОдинТип);
ПроверитьСвоиМакетыГруппировки(Копия, Ложь, Имена, Типы);
ПроверитьСвоиМакетыГруппировки(Копия, Истина, СтрРазделить("КодТовара", ","), ОдинТип);
Сообщить("ПоСкладу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);
Если ТипЗнч(Поле) <> Тип("ПолеОбластиКомпоновкиДанных")
Или ТипЗнч(Поле.Значение) <> Тип("Строка") Или Поле.Значение <> Текст Тогда
ВызватьИсключение "Не совпало полное текстовое содержимое собственной области";
КонецЕсли;
КонецПроцедуры
Функция СвойТипКоличестваМакета()
Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный));
КонецФункции
Процедура ПроверитьСвоюРазрядностьМакета(Описание)
Квалификаторы = Описание.КвалификаторыЧисла;
Если ТипЗнч(Квалификаторы) <> Тип("КвалификаторыЧисла") Или Квалификаторы.Разрядность <> 1
Или Квалификаторы.РазрядностьДробнойЧасти <> 0
Или Квалификаторы.ДопустимыйЗнак <> ДопустимыйЗнак.Неотрицательный Тогда
ВызватьИсключение "Своё количество макета имеет один разряд, ноль дробных и неотрицательный знак";
КонецЕсли;
КонецПроцедуры
Функция СоздатьСвоюОсновуМакетовПолей()
Схема = Новый СхемаКомпоновкиДанных;
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "СвоиДанные85";
Источник.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Если ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен собственный набор запроса";
КонецЕсли;
Набор.Имя = "УчебныеОстатки85";
Набор.ИсточникДанных = "СвоиДанные85";
Набор.АвтоЗаполнениеДоступныхПолей = Ложь;
Набор.Запрос = "ВЫБРАТЬ ""A01"" КАК КодТовара, 3 КАК Количество, ""Учебный"" КАК Склад";
Имена = СтрРазделить("КодТовара|Количество|Склад", "|");
Для Индекс = 0 По 2 Цикл
Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно простое собственное описание поля, не папка";
КонецЕсли;
Поле.Поле = Имена[Индекс];
Поле.ПутьКДанным = Имена[Индекс];
Если Индекс = 1 Тогда
Поле.ТипЗначения = СвойТипКоличестваМакета();
Иначе
Поле.ТипЗначения = Новый ОписаниеТипов("Строка");
КонецЕсли;
КонецЦикла;
ИменаМакетов = СтрРазделить("КодТовара|Количество|Склад|КоличествоВыделено85", "|");
Тексты = СтрРазделить("Код: A01|Количество: 3|Склад: Учебный|Количество: 3 (выделено)", "|");
Для Индекс = 0 По 3 Цикл
Описание = Схема.Макеты.Добавить();
ЗаполнитьСвойИменованныйМакет(Описание, ИменаМакетов[Индекс], Тексты[Индекс]);
КонецЦикла;
ПроверитьСвоюОсновуМакетовПолей(Схема);
Возврат Схема;
КонецФункции
Процедура ПроверитьСвоюОсновуМакетовПолей(Схема)
Если ТипЗнч(Схема) <> Тип("СхемаКомпоновкиДанных") Или Схема.ИсточникиДанных.Количество() <> 1
Или Схема.НаборыДанных.Количество() <> 1 Или Схема.Макеты.Количество() <> 4 Тогда
ВызватьИсключение "Нужны только собственные источник, набор и четыре согласованные области";
КонецЕсли;
Источник = Схема.ИсточникиДанных.Получить(0);
Если ТипЗнч(Источник) <> Тип("ИсточникДанныхСхемыКомпоновкиДанных")
Или Источник.Имя <> "СвоиДанные85" Или Источник.ТипИсточникаДанных <> "Local" Тогда
ВызватьИсключение "Не совпал собственный источник";
КонецЕсли;
Набор = Схема.НаборыДанных.Получить(0);
Если ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен собственный набор запроса";
КонецЕсли;
Если Набор.Имя <> "УчебныеОстатки85" Или Набор.ИсточникДанных <> "СвоиДанные85"
Или Набор.АвтоЗаполнениеДоступныхПолей Или Набор.Запрос <> "ВЫБРАТЬ ""A01"" КАК КодТовара, 3 КАК Количество, ""Учебный"" КАК Склад"
Или Набор.Поля.Количество() <> 3 Тогда
ВызватьИсключение "Не совпали полный собственный запрос и ручное описание полей";
КонецЕсли;
Имена = СтрРазделить("КодТовара|Количество|Склад", "|");
Типы = СтрРазделить("Строка,Число,Строка", ",");
Для Индекс = 0 По 2 Цикл
Поле = Набор.Поля.Получить(Индекс);
Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")
Или Поле.Поле <> Имена[Индекс] Или Поле.ПутьКДанным <> Имена[Индекс]
Или ТипЗнч(Поле.ТипЗначения) <> Тип("ОписаниеТипов") Тогда
ВызватьИсключение "Не совпали полный путь, имя и описание собственного поля";
КонецЕсли;
ПолныеТипы = Поле.ТипЗначения.Типы();
Если ПолныеТипы.Количество() <> 1 Или ПолныеТипы[0] <> Тип(Типы[Индекс]) Тогда
ВызватьИсключение "Не совпал полный набор типов собственного поля";
КонецЕсли;
Если Индекс = 1 Тогда
ПроверитьСвоюРазрядностьМакета(Поле.ТипЗначения);
КонецЕсли;
КонецЦикла;
ИменаМакетов = СтрРазделить("КодТовара|Количество|Склад|КоличествоВыделено85", "|");
Тексты = СтрРазделить("Код: A01|Количество: 3|Склад: Учебный|Количество: 3 (выделено)", "|");
Для Индекс = 0 По 3 Цикл
Описание = Схема.Макеты.Получить(Индекс);
Если ТипЗнч(Описание) <> Тип("ОписаниеМакетаСхемыКомпоновкиДанных")
Или Описание.Имя <> ИменаМакетов[Индекс] Или Схема.Макеты.Найти(ИменаМакетов[Индекс]) <> Описание Тогда
ВызватьИсключение "Не совпали имена и порядок существующих собственных макетов";
КонецЕсли;
ПроверитьСвоюПолнуюОбласть(Описание, Тексты[Индекс]);
КонецЦикла;
КонецПроцедуры
Функция СвоеПолеВXML(Поле)
Если ТипЗнч(Поле) <> Тип("ПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Сериализуется только собственное поле СКД, не объект или записи базы";
КонецЕсли;
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
Попытка
СериализаторXDTO.ЗаписатьXML(Запись, Поле);
Возврат Запись.Закрыть();
Исключение
Запись.Закрыть();
ВызватьИсключение;
КонецПопытки;
КонецФункции
Функция СоздатьСвоюОсновуГруппировок()
Схема = СоздатьСвоюОсновуМакетовПолей();
Группировка = Схема.НастройкиПоУмолчанию.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Если ТипЗнч(Группировка) <> Тип("ГруппировкаКомпоновкиДанных") Тогда
ВызватьИсключение "Нужна настоящая собственная группировка обычных настроек";
КонецЕсли;
Группировка.Имя = "ПоСкладу85";
Группировка.Использование = Истина;
Поле = Группировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
Если ТипЗнч(Поле) <> Тип("ПолеГруппировкиКомпоновкиДанных") Тогда
ВызватьИсключение "Нужно явно заданное собственное поле группировки, не автоэлемент";
КонецЕсли;
Поле.Поле = Новый ПолеКомпоновкиДанных("Склад");
Поле.Использование = Истина;
Поле.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
ПроверитьСвоюОсновуГруппировок(Схема);
Возврат Схема;
КонецФункции
Процедура ПроверитьСвоюОсновуГруппировок(Схема)
ПроверитьСвоюОсновуМакетовПолей(Схема);
Структура = Схема.НастройкиПоУмолчанию.Структура;
Если Структура.Количество() <> 1 Тогда
ВызватьИсключение "В обычных настройках нужна единственная собственная группировка";
КонецЕсли;
Группировка = Структура.Получить(0);
Если ТипЗнч(Группировка) <> Тип("ГруппировкаКомпоновкиДанных")
Или Группировка.Имя <> "ПоСкладу85" Или Не Группировка.Использование
Или ТипЗнч(Группировка.ПоляГруппировки) <> Тип("ПоляГруппировкиКомпоновкиДанных") Тогда
ВызватьИсключение "Не совпала реальная собственная именованная группировка";
КонецЕсли;
Если Группировка.ПоляГруппировки.Элементы.Количество() <> 1 Тогда
ВызватьИсключение "Группировка использует только объявленное собственное поле Склад";
КонецЕсли;
Поле = Группировка.ПоляГруппировки.Элементы.Получить(0);
Если ТипЗнч(Поле) <> Тип("ПолеГруппировкиКомпоновкиДанных") Или Не Поле.Использование
Или Поле.ТипГруппировки <> ТипГруппировкиКомпоновкиДанных.Элементы Тогда
ВызватьИсключение "Не совпали тип и использование собственного поля группировки";
КонецЕсли;
Если СвоеПолеВXML(Поле.Поле) <> СвоеПолеВXML(Новый ПолеКомпоновкиДанных("Склад")) Тогда
ВызватьИсключение "Не совпал полный собственный путь поля группировки";
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСвойКаталогГруппировок(Схема, Заголовки)
ПроверитьСвоюОсновуГруппировок(Схема);
Если Заголовки Тогда
Каталог = Схема.МакетыЗаголовковГруппировок;
Иначе
Каталог = Схема.МакетыГруппировок;
КонецЕсли;
Если ТипЗнч(Каталог) <> Тип("МакетыГруппировокСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужен собственный каталог правильного типа";
КонецЕсли;
Возврат Каталог;
КонецФункции
Процедура ЗаполнитьСвойМакетГруппировки(Схема, Описание, ИмяМакета, ТипМакета)
ПроверитьСвоюОсновуГруппировок(Схема);
Если ТипЗнч(Описание) <> Тип("МакетГруппировкиСхемыКомпоновкиДанных")
Или ТипЗнч(Схема.Макеты.Найти(ИмяМакета)) <> Тип("ОписаниеМакетаСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужны настоящее собственное описание группировки и существующая область";
КонецЕсли;
Если ТипМакета <> ТипМакетаОбластиКомпоновкиДанных.Заголовок
И ТипМакета <> ТипМакетаОбластиКомпоновкиДанных.Подвал Тогда
ВызватьИсключение "Используются только явно подготовленные типы заголовка и подвала";
КонецЕсли;
Описание.ИмяГруппировки = "ПоСкладу85";
Описание.Макет = ИмяМакета;
Описание.ТипМакета = ТипМакета;
Если ТипЗнч(Описание.ПоляГруппировки) <> Тип("Массив") Или Описание.ПоляГруппировки.Количество() <> 0 Тогда
ВызватьИсключение "Дополнительный массив выбора полей в этом именованном опыте должен быть пуст";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоиМакетыГруппировки(Схема, Заголовки, ИменаМакетов, ТипыМакетов)
Каталог = ПолучитьСвойКаталогГруппировок(Схема, Заголовки);
Если ИменаМакетов.Количество() <> ТипыМакетов.Количество() Или Каталог.Количество() <> ИменаМакетов.Количество() Тогда
ВызватьИсключение "Не совпал полный размер собственного каталога группировки";
КонецЕсли;
Для Индекс = 0 По ИменаМакетов.Количество() - 1 Цикл
Описание = Каталог.Получить(Индекс);
Если ТипЗнч(Описание) <> Тип("МакетГруппировкиСхемыКомпоновкиДанных")
Или Описание.ИмяГруппировки <> "ПоСкладу85" Или Описание.Макет <> ИменаМакетов[Индекс]
Или Описание.ТипМакета <> ТипыМакетов[Индекс] Или Каталог.Индекс(Описание) <> Индекс
Или Каталог[Индекс] <> Описание Тогда
ВызватьИсключение "Не совпали все имена, типы enum, ссылки и порядок собственных описаний";
КонецЕсли;
Если ТипЗнч(Описание.ПоляГруппировки) <> Тип("Массив") Или Описание.ПоляГруппировки.Количество() <> 0
Или ТипЗнч(Схема.Макеты.Найти(Описание.Макет)) <> Тип("ОписаниеМакетаСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "Нужна существующая собственная область и прежний пустой дополнительный массив";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ВосстановитьСвоиМакетыГруппировки(Схема)
Пусто = Новый Массив;
ПроверитьСвоиМакетыГруппировки(Схема, Ложь, Пусто, Пусто);
Основной = ПолучитьСвойКаталогГруппировок(Схема, Ложь);
Шапка = Основной.Добавить();
ЗаполнитьСвойМакетГруппировки(Схема, Шапка, "Склад", ТипМакетаОбластиКомпоновкиДанных.Заголовок);
Подвал = Основной.Добавить();
ЗаполнитьСвойМакетГруппировки(Схема, Подвал, "Количество", ТипМакетаОбластиКомпоновкиДанных.Подвал);
КонецПроцедурыУчебныеМакетыГруппировок85.Форма
Своя внешняя обработка УчебныеМакетыГруппировок85 → управляемая Форма → Модуль
Полный отдельный модуль собственной формы с серверным вызовом; здесь не запускался.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Именованная группировка, два каталога макетов и независимое восстановление проверены");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныеЗадачи.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Создать и проверить весь собственный источник, запрос, три полных описания полей и четыре реальные области. Добавить настоящую ГруппировкаКомпоновкиДанных в обычную Структура, дать имя ПоСкладу85 и включить использование. Добавить явное поле Склад, а не автоэлемент; задать тип Элементы.
Полный путь поля проверяется через документированную XML/XDTO-сериализацию ПолеКомпоновкиДанных в памяти и такой же самостоятельно созданный эталон Склад. Не используется догадка о преобразовании произвольного дескриптора к строке. XML-писатель закрывается и при ошибке; никакие файлы не создаются.
Схема.МакетыГруппировок и Схема.МакетыЗаголовковГруппировок — readonly ссылки на два каталога одного типа. Основной получает заголовок, отдельный — другую реально существующую область. На каждом шаге проверить настоящий тип описания, имя существующей группы, строковую ссылку на область, точное enum-значение и положение.
Вставить основной подвал по индексу0, затем Сдвинуть(Подвал,1) возвращает порядок заголовок/подвал. Enum ТипМакетаОбластиКомпоновкиДанных.Заголовок/Подвал не заменяется строкой. Временное переключение заголовка на существующую альтернативную область проверяется полностью, затем ссылка возвращается.
ПоляГруппировки у описания — readonly Массив, не коллекция настроек. В этом именованном опыте дополнительных полей выбора не задаём и явно проверяем0. Тип элементов и правила отбора этим массивом не выдумываются: пример относится к существующей группе по имени, а не к произвольной подборке полей.
Независимые схема, набор, области, группировка и два каталога создаются заново. Удалить объект основной шапки, не индекс; старую шапку больше не использовать. Отдельный каталог и копия сохраняют прежние описания. Восстановить новую шапку через Вставить(0).
Очистить только основной каталог, подтвердить0 при прежнем отдельном заголовке и неизменной копии. Восстановить новые основные описания. Отдельный заголовок удалить объектом и заново добавить, проверяя основной каталог неизменным.
Семнадцать прямых проверок оригинальных каталогов сверяют полный состав, порядок, имена и enum, а общий контроль заново проверяет реальные поля, пути, включённую группу и всё содержимое областей. Финальное состояние обеих независимых моделей одинаково по этим полным эталонам. Отчёт не компилируется и не выводится.
Как проверить результат
Будущий результат модели: ПоСкладу85 использует поле Склад и тип Элементы. Основной каталог содержит Склад/Заголовок и Количество/Подвал; отдельный каталог заголовков — КодТовара/Заголовок. Все три описания ссылаются на существующие области, дополнительный массив полей у каждого пуст; после восстановления копия и оригинал соответствуют полному эталону.
Будущий отрицательный контроль: после заполнения первого Подвал присвоить Подвал.ТипМакета = ТипМакетаОбластиКомпоновкиДанных.Заголовок, не меняя массив ожидаемых типов. Проверка должна отказать при тех же размерах, имени группы и строках ссылок. Вернуть код, сохранить/F7 вне опыта и открыть новый собственный сеанс. Здесь контроль не выполнялся.
runtimeVerifiedScenarios=0. Этот опыт проверяет собственную объектную модель и строки XML в памяти, не результат получения остатков или вид готового отчёта. Нет записей, сети, рабочих данных и печати.
Ожидаемый результат
Урок различает настоящие настройки группировки и массив полей у её макета, строки ссылок и enum, два каталога и независимую копию, с полным восстановлением.
На что обратить внимание
ПоляГруппировки у ГруппировкаКомпоновкиДанных — ПоляГруппировкиКомпоновкиДанных с Элементы. У МакетГруппировкиСхемыКомпоновкиДанных — Массив. Не переносите API между этими разными свойствами.
ИмяГруппировки и Макет — writable Строка; ТипМакета — специальный enum. Самые похожие названия не означают одинаковые типы. Readonly каталоги и массивы не присваиваются новыми объектами.
Вставить — абсолютный индекс, Сдвинуть — описание и относительное смещение, Удалить — описание. У данной коллекции нет Найти; индекс/объект не подменяются вызовом соседней коллекции.
Массив дополнительных полей оставлен пустым намеренно: его недокументированный здесь тип элементов и алгоритм выбора не выдаются за проверенный контракт. Наличие группы и её реального поля проверено независимо.
Сериализуется только ПолеКомпоновкиДанных, чей контракт разрешает XML/XDTO. Сериализатор не получает объекты метаданных, наборы записей или всю информационную базу. УстановитьСтроку не создаёт файл; Закрыть освобождает собственный писатель в обоих исходах.
В областях буквальные учебные надписи, а не вычисленные агрегаты. Каталоги не доказывают успешное применение правил компоновщиком или дизайн отчёта: настоящее выполнение/вывод в этом уроке не заявлены.
Число в ОписаниеТипов задаётся вместе со вторым аргументом КвалификаторыЧисла(1,0,Неотрицательный), а не одним именем типа. Полная проверка сначала сверяет единственный тип Число, затем тип квалификаторов, общую разрядность1, дробную0 и знак. Строковые КодТовара/Склад остаются строками без числовых квалификаторов. Не расширяйте данные за0–9 без согласованного изменения описания и его эталона; запрос и агрегат здесь не исполняются.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.