ВыбранныеПоляКомпоновкиДанных

Типы · DataCompositionSelectedFields

Набор выбранных полей.

Полное описание, параметры и ограничения

ВыбранныеПоляКомпоновкиДанных (DataCompositionSelectedFields)

ВыбранныеПоляКомпоновкиДанных (DataCompositionSelectedFields)

Доступен, начиная с версии 8.1.

Свойства:
ДоступныеПоляВыбора (SelectionAvailableFields)
ИдентификаторПользовательскойНастройки (UserSettingID)
ПредставлениеПользовательскойНастройки (UserSettingPresentation)
РежимОтображения (ViewMode)
Элементы (Items)

Методы:
ПолучитьИдентификаторПоОбъекту (GetIDByObject)
ПолучитьКоличествоИспользуемых (GetUsedCount)
ПолучитьОбъектПоИдентификатору (GetObjectByID)

Описание:

Набор выбранных полей.

Доступность:

Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.
Данный объект может быть сериализован в/из XML. Может использоваться в реквизитах управляемой формы. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен {http://v8.1c.ru/8.1/data-composition-system/settings}. Имя типа XDTO: Selection.

См. также:
ТаблицаКомпоновкиДанных, свойство Выбор
ДиаграммаКомпоновкиДанных, свойство Выбор
ГруппировкаКомпоновкиДанных, свойство Выбор
ГруппировкаДиаграммыКомпоновкиДанных, свойство Выбор
ГруппировкаТаблицыКомпоновкиДанных, свойство Выбор
НастройкиКомпоновкиДанных, свойство Выбор
ТекущиеДанныеСтруктурыНастроекКомпоновкиДанных, свойство Выбор

Использование в версии:

Доступен, начиная с версии 8.1.

Методическая информация

Практические примеры

Параметр связи СКД: объявление строковых кодов и согласованные режимы = / В

Создаём свой источник A01/3 и приёмник с буквальными строками A01/500, B01/700 внутри настоящего вложенного запроса. Объявляем КодыСвязи85 в схеме, связываем его с полем источника, переключаем полное условие запроса и Булево разрешения списка вместе, проверяем восстановление и независимую копию без исполнения.

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

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

Подготовка

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

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

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

  4. Источник и приёмник объявлены самим кодом: четыре уникальных пути, в каждом наборе Строка/Число. Приёмник использует вложенный запрос как таблицу-источник, объединяющую две собственные буквальные строки; рабочих таблиц и неизвестных параметров нет.

  5. Числовые поля имеют разные явные учебные контракты: КоличествоИсточника — целое 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 → управляемая Форма → Модуль

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

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

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

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

  1. Полностью объявить свой параметр Схема.Параметры.Добавить(): имя КодыСвязи85, ОписаниеТипов("Строка"), строковое значение по умолчанию пустое, использование Авто. В КА2 АнализСчета настоящий параметр связи Ссылки также объявлен в схеме, тип соответствует полю источника.

  2. Не устанавливать Всегда механически: по справке этот режим всегда использует значение настройки. В своём опыте проверяется Авто и передача кода через Параметр связи; пустой default не выдаётся за полученное значение источника.

  3. Параметр свойства связи — имя без амперсанда: КодыСвязи85. В запросе используется &КодыСвязи85. Значение определяется ВыражениеИсточник="КодИсточника"; ВыражениеПриемник="КодПриемника" указывает реальный ключ приёмника. ЦенаПриемника нужна в выборе; источник кода также выбран.

  4. Скалярная версия запроса содержит Данные.Код = &КодыСвязи85 и РазрешенСписокПараметров=Ложь. Списочная версия содержит Данные.Код В (&КодыСвязи85) и флаг Истина. СвойЗапросПриемника возвращает полный точный запрос режима, а УстановитьСвойРежимСвязи меняет запрос и флаг согласованно.

  5. Условие находится во внешнем запросе с настоящим ИЗ (вложенный запрос) КАК Данные, не в выдуманном ГДЕ без источника. Вложенные источники документированы установленной справкой; поля Данные.Код/Цена объявлены внутренним списком выборки.

  6. Восемь контрольных состояний оригинала проверяют полный источник, оба текста запросов, все поля/типы/порядок, весь параметр, его положительный/отрицательный поиск, выбор, обе стороны связи, имя параметра, реальный Булево и каталог. Флаг списка не считается доказанным только по названию свойства.

  7. Копия создаётся заново со своим параметром и исходным запросом =. Во время режима В оригинала копия остаётся скалярной. После возврата режима удалить текущую связь как объект, не индекс, подтвердить0 при сохранённом объявлении параметра и запросах, создать новую; очистить оригинальный каталог и восстановить снова.

  8. Списочный режим разрешает обработку списка, но код не присваивает Массив строковому ТипЗначения параметра и не запускает движок. Конкретная упаковка значений компоновщиком и данные результата остаются будущей runtime-проверкой.

  9. СвойТипПоляПараметра различает все четыре настоящих имени поля: коды Строка, количество Число(1,0,Неотрицательный), цена Число(3,0,Неотрицательный). Проверка каждого числового поля сверяет все три квалификатора, а не только наличие Число в Типы(). Строковый параметр КодыСвязи85, запросы и переключение = / В остаются прежними.

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

  1. Будущий итог проверки модели: единственный строковый КодыСвязи85 с пустым default/Авто; два исходных набора и полный скалярный запрос; одна связь Источник85→Приемник85, КодИсточника→КодПриемника, Параметр=КодыСвязи85, флаг списка Ложь. Копия сохраняет то же исходное состояние.

  2. Буквальные строки задают A01/500 и B01/700. По математической логике = для A01 выбирает первый код, а В для списка A01/B01 допускает оба кода, но здесь список источников не формировался и запрос не выполнялся: это объяснение режимов, не полученные строки или обещание производительности.

  3. Будущий отрицательный контроль: после согласованного перехода в режим В вручную заменить только Связь.РазрешенСписокПараметров на Ложь, не меняя эталон Истина и полный запрос. Проверка должна отказать. Альтернативно заменить имя параметра связи на НетТакогоПараметра85 при прежних запросах. Вернуть код, сохранить/F7 вне опыта и открыть новый свой сеанс; здесь контроль не выполнялся.

  4. runtimeVerifiedScenarios=0. Сохранность прежних материалов и native-контракты проверяются статически. Нет выполнения 1С, запросов, записи, сети, реального компоновщика, печати или изменения конфигураций пользователя.

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

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

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

  1. Параметр связи хранит имя параметра, не его значение и не текст &КодыСвязи85. Амперсанд нужен в языке запроса; строка свойства задаётся без него. Полный текст запроса не сводится к поиску подстроки В.

  2. Список допустим при использовании параметра в операции В. Не включайте Истина при сохранённом сравнении = и не подменяйте ОписаниеТипов строкового элемента типом Массив без документированного основания.

  3. Авто и Всегда имеют разный смысл. Этот урок не утверждает, что default пустой станет A01 сам по себе: это работа будущего компоновщика при использовании связи, здесь ни её исполнение, ни фактическая передача не проверялись.

  4. Буквальный вложенный запрос позволяет изучать контракты без чужих таблиц. Наличие параметрической связи не обещает выполненный SQL, количество обращений или готовый визуальный отчёт.

  5. Копия содержит новые собственные объекты. После Удалить и Очистить старые ссылки связи не используются; объявление параметра и оба набора сохраняются. XML получает только собственное ПолеКомпоновкиДанных и пишет строку в памяти.

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

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

Ресурсы СКД: количество и выручка по складу, общий итог и восстановление

Для собственного учебного отчёта объявляем числовые Количество и Выручка, реальное поле Склад, обычную группу и выбор обоих числовых полей. Создаём формулы суммирования, отличаем пустое ограничение от ОбщийИтог, переставляем и удаляем ресурсы, проверяем поиск и восстановление всего состояния без запуска отчёта.

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

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

Подготовка

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

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

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

  4. Код сам объявляет Local-источник СвоиРесурсы85 и набор ОбъемИВыручка85 с буквальным запросом Склад="Учебный", Количество=3, Выручка=1500. Поля заданы вручную как Строка/Число/Число. Рабочие справочники, регистры и внешние неизвестные объекты не нужны.

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

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

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

Функция СоздатьСвоюОсновуРесурсов()
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "СвоиРесурсы85";
    Источник.ТипИсточникаДанных = "Local";
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
    Если ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужен собственный набор запроса";
    КонецЕсли;
    Набор.Имя = "ОбъемИВыручка85";
    Набор.ИсточникДанных = "СвоиРесурсы85";
    Набор.АвтоЗаполнениеДоступныхПолей = Ложь;
    Набор.Запрос = "ВЫБРАТЬ ""Учебный"" КАК Склад, 3 КАК Количество, 1500 КАК Выручка";
    Имена = СтрРазделить("Склад,Количество,Выручка", ",");
    Типы = СтрРазделить("Строка,Число,Число", ",");
    Для Индекс = 0 По 2 Цикл
        Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
        Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
            ВызватьИсключение "Нужно свое явно объявленное поле, не папка";
        КонецЕсли;
        Поле.Поле = Имена[Индекс];
        Поле.ПутьКДанным = Имена[Индекс];
        Поле.ТипЗначения = Новый ОписаниеТипов(Типы[Индекс]);
    КонецЦикла;
    Группа = Схема.НастройкиПоУмолчанию.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
    Если ТипЗнч(Группа) <> Тип("ГруппировкаКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужна собственная обычная группа настроек";
    КонецЕсли;
    Группа.Имя = "ПоСкладу85";
    Группа.Использование = Истина;
    ПолеГруппы = Группа.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
    Если ТипЗнч(ПолеГруппы) <> Тип("ПолеГруппировкиКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужно собственное явное поле группировки";
    КонецЕсли;
    ПолеГруппы.Поле = Новый ПолеКомпоновкиДанных("Склад");
    ПолеГруппы.Использование = Истина;
    ПолеГруппы.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
    Для Индекс = 1 По 2 Цикл
        Выбор = Схема.НастройкиПоУмолчанию.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
        Если ТипЗнч(Выбор) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
            ВызватьИсключение "Нужно собственное явное выбранное поле";
        КонецЕсли;
        Выбор.Поле = Новый ПолеКомпоновкиДанных(Имена[Индекс]);
        Выбор.Использование = Истина;
    КонецЦикла;
    ПроверитьСвоюОсновуРесурсов(Схема);
    Возврат Схема;
КонецФункции

Процедура ПроверитьСвоюОсновуРесурсов(Схема)
    Если ТипЗнч(Схема) <> Тип("СхемаКомпоновкиДанных")
        Или Схема.ИсточникиДанных.Количество() <> 1 Или Схема.НаборыДанных.Количество() <> 1
        Или Схема.НастройкиПоУмолчанию.Структура.Количество() <> 1
        Или Схема.НастройкиПоУмолчанию.Выбор.Элементы.Количество() <> 2 Тогда
        ВызватьИсключение "Нужны прежние свои источник, набор, группа и два выбранных поля";
    КонецЕсли;
    Источник = Схема.ИсточникиДанных.Получить(0);
    Если ТипЗнч(Источник) <> Тип("ИсточникДанныхСхемыКомпоновкиДанных")
        Или Источник.Имя <> "СвоиРесурсы85" Или Источник.ТипИсточникаДанных <> "Local" Тогда
        ВызватьИсключение "Не совпал полный собственный источник";
    КонецЕсли;
    Набор = Схема.НаборыДанных.Получить(0);
    Если ТипЗнч(Набор) <> Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда
        ВызватьИсключение "Нужен собственный набор запроса";
    КонецЕсли;
    Если Набор.Имя <> "ОбъемИВыручка85" Или Набор.ИсточникДанных <> "СвоиРесурсы85"
        Или Набор.АвтоЗаполнениеДоступныхПолей Или Набор.Запрос <> "ВЫБРАТЬ ""Учебный"" КАК Склад, 3 КАК Количество, 1500 КАК Выручка"
        Или Набор.Поля.Количество() <> 3 Тогда
        ВызватьИсключение "Не совпали полный собственный запрос и ручное объявление полей";
    КонецЕсли;
    Имена = СтрРазделить("Склад,Количество,Выручка", ",");
    Типы = СтрРазделить("Строка,Число,Число", ",");
    Для Индекс = 0 По 2 Цикл
        Поле = Набор.Поля.Получить(Индекс);
        Если ТипЗнч(Поле) <> Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")
            Или Поле.Поле <> Имена[Индекс] Или Поле.ПутьКДанным <> Имена[Индекс]
            Или ТипЗнч(Поле.ТипЗначения) <> Тип("ОписаниеТипов") Тогда
            ВызватьИсключение "Не совпали полные пути, порядок и типы собственных полей";
        КонецЕсли;
        ПолныеТипы = Поле.ТипЗначения.Типы();
        Если ПолныеТипы.Количество() <> 1 Или ПолныеТипы[0] <> Тип(Типы[Индекс]) Тогда
            ВызватьИсключение "Не совпал полный набор типов собственного поля";
        КонецЕсли;
    КонецЦикла;
    Группа = Схема.НастройкиПоУмолчанию.Структура.Получить(0);
    Если ТипЗнч(Группа) <> Тип("ГруппировкаКомпоновкиДанных") Или Группа.Имя <> "ПоСкладу85"
        Или Не Группа.Использование Или ТипЗнч(Группа.ПоляГруппировки) <> Тип("ПоляГруппировкиКомпоновкиДанных") Тогда
        ВызватьИсключение "Не совпала собственная обычная группа по складу";
    КонецЕсли;
    Если Группа.ПоляГруппировки.Элементы.Количество() <> 1 Тогда
        ВызватьИсключение "В своей группе ровно одно явно заданное поле склада";
    КонецЕсли;
    ПолеГруппы = Группа.ПоляГруппировки.Элементы.Получить(0);
    Если ТипЗнч(ПолеГруппы) <> Тип("ПолеГруппировкиКомпоновкиДанных") Или Не ПолеГруппы.Использование
        Или ПолеГруппы.ТипГруппировки <> ТипГруппировкиКомпоновкиДанных.Элементы Тогда
        ВызватьИсключение "Не совпал тип используемого собственного поля группы";
    КонецЕсли;
    Если СвоеПолеВXML(ПолеГруппы.Поле) <> СвоеПолеВXML(Новый ПолеКомпоновкиДанных("Склад")) Тогда
        ВызватьИсключение "Не совпал полный собственный путь группировки";
    КонецЕсли;
    Для Индекс = 0 По 1 Цикл
        Выбор = Схема.НастройкиПоУмолчанию.Выбор.Элементы.Получить(Индекс);
        Если ТипЗнч(Выбор) <> Тип("ВыбранноеПолеКомпоновкиДанных") Или Не Выбор.Использование Тогда
            ВызватьИсключение "Нужно используемое собственное выбранное числовое поле";
        КонецЕсли;
        Если СвоеПолеВXML(Выбор.Поле) <> СвоеПолеВXML(Новый ПолеКомпоновкиДанных(Имена[Индекс + 1])) Тогда
            ВызватьИсключение "Не совпали полные пути и порядок выбранных ресурсов";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

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

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

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

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

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

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

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

  1. Построить всю собственную основу: точный текст запроса, три полных пути/типа, включённую обычную группу ПоСкладу85 по полю Склад и выбор используемых Количество/Выручка. Полные пути объектов ПолеКомпоновкиДанных сравниваются через собственную XML-строку в памяти, не через выдуманное строковое представление.

  2. Каталог Схема.ПоляИтога readonly, но его методы меняют собственное содержимое. Добавить без параметров возвращает реальное ПолеИтогаСхемыКомпоновкиДанных. Для Количество задать путь Количество и формулу Сумма(Количество); первоначально Группировки пусты.

  3. Вставить(0) создаёт Выручка с формулой Сумма(Выручка). В его собственный массив Группировки добавить строки Склад и ОбщийИтог. Здесь Склад — имя поля, а ПоСкладу85 — имя объекта группы настроек: подменять одно другим нельзя.

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

  5. Сдвинуть(Выручка,1) принимает текущий объект и относительное смещение; Вставить принимает абсолютный индекс. Найти получает полный собственный путь, что подтверждено использованием ПоляИтога.Найти(Поле.ПутьКДанным) в коде КА2. Проверяются положительный поиск и документированное Неопределено для отсутствующего ресурса.

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

  7. Заново построить независимую собственную схему и два её ресурса. Удалить объект Количество, не индекс; старую ссылку не использовать. Копия сохраняет прежние пути/формулы/массивы. Восстановить новым Вставить(0), затем очистить только каталог оригинала, подтвердить0 при сохранённой основе и копии, заново добавить два новых описания.

  8. Readonly у Группировки запрещает замену свойства целиком, но не показанные Добавить/Очистить его собственного массива. В УНФ ОтчетыУНФ есть реальный цикл Ресурс.Группировки.Очистить(), добавление имён полей и ОбщийИтог; этот урок не вызывает тот рабочий модуль.

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

  1. Будущий результат проверки модели: два ресурса в порядке Количество/Выручка; точные формулы Сумма(Количество)/Сумма(Выручка); первый массив пуст, второй содержит Склад, ОбщийИтог. Источник, ручные типы, группа ПоСкладу85 и выбор числовых полей остаются прежними после удаления и очистки.

  2. При будущем разрешённом выполнении отчёта заданная единственная строка позволила бы ожидать количество3 и выручку1500. Сейчас эти числа — литералы декларации, а формулы — строки модели: агрегаты не вычислялись и не выдаются за полученные результаты.

  3. Будущий отрицательный контроль: после заполнения выручки заменить Выручка.Группировки[0] = "ПоСкладу85", не меняя эталон. Проверка должна отказать при прежних размерах и формуле, потому что нужен путь поля Склад. Вернуть исходный код, сохранить/F7 вне опыта и открыть новый собственный сеанс. Здесь контроль не выполнялся.

  4. runtimeVerifiedScenarios=0. Сохранность всех прежних уроков, native-контракты и поиск проверяются статически. Нет выполнения запросов, компоновщика, процессора, записи, сети, печати или изменений конфигураций пользователя.

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

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

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

  1. Группировки хранит имена полей, а не имя объекта ГруппировкаКомпоновкиДанных. Для своего строкового поля Склад не добавляется суффикс Иерархия: иерархических данных в этом опыте нет. ОбщийИтог — специальная документированная строка, не глобальный enum.

  2. Суммируются именно явно объявленные числовые Количество/Выручка. Путь ресурса и формула — разные строки; сохранённое число ресурсов не гарантирует правильный путь, выражение или ограничение расчёта.

  3. Найти может вернуть Неопределено. Не обращайтесь к свойствам отсутствующего результата; этот код проверяет отсутствие прямо. На ресурсах свои полные пути уникальны, поэтому положительный поиск не зависит от дублей.

  4. Удалить принимает ресурс, Вставить — индекс, Сдвинуть — ресурс/смещение. После Удалить и Очистить прежние ссылки ресурсов не применяются. Копия собирается из собственных строк заново; дочерние объекты одной схемы не передаются другой.

  5. Имя и ПоляГруппировки здесь доступны у обычной группы НастройкиПоУмолчанию, а не у объектов пользовательских настроек. XML-писатель сериализует только свое ПолеКомпоновкиДанных, пишет в память и закрывается при успехе и исключении.

  6. Урок показывает контракты и проверку модели, не готовое визуальное оформление отчёта. Пока нет выполнения в1С, нельзя обещать увиденные итоги или runtime-корректность.

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

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

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

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

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