Сортировка по Количество Убыв выводит сначала Книгу, Возр сначала Ручку. Ищем настоящий элемент, его ID и пользовательский раздел; изменяются реальные строки результата, не подписи в модели.
Где и как запускать
Полный серверный общий модуль нового собственного стенда УчебныеПользовательскиеРазделы85; каждый урок запускается отдельно.
Подготовка
Создать НОВУЮ отдельную пустую учебную базу, не рабочую и не ее копию: точно8.5.1.1343, конфигурация УчебныеПользовательскиеРазделы85, совместимость Не использовать. Без бизнес-объектов, регистров, подписок, заданий и расширений.
Конфигуратор → Общие → Общие модули → УчебныеПользовательскиеРазделы85: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставить ВЕСЬ код одного выбранного урока; одноименные ВыполнитьПример из разных уроков не смешивать.
Конфигуратор → Обработки → УчебныеПользовательскиеРазделы85 → Формы → Пульт: управляемая форма; команда Выполнить, кнопка с этой командой и действие команды Выполнить. Реквизиты не нужны; полный модуль формы дан отдельно ниже.
Сохранить и обновить свою учебную конфигурацию базы данных (F7). Открыть свежий собственный клиент и учебную обработку, выполнить команду. Здесь F7 и1С не запускались: это будущие ручные шаги.
Схема и данные целиком создаются кодом: Local-запрос Книга3×250=750 / Ручка1×50=50, четыре выбранных поля и одна группа деталей. Документы и регистры не нужны.
Редактор обязательно связывается с настоящим источником доступных настроек и загружает подготовленные основные настройки. Пользовательский объект действительно ищется по своему ID и проверяется по точному типу.
Проверки используют свежий настоящий вывод для каждого состояния. XML-снимки только в памяти сохраняют целиком схему и основные настройки; файлов, архивов и резервных копий нет.
runtimeVerifiedScenarios=0. Сверка установленной справки и статические проверки не равны запуску1С. Настоящий UI редактора, долговременное сохранение, сеть, печать и production здесь не выполнялись.
Функция ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
Схема = Новый СхемаКомпоновкиДанных;
ЗаполнитьСвоиДанные(Схема);
ЗаполнитьСвоиНачальныеНастройки(Схема.НастройкиПоУмолчанию);
Элемент = Схема.НастройкиПоУмолчанию.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
Элемент.Поле = Новый ПолеКомпоновкиДанных("Количество");
Элемент.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
Элемент.Использование = Истина;
Элемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Авто;
Если Элемент.РежимОтображения <> РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Авто Тогда
ВызватьИсключение "Собственный элемент порядка должен иметь режим Авто для пользовательского состава";
КонецЕсли;
Основные = Схема.НастройкиПоУмолчанию.Порядок;
Основные.ИдентификаторПользовательскойНастройки = "ПорядокТоваров85";
Основные.ПредставлениеПользовательскойНастройки = "Направление количества";
Основные.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный;
ТекстСхемы = СвойОбъектРасшифровкиВСтроку(Схема);
Редактор = СоздатьСвойРедактор(Схема);
ТекущийПорядок = Редактор.Настройки.Порядок;
Доступное = ТекущийПорядок.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Количество"));
Если Доступное = Неопределено Или ТипЗнч(Доступное) <> Тип("ДоступноеПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Настоящий источник должен разрешить собственное поле Количество для сортировки";
КонецЕсли;
Если ТекущийПорядок.Элементы.Количество() <> 1 Тогда
ВызватьИсключение "В своем основном порядке один реальный элемент";
КонецЕсли;
ТекущийЭлемент = ТекущийПорядок.Элементы.Получить(0);
IDПорядка = ТекущийПорядок.ПолучитьИдентификаторПоОбъекту(ТекущийЭлемент);
Если IDПорядка = Неопределено Тогда
ВызватьИсключение "Собственный элемент должен получить настоящий ID своего владельца";
КонецЕсли;
Если ТипЗнч(IDПорядка) <> Тип("ИдентификаторКомпоновкиДанных")
Или ТекущийПорядок.ПолучитьОбъектПоИдентификатору(IDПорядка) <> ТекущийЭлемент Тогда
ВызватьИсключение "Обратный поиск должен вернуть собственный элемент порядка";
КонецЕсли;
Пользовательский = ПолучитьСвойПользовательскийРаздел(Редактор, "ПорядокТоваров85", Тип("ПорядокКомпоновкиДанных"));
Если Пользовательский.Элементы.Количество() <> 1 Тогда
ВызватьИсключение "В своем пользовательском порядке нужен один настоящий элемент";
КонецЕсли;
ПользовательскийЭлемент = Пользовательский.Элементы.Получить(0);
Если ТипЗнч(ПользовательскийЭлемент) <> Тип("ЭлементПорядкаКомпоновкиДанных") Тогда
ВызватьИсключение "Пользовательский порядок должен содержать реальный простой элемент, не автоэлемент";
КонецЕсли;
ПользовательскийЭлемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Авто;
Если ПользовательскийЭлемент.РежимОтображения <> РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Авто Тогда
ВызватьИсключение "В собственном user-элементе должен сохраниться разрешенный режим Авто";
КонецЕсли;
ТекстОсновных = СвойОбъектРасшифровкиВСтроку(Редактор.Настройки);
ПроверитьСвоиСтроки(Схема, Редактор.ПолучитьНастройки(), Ложь, Ложь, "Книга");
ПользовательскийЭлемент.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
ПроверитьСвоиСтроки(Схема, Редактор.ПолучитьНастройки(), Ложь, Ложь, "Ручка");
ПользовательскийЭлемент.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
ПроверитьСвоиСтроки(Схема, Редактор.ПолучитьНастройки(), Ложь, Ложь, "Книга");
Если СвойОбъектРасшифровкиВСтроку(Редактор.Настройки) <> ТекстОсновных
Или СвойОбъектРасшифровкиВСтроку(Схема) <> ТекстСхемы
Или ТекущийПорядок.ПредставлениеПользовательскойНастройки <> "Направление количества"
Или ТекущийПорядок.РежимОтображения <> РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный Тогда
ВызватьИсключение "Пользовательская сортировка не должна переписывать основные настройки или исходную схему";
КонецЕсли;
Возврат ТекущийПорядок.ПредставлениеПользовательскойНастройки + ": Убыв→Книга; Возр→Ручка; Убыв→Книга; количество4, сумма800";
КонецФункции
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
Процедура ЗаполнитьСвоиДанные(Схема)
Источник = Схема.ИсточникиДанных.Добавить();
Источник.Имя = "УчебныйИсточник";
Источник.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
Набор.Имя = "УчебныеТовары";
Набор.ИсточникДанных = Источник.Имя;
Набор.АвтоЗаполнениеДоступныхПолей = Истина;
Набор.Запрос = "ВЫБРАТЬ
| ""Книга"" КАК Наименование,
| 3 КАК Количество,
| 250 КАК Цена,
| 750 КАК Сумма
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ ""Ручка"", 1, 50, 50";
КонецПроцедуры
Процедура ЗаполнитьСвоиНачальныеНастройки(Настройки)
Для Каждого ИмяПоля Из СтрРазделить("Наименование,Количество,Цена,Сумма", ",") Цикл
Выбранное = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
Выбранное.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
Выбранное.Использование = Истина;
КонецЦикла;
Детали = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Детали.Использование = Истина;
АвтоВыбор = Детали.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
АвтоВыбор.Использование = Истина;
КонецПроцедуры
Функция СоздатьСвойРедактор(Схема)
Редактор = Новый КомпоновщикНастроекКомпоновкиДанных;
Редактор.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
Редактор.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
Возврат Редактор;
КонецФункции
Функция ПолучитьСвойПользовательскийРаздел(Редактор, Идентификатор, ТребуемыйТип)
Раздел = Редактор.ПользовательскиеНастройки.Элементы.Найти(Идентификатор);
Если Раздел = Неопределено Тогда
ВызватьИсключение "Собственный раздел должен реально появиться в пользовательских настройках";
КонецЕсли;
Если ТипЗнч(Раздел) <> ТребуемыйТип Или Раздел.ИдентификаторПользовательскойНастройки <> Идентификатор Тогда
ВызватьИсключение "Найден не тот тип или ID собственного пользовательского раздела";
КонецЕсли;
Возврат Раздел;
КонецФункции
Функция СвойОбъектРасшифровкиВСтроку(Объект)
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, Объект);
Возврат Запись.Закрыть();
КонецФункции
Процедура ПроверитьСвоиСтроки(Схема, Настройки, ТолькоКнига, БезЦены, ПервыйТовар)
Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = Компоновщик.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
Процессор = Новый ПроцессорКомпоновкиДанных;
Процессор.Инициализировать(Макет);
Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
Приемник = Новый ТаблицаЗначений;
Вывод.ОтображатьПроцентВывода = Ложь;
Вывод.УстановитьОбъект(Приемник);
Результат = Вывод.Вывести(Процессор, Ложь);
Если ТипЗнч(Результат) <> Тип("ТаблицаЗначений") Тогда
ВызватьИсключение "Нужны настоящие строки собственного вывода, не заранее заполненный приемник";
КонецЕсли;
Если Результат.Количество() <> ?(ТолькоКнига, 1, 2) Или Результат.Колонки.Количество() <> ?(БезЦены, 3, 4) Тогда
ВызватьИсключение "Не совпали фактические строки или пользовательский состав колонок";
КонецЕсли;
Для Каждого ИмяПоля Из СтрРазделить("Наименование,Количество,Сумма", ",") Цикл
Если Результат.Колонки.Найти(ИмяПоля) = Неопределено Тогда
ВызватьИсключение "Не найдена реальная колонка " + ИмяПоля;
КонецЕсли;
КонецЦикла;
Если БезЦены Тогда
Если Результат.Колонки.Найти("Цена") <> Неопределено Тогда
ВызватьИсключение "Пользователь выключил Цена: эта колонка не должна выводиться";
КонецЕсли;
ИначеЕсли Результат.Колонки.Найти("Цена") = Неопределено Тогда
ВызватьИсключение "В первоначальном отчете нужна настоящая колонка Цена";
КонецЕсли;
Книга = Результат.Найти("Книга", "Наименование");
Ручка = Результат.Найти("Ручка", "Наименование");
Если Книга = Неопределено Тогда
ВызватьИсключение "В собственном результате должна сохраниться Книга";
КонецЕсли;
Если Книга.Количество <> 3 Или Книга.Сумма <> 750 Тогда
ВызватьИсключение "Неверные настоящие числа Книги";
КонецЕсли;
Если ТолькоКнига Тогда
Если Ручка <> Неопределено Тогда
ВызватьИсключение "Ручка не должна пройти отбор Сумма больше100";
КонецЕсли;
Иначе
Если Ручка = Неопределено Тогда
ВызватьИсключение "Пользовательские настройки должны сохранить Ручку";
КонецЕсли;
Если Ручка.Количество <> 1 Или Ручка.Сумма <> 50 Тогда
ВызватьИсключение "Неверные настоящие числа Ручки";
КонецЕсли;
КонецЕсли;
Если Не БезЦены Тогда
Если Книга.Цена <> 250 Тогда
ВызватьИсключение "Неверная настоящая цена Книги";
КонецЕсли;
Если Не ТолькоКнига И Ручка.Цена <> 50 Тогда
ВызватьИсключение "Неверная настоящая цена Ручки";
КонецЕсли;
КонецЕсли;
Если Результат.Итог("Количество") <> ?(ТолькоКнига, 3, 4) Или Результат.Итог("Сумма") <> ?(ТолькоКнига, 750, 800) Тогда
ВызватьИсключение "Итоги должны рассчитываться из фактических отфильтрованных строк";
КонецЕсли;
Если ПервыйТовар <> "" И Результат[0].Наименование <> ПервыйТовар Тогда
ВызватьИсключение "Пользовательская сортировка должна изменить фактическую первую строку";
КонецЕсли;
КонецПроцедурыУчебныеПользовательскиеРазделы85.Пульт
УчебныеПользовательскиеРазделы85 → Обработки → УчебныеПользовательскиеРазделы85 → Формы → Пульт → Модуль
Полный модуль собственной управляемой формы; здесь не выполнялся.
&НаКлиенте
Процедура Выполнить(Команда)
Сообщить(ВыполнитьНаСервере());
КонецПроцедуры
&НаСервереБезКонтекста
Функция ВыполнитьНаСервере()
Возврат УчебныеПользовательскиеРазделы85.ВыполнитьПример();
КонецФункцииРазбор по шагам
Подготовить настоящий элемент Количество с направлением Убыв, Использование=Истина и режимом Авто. Это простой ЭлементПорядкаКомпоновкиДанных, не автоэлемент порядка.
Вынести весь Порядок в пользовательский раздел собственным ID, представлением и Обычным режимом. Проверить реальное доступное поле Количество у source-связанных основных настроек.
По основному действительному элементу получить настоящий ИдентификаторКомпоновкиДанных и найти тот же элемент обратно у его Порядок. Ни числовой индекс, ни строковый пользовательский ID не заменяют этот тип.
По строковому ID найти реальный пользовательский Порядок. Проверить тип его единственного элемента. РежимОтображения=Авто установить/прочитать и у собственного основного, и у пользовательского элемента.
Вывести фактические строки Убыв: первая Книга с количеством3. Поменять пользовательское направление наВозр: первая Ручка с количеством1; сами значения и итог4/800 не меняются.
Вернуть Убыв и проверить прежнюю первую Книгу. Во всех трех состояниях заново создаются макет, процессор и реальный приемник, а не сортируется заранее заполненная ожидаемая таблица.
Схема и основные настройки должны сохранить полный XML. Представление читается только у основных; фактический UI режима отображения и сохранение настроек между сеансами не проверены.
Как проверить результат
Будущий результат должен пройти все встроенные проверки реальных строк/чисел и конкретного пользовательского изменения. Каталог настроек, строковый ID и флаг сами по себе не доказывают изменение отчета.
Три состояния выполняются свежими макетами/процессорами. До пользовательского изменения, после него и после возврата проверяются собственные данные. Ни один ожидаемый приемник не заполняется вручную.
Полный XML исходной схемы и основных настроек должен совпасть с первоначальным. Пользовательское изменение действует в эффективной копии ПолучитьНастройки, не заменяет исходный основной раздел.
Отрицательный контроль будущего отдельного опыта: изменить в буквальном запросе только количество Книги3→30 при прежней сумме750. Проверка реальной ячейки должна отказать, несмотря на прежние названия и сумму.
runtimeVerifiedScenarios=0. Все проверки в BSL — будущие условия приемки собственного учебного запуска; реальный запуск здесь не выполнялся.
Ожидаемый результат
Полный код проверяет три состояния собственного пользовательского раздела, действительный результат и сохранность исходной схемы. Здесь в1С не запускался.
На что обратить внимание
ПредставлениеПользовательскойНастройки недоступно у user-объекта: читается только у основных настроек. РежимОтображения описывает поведение редактора, но настоящий интерфейс здесь не проверялся.
Строковый пользовательский ID и ИдентификаторКомпоновкиДанных для обратного поиска элемента — разные типы и разные задачи. ID берется у фактического владельца, не создается числом или строкой вручную.
ДоступныеПоля — readonly набор текущего источника. Проверяется настоящий путь через НайтиПоле; нельзя заменить набор новой коллекцией или молча продолжить при Неопределено.
После повторной ЗагрузитьНастройки пользовательский состав пересоздается. Эти уроки загружают его один раз и не держат ссылки через последующие перезагрузки.
Поля и Отбор user-правила условного оформления недоступны: в своем пользовательском правиле меняется только разрешенный флаг Использование. Исходное правило целиком сохраняется в основных настройках.
Сложные подгруппы, разные наборы, фиксированные настройки и спорные native-примечания требуют самостоятельной задачи. Здесь опыт ограничен собственной двухстрочной схемой и проверяемым действием, без универсальных обещаний.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.