Тип: РежимИзмененияСвязанногоЗначения. Указывает, каким образом изменять связаное значение.
Полное описание, параметры и ограничения
СвязьПараметраВыбораКомпоновкиДанных.ИзменениеЗначения (DataCompositionChoiceParameterLink.ValueChange)
СвязьПараметраВыбораКомпоновкиДанных (DataCompositionChoiceParameterLink)
ИзменениеЗначения (ValueChange)
Доступен, начиная с версии 8.2.
Использование:
Только чтение.
Описание:
Тип: РежимИзмененияСвязанногоЗначения.
Указывает, каким образом изменять связаное значение.
Доступность:
Тонкий клиент, веб-клиент, толстый клиент.
Использование в версии:
Доступен, начиная с версии 8.2.
Методическая информация
Практические примеры
Локальный учебный preview: свои связи выбора и подбор750 → 950 → 50 → 1000
Собственные native коллекции выбора СКД используются явно написанным локальным потребителем. Это НЕ изменение стандартной формы выбора/metadata/связей компоновщика: документированного setter такого применения в уроке нет. Полный builder, настоящие native фабрики и только собственные типизированные товары в памяти.
Где и как запускать
Полный непривилегированный common moduleУчебныйПредпросмотр85, клиент обычного приложения. Только thick ordinary8.5.1.1343; own память/частнаяВТ, не server/thin/web.
Подготовка
Создайте вручную отдельную новую пустую файловуюИБ8.5.1.1343. Не используйте рабочуюИБ, копию УНФ/КА/УТ/БП, серверную production базу или чужую форму выбора. Здесь выполнено только авторство/static checks; созданиеИБ, обновление конфигурации и запуск не выполнялись.
Конфигуратор → Конфигурация → Открыть конфигурацию. Имя корня=УчебныйЛокальныйПодбор85, Основной режим запуска=Обычное приложение, Режим совместимости=Не использовать. Учебный запуск именно толстым клиентом в обычном приложении.
Оставьте пустыми справочники, документы, перечисления, планы, регистры, отчеты, обработки, константы, параметры сеанса, подписки, задания, общие реквизиты и хранилища настроек. Никаких расширений, BSP, чужих библиотек или автоматических обработчиков. Код проверяет пустые business metadata и три источника расширений, но новаяИБ/отсутствие чужого кода требуют ручной подготовки.
Общие → Общие модули → Добавить УчебныйПредпросмотр85. Клиент(обычное приложение)=Да; Клиент(управляемое приложение)=Нет; Сервер=Нет; Внешнее соединение=Нет; Глобальный=Нет; Привилегированный=Нет; Вызов сервера=Нет; Повторное использование возвращаемых значений=Не использовать. Вставьте весь основной блок кода целиком на уровне модуля. Директивы#Если/#КонецЕсли уже включены.
Общие → Общие формы → Добавить УчебныйЛокальныйВыбор85. Тип формы=Обычная, это единственная общая форма. В ее модуль вставьте весь вспомогательный блок «Полный модуль своей обычной формы». Никаких &НаКлиенте/&НаСервере и управляемых форм здесь нет.
В реквизиты формы добавьте Результат85 типаТабличныйДокумент. Поместите на форму Поле табличного документа, имяПолеРезультата85, Данные=Результат85. Оставьте только просмотр результата, без команд печати/файлового сохранения.
Добавьте обычную кнопкуВыполнить85 с Действие=Выполнить85. АргументКнопка предоставляет платформа; не создавайте фиктивный объект кнопки и не вызывайте обработчик напрямую.
Корень конфигурации → Модуль обычного приложения. Он должен быть пустым. Вставьте весь блок «Полный модуль обычного приложения». СобытиеПриНачалеРаботыСистемы открывает только подготовленную собственную общую форму; вычисления запускаются явной кнопкой.
Создайте только своего учебного пользователя/учебную роль с доступом к запуску и этой форме. Не включайте обработчики авторизации, фоновые задания, сервисы или связи с внешними системами. Это не образец production прав.
Проверьте синтаксис всех трех полных модулей и вручную обновите конфигурацию только своей новойИБ. Запустите ее толстым клиентом8.5.1.1343 в обычном приложении. Никаких внешних объектов или исходных файлов готовить не нужно.
НажмитеВыполнить85. Код создает реальныйUUID и типизированнуюТаблицаЗначений сBOOK(PAPER,3,250,750), PAD(PAPER,2,100,200), PEN(OFFICE,1,50,50). Эти единственные данные находятся в памяти, передаются в свою частную временную таблицу и проверяются по всем полям.
Полный builder создает собственнуюСхемаКомпоновкиДанных: источникLocal, один объектный наборСвоиТовары с шестью типизированными полями и три параметраКатегорияВыбора/ЦенаМин/ТоварВыбора. ИмяОбъекта совпадает с реальным ключом структурыДанныеОбъектов; неизвестного внешнего источника/запроса к metadata нет.
Компоновщик получает источник по собственной схеме. Берем реальные Компоновщик.Настройки, доступные толстому клиенту по справке свойства Настройки. Настройки должны фактически иметь ДоступныеПараметры и ТоварВыбора; при отсутствии программа останавливается с OWN-PREVIEW-NO-AVAILABLE/NO-PARAMETER. Источник, схема и компоновщик удерживаются в собственном контексте до конца процесса. Не заменяйте отсутствие выдуманным параметром.
Настоящие коллекции получаем только методамиGetChoice* настоящего доступного параметра. Перед добавлением обе должны иметьКоличество()=0. При непустой исходной коллекции стоп: мы не удаляем неизвестные автоматически добавленные элементы.
У собственного элементаПараметрВыбора задаемЦенаМин=200. ЧерезДобавить/Вставить создаем две настоящие связи сПолеКомпоновкиДанных; проверяемИндекс/Получить, сдвигаем именно свой объектЦена на одну позицию и проверяем фактический новый порядок. Далее работает собственный явно заданный потребитель, не стандартная форма выбора.
Предпросмотр строит параметризованный Запрос только к ВТСвоиТовары своего МенеджерВременныхТаблиц. Native имена/поля/значение200 определяют включение условий. После каждого этапа проверяются точные коды, UUID, числовые поля и суммы: BOOK750 → PAPER950 после удаления связи цены → OFFICE50 после изменения категории собственного memory компоновщика native setter УстановитьЗначениеПараметра → все1000 после очистки только подтвержденной собственной коллекции.
ИзменениеЗначения readonly: код читает настоящий режимКатегория.ИзменениеЗначения и принимает толькоОчищать/НеИзменять. Он применяется явно нашей функцией к собственной переменной выбора; не заявляется автоматическое поведение платформы. Даже сохраненныйBOOK не подтверждается допустимым приOFFICE, чей набор содержит толькоPEN.
Отдельные6 отрицательных случаев создают6 свежих собственных контекстов: неверный тип коллекции, чужое поле, дубликат связи, строка200 вместо числа, сумма749 и угаданныйdefault политики. Принимается только соответствующий собственный маркер, неожиданная ошибка передается дальше. Исходные успешные контекст/товары не исправляются слепым rollback.
Ожидаемый при ручном запуске результат: протокол750/950/50/1000, фактическая политика и6 отказов, затем таблица трех своих товаров. СтараяРезультат85 заменяется только после полного завершения. Это не гарантия атомарности действий формы и не доказательство фактического запуска1С здесь.
Закройте собственную форму/сеанс: данные, схемы, кандидаты и вывод находятся в памяти. Свой менеджерВТ закрывается на успехе и при ошибке; не объявляется rollbackИБ или гарантированное сохранение первичного исключения при ошибке самого закрытия. Файлы, сеть, сохраненные пользовательские настройки, metadata, стандартная форма выбора и рабочиеИБ не изменяются. Native setter меняет только настройки собственного компоновщика в памяти.
#Если ТолстыйКлиентОбычноеПриложение Тогда
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвоюСхему()
ПроверитьСвойПустойСтенд();
Если Метаданные.ОбщиеМодули.Количество() <> 1
Или Метаданные.ОбщиеМодули.Найти("УчебныйПредпросмотр85") = Неопределено
Или Метаданные.ОбщиеФормы.Количество() <> 1
Или Метаданные.ОбщиеФормы.Найти("УчебныйЛокальныйВыбор85") = Неопределено
Или Метаданные.Обработки.Количество() <> 0 Или Метаданные.Отчеты.Количество() <> 0
Или Метаданные.Константы.Количество() <> 0 Или Метаданные.ПараметрыСеанса.Количество() <> 0
Или Метаданные.ХранилищаНастроек.Количество() <> 0 Тогда
ВызватьИсключение "Нужны только свои один общий модуль и одна обычная общая форма";
КонецЕсли;
КонецПроцедуры
Функция СоздатьТовары(СвойUUID)
Товары = Новый ТаблицаЗначений;
Товары.Колонки.Добавить("UUID", Новый ОписаниеТипов("УникальныйИдентификатор"));
Товары.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
Товары.Колонки.Добавить("Категория", Новый ОписаниеТипов("Строка"));
ЧисловойТип = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9, 2, ДопустимыйЗнак.Неотрицательный));
Для Каждого Имя Из СтрРазделить("Количество,Цена,Сумма", ",") Цикл
Товары.Колонки.Добавить(Имя, ЧисловойТип);
КонецЦикла;
Книга = Товары.Добавить();
Книга.UUID = СвойUUID;
Книга.Код = "BOOK";
Книга.Категория = "PAPER";
Книга.Количество = 3;
Книга.Цена = 250;
Книга.Сумма = 750;
Блокнот = Товары.Добавить();
Блокнот.UUID = СвойUUID;
Блокнот.Код = "PAD";
Блокнот.Категория = "PAPER";
Блокнот.Количество = 2;
Блокнот.Цена = 100;
Блокнот.Сумма = 200;
Ручка = Товары.Добавить();
Ручка.UUID = СвойUUID;
Ручка.Код = "PEN";
Ручка.Категория = "OFFICE";
Ручка.Количество = 1;
Ручка.Цена = 50;
Ручка.Сумма = 50;
Возврат Товары;
КонецФункции
Процедура ПроверитьТовары(Товары, СвойUUID)
Если ТипЗнч(СвойUUID) <> Тип("УникальныйИдентификатор") Или ТипЗнч(Товары) <> Тип("ТаблицаЗначений") Тогда
ВызватьИсключение "OWN-PREVIEW-DATA-TYPE";
КонецЕсли;
Если Товары.Колонки.Количество() <> 6 Или Товары.Количество() <> 3 Тогда
ВызватьИсключение "OWN-PREVIEW-FIXTURE";
КонецЕсли;
Ожидания = СоздатьТовары(СвойUUID);
Для Индекс = 0 По 5 Цикл
Колонка = Товары.Колонки.Получить(Индекс);
ОжидаемаяКолонка = Ожидания.Колонки.Получить(Индекс);
Если Колонка.Имя <> ОжидаемаяКолонка.Имя
Или Колонка.ТипЗначения <> ОжидаемаяКолонка.ТипЗначения Тогда
ВызватьИсключение "OWN-PREVIEW-FIXTURE";
КонецЕсли;
КонецЦикла;
Для Индекс = 0 По 2 Цикл
Факт = Товары.Получить(Индекс);
Ожидание = Ожидания.Получить(Индекс);
Если Факт.UUID <> СвойUUID Или Факт.Код <> Ожидание.Код Или Факт.Категория <> Ожидание.Категория
Или Факт.Количество <> Ожидание.Количество Или Факт.Цена <> Ожидание.Цена
Или Факт.Сумма <> Ожидание.Сумма Или Факт.Количество * Факт.Цена <> Факт.Сумма Тогда
ВызватьИсключение "OWN-PREVIEW-FIXTURE";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция СоздатьКонтекст(СвойUUID)
Товары = СоздатьТовары(СвойUUID);
ПроверитьТовары(Товары, СвойUUID);
Схема = Новый СхемаКомпоновкиДанных;
ИсточникСхемы = Схема.ИсточникиДанных.Добавить();
ИсточникСхемы.Имя = "СвойЛокальныйИсточник";
ИсточникСхемы.ТипИсточникаДанных = "Local";
Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
Если ТипЗнч(Набор) <> Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-SCHEMA";
КонецЕсли;
Набор.Имя = "СвоиТовары";
Набор.ИсточникДанных = ИсточникСхемы.Имя;
Набор.ИмяОбъекта = "СвоиТовары";
Для Каждого Колонка Из Товары.Колонки Цикл
Поле = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.Поле = Колонка.Имя;
Поле.ПутьКДанным = Колонка.Имя;
Поле.ТипЗначения = Колонка.ТипЗначения;
КонецЦикла;
Для Каждого Имя Из СтрРазделить("КатегорияВыбора,ЦенаМин,ТоварВыбора", ",") Цикл
Параметр = Схема.Параметры.Добавить();
Параметр.Имя = Имя;
Параметр.ВключатьВДоступныеПоля = Истина;
Параметр.Использование = ИспользованиеПараметраКомпоновкиДанных.Всегда;
Если Имя = "ЦенаМин" Тогда
Параметр.ТипЗначения = Товары.Колонки.Найти("Цена").ТипЗначения;
Параметр.Значение = 0;
Иначе
Параметр.ТипЗначения = Новый ОписаниеТипов("Строка");
Если Имя = "КатегорияВыбора" Тогда
Параметр.Значение = "PAPER";
Иначе
Параметр.Значение = "BOOK";
КонецЕсли;
КонецЕсли;
КонецЦикла;
ДанныеОбъектов = Новый Структура("СвоиТовары", Товары);
Если Не ДанныеОбъектов.Свойство(Набор.ИмяОбъекта, ФактическиеТовары) Или ФактическиеТовары <> Товары
Или Набор.Поля.Количество() <> Товары.Колонки.Количество() Тогда
ВызватьИсключение "OWN-PREVIEW-SOURCE";
КонецЕсли;
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема);
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
Компоновщик.Инициализировать(ИсточникНастроек);
СвоиНастройки = Компоновщик.Настройки;
Если ТипЗнч(СвоиНастройки) <> Тип("НастройкиКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-SETTINGS";
КонецЕсли;
Доступные = СвоиНастройки.ПараметрыДанных.ДоступныеПараметры;
Если ТипЗнч(Доступные) <> Тип("ДоступныеПараметрыКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-NO-AVAILABLE: свой native компоновщик не связал доступные параметры; остановитесь";
КонецЕсли;
ОписаниеВыбора = Доступные.НайтиПараметр(Новый ПараметрКомпоновкиДанных("ТоварВыбора"));
Если ТипЗнч(ОписаниеВыбора) <> Тип("ДоступныйПараметрКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-NO-PARAMETER";
КонецЕсли;
Связи = ОписаниеВыбора.ПолучитьСвязиПараметровВыбора();
ПараметрыВыбора = ОписаниеВыбора.ПолучитьПараметрыВыбора();
Если ТипЗнч(Связи) <> Тип("СвязиПараметровВыбораКомпоновкиДанных")
Или ТипЗнч(ПараметрыВыбора) <> Тип("ПараметрыВыбораКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-COLLECTIONS";
КонецЕсли;
Если Связи.Количество() <> 0 Или ПараметрыВыбора.Количество() <> 0 Тогда
ВызватьИсключение "OWN-PREVIEW-NOT-EMPTY: чужие или автоматически заполненные коллекции не очищаем";
КонецЕсли;
МинимальнаяЦена = ПараметрыВыбора.Добавить();
Если ТипЗнч(МинимальнаяЦена) <> Тип("ПараметрВыбораКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-CHOICE-TYPE";
КонецЕсли;
МинимальнаяЦена.Имя = "ЦенаМин";
МинимальнаяЦена.Значение = 200;
Если ПараметрыВыбора.Количество() <> 1 Или ПараметрыВыбора.Получить(0).Имя <> "ЦенаМин"
Или ПараметрыВыбора.Получить(0).Значение <> 200 Тогда
ВызватьИсключение "OWN-PREVIEW-CHOICE-READBACK";
КонецЕсли;
СвоиНастройки.ПараметрыДанных.УстановитьЗначениеПараметра("КатегорияВыбора", "PAPER");
СвоиНастройки.ПараметрыДанных.УстановитьЗначениеПараметра("ЦенаМин", МинимальнаяЦена.Значение);
Категория = Связи.Добавить();
Если ТипЗнч(Категория) <> Тип("СвязьПараметраВыбораКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-TYPE";
КонецЕсли;
Категория.Имя = "Категория";
Категория.Поле = Новый ПолеКомпоновкиДанных("ПараметрыДанных.КатегорияВыбора");
Цена = Связи.Вставить(0);
Цена.Имя = "Цена";
Цена.Поле = Новый ПолеКомпоновкиДанных("ПараметрыДанных.ЦенаМин");
Если Связи.Количество() <> 2 Или Связи.Индекс(Цена) <> 0 Или Связи.Индекс(Категория) <> 1
Или Связи.Получить(0).Имя <> "Цена" Или Связи.Получить(1).Имя <> "Категория" Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-ORDER";
КонецЕсли;
Связи.Сдвинуть(Цена, 1);
Если Связи.Индекс(Цена) <> 1 Или Связи.Индекс(Категория) <> 0
Или Связи.Получить(0).Имя <> "Категория" Или Связи.Получить(1).Имя <> "Цена" Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-MOVE";
КонецЕсли;
Политика = Категория.ИзменениеЗначения;
Если ТипЗнч(Политика) <> Тип("РежимИзмененияСвязанногоЗначения") Тогда
ВызватьИсключение "OWN-PREVIEW-POLICY";
КонецЕсли;
Если Политика <> РежимИзмененияСвязанногоЗначения.Очищать
И Политика <> РежимИзмененияСвязанногоЗначения.НеИзменять Тогда
ВызватьИсключение "OWN-PREVIEW-POLICY";
КонецЕсли;
Возврат Новый Структура("UUID,Схема,Источник,Компоновщик,ДанныеОбъектов,Настройки,Связи,ПараметрыВыбора,Категория,Цена,Политика",
СвойUUID, Схема, ИсточникНастроек, Компоновщик, ДанныеОбъектов, СвоиНастройки, Связи, ПараметрыВыбора, Категория, Цена, Политика);
КонецФункции
Функция ПолучитьУсловия(Контекст)
Если ТипЗнч(Контекст.Схема) <> Тип("СхемаКомпоновкиДанных")
Или ТипЗнч(Контекст.Источник) <> Тип("ИсточникДоступныхНастроекКомпоновкиДанных")
Или ТипЗнч(Контекст.Компоновщик) <> Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-OWNER";
КонецЕсли;
Если ТипЗнч(Контекст.Связи) <> Тип("СвязиПараметровВыбораКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-LINKS-TYPE";
КонецЕсли;
Если Контекст.ПараметрыВыбора.Количество() <> 1 Тогда
ВызватьИсключение "OWN-PREVIEW-CHOICE-COUNT";
КонецЕсли;
МинимальнаяЦена = Контекст.ПараметрыВыбора.Получить(0);
Если ТипЗнч(МинимальнаяЦена) <> Тип("ПараметрВыбораКомпоновкиДанных")
Или МинимальнаяЦена.Имя <> "ЦенаМин" Или ТипЗнч(МинимальнаяЦена.Значение) <> Тип("Число")
Или МинимальнаяЦена.Значение <> 200 Тогда
ВызватьИсключение "OWN-PREVIEW-CHOICE-VALUE";
КонецЕсли;
ПараметрКатегории = Контекст.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КатегорияВыбора"));
ПараметрЦены = Контекст.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ЦенаМин"));
Если ТипЗнч(ПараметрКатегории) <> Тип("ЗначениеПараметраНастроекКомпоновкиДанных")
Или ТипЗнч(ПараметрЦены) <> Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-PARAMETER-VALUE";
КонецЕсли;
Если ТипЗнч(ПараметрКатегории.Значение) <> Тип("Строка")
Или (ПараметрКатегории.Значение <> "PAPER" И ПараметрКатегории.Значение <> "OFFICE")
Или ПараметрЦены.Значение <> МинимальнаяЦена.Значение Тогда
ВызватьИсключение "OWN-PREVIEW-PARAMETER-VALUE";
КонецЕсли;
ИспользоватьКатегорию = Ложь;
ИспользоватьЦену = Ложь;
Для Каждого Связь Из Контекст.Связи Цикл
Если ТипЗнч(Связь) <> Тип("СвязьПараметраВыбораКомпоновкиДанных")
Или ТипЗнч(Связь.Поле) <> Тип("ПолеКомпоновкиДанных") Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-TYPE";
КонецЕсли;
Если Связь.Имя = "Категория" Тогда
Если ИспользоватьКатегорию Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-DUPLICATE";
КонецЕсли;
Если Строка(Связь.Поле) <> "ПараметрыДанных.КатегорияВыбора" Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-FIELD";
КонецЕсли;
ИспользоватьКатегорию = Истина;
ИначеЕсли Связь.Имя = "Цена" Тогда
Если ИспользоватьЦену Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-DUPLICATE";
КонецЕсли;
Если Строка(Связь.Поле) <> "ПараметрыДанных.ЦенаМин" Тогда
ВызватьИсключение "OWN-PREVIEW-LINK-FIELD";
КонецЕсли;
ИспользоватьЦену = Истина;
Иначе
ВызватьИсключение "OWN-PREVIEW-LINK-NAME";
КонецЕсли;
КонецЦикла;
Возврат Новый Структура("Категория,ЦенаМин,ИспользоватьКатегорию,ИспользоватьЦену",
ПараметрКатегории.Значение, МинимальнаяЦена.Значение, ИспользоватьКатегорию, ИспользоватьЦену);
КонецФункции
Функция Предпросмотр(Контекст)
Товары = Контекст.ДанныеОбъектов.СвоиТовары;
ПроверитьТовары(Товары, Контекст.UUID);
Условия = ПолучитьУсловия(Контекст);
Менеджер = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Менеджер;
Запрос.Текст = "ВЫБРАТЬ И.UUID, И.Код, И.Категория, И.Количество, И.Цена, И.Сумма
|ПОМЕСТИТЬ ВТСвоиТовары ИЗ &Товары КАК И";
Запрос.УстановитьПараметр("Товары", Товары);
Попытка
Запрос.Выполнить();
Запрос.Текст = "ВЫБРАТЬ И.UUID, И.Код, И.Категория, И.Количество, И.Цена, И.Сумма
|ИЗ ВТСвоиТовары КАК И
|ГДЕ (НЕ &ИспользоватьКатегорию ИЛИ И.Категория = &Категория)
|И (&НеИспользоватьЦену ИЛИ И.Цена >= &ЦенаМин)
|УПОРЯДОЧИТЬ ПО И.Код";
Запрос.УстановитьПараметр("ИспользоватьКатегорию", Условия.ИспользоватьКатегорию);
Запрос.УстановитьПараметр("Категория", Условия.Категория);
Запрос.УстановитьПараметр("НеИспользоватьЦену", Не Условия.ИспользоватьЦену);
Запрос.УстановитьПараметр("ЦенаМин", Условия.ЦенаМин);
Результат = Запрос.Выполнить().Выгрузить();
Исключение
Менеджер.Закрыть();
ВызватьИсключение;
КонецПопытки;
Менеджер.Закрыть();
Возврат Результат;
КонецФункции
Процедура ПроверитьПредпросмотр(Результат, СвойUUID, ОжидаемыеКоды, ОжидаемаяСумма)
Коды = СтрРазделить(ОжидаемыеКоды, ",");
Если ТипЗнч(Результат) <> Тип("ТаблицаЗначений") Или Результат.Количество() <> Коды.Количество() Тогда
ВызватьИсключение "OWN-PREVIEW-RESULT";
КонецЕсли;
Сумма = 0;
Для Индекс = 0 По Коды.Количество() - 1 Цикл
Товар = Результат.Получить(Индекс);
Если Товар.UUID <> СвойUUID Или Товар.Код <> Коды[Индекс]
Или ТипЗнч(Товар.Количество) <> Тип("Число") Или ТипЗнч(Товар.Цена) <> Тип("Число")
Или ТипЗнч(Товар.Сумма) <> Тип("Число") Или Товар.Количество * Товар.Цена <> Товар.Сумма Тогда
ВызватьИсключение "OWN-PREVIEW-RESULT";
КонецЕсли;
Сумма = Сумма + Товар.Сумма;
КонецЦикла;
Если Сумма <> ОжидаемаяСумма Тогда
ВызватьИсключение "OWN-PREVIEW-TOTAL";
КонецЕсли;
КонецПроцедуры
Функция ПрименитьСвоюПолитику(Политика, СвойВыбранныйКод)
Если ТипЗнч(Политика) <> Тип("РежимИзмененияСвязанногоЗначения") Или ТипЗнч(СвойВыбранныйКод) <> Тип("Строка") Тогда
ВызватьИсключение "OWN-PREVIEW-POLICY";
КонецЕсли;
Если Политика = РежимИзмененияСвязанногоЗначения.Очищать Тогда
Возврат "";
ИначеЕсли Политика = РежимИзмененияСвязанногоЗначения.НеИзменять Тогда
Возврат СвойВыбранныйКод;
Иначе
ВызватьИсключение "OWN-PREVIEW-POLICY";
КонецЕсли;
КонецФункции
Функция ПроверитьОтказы(СвойUUID)
Для Номер = 1 По 6 Цикл
Контекст = СоздатьКонтекст(СвойUUID);
Если Номер = 1 Тогда
Контекст.Связи = Новый Массив;
Маркер = "OWN-PREVIEW-LINKS-TYPE";
ИначеЕсли Номер = 2 Тогда
Контекст.Категория.Поле = Новый ПолеКомпоновкиДанных("НесуществующееПоле");
Маркер = "OWN-PREVIEW-LINK-FIELD";
ИначеЕсли Номер = 3 Тогда
Контекст.Цена.Имя = "Категория";
Маркер = "OWN-PREVIEW-LINK-DUPLICATE";
ИначеЕсли Номер = 4 Тогда
Контекст.ПараметрыВыбора.Получить(0).Значение = "200";
Маркер = "OWN-PREVIEW-CHOICE-VALUE";
ИначеЕсли Номер = 5 Тогда
Контекст.ДанныеОбъектов.СвоиТовары.Получить(0).Сумма = 749;
Маркер = "OWN-PREVIEW-FIXTURE";
Иначе
Маркер = "OWN-PREVIEW-POLICY";
КонецЕсли;
Отказ = Ложь;
Попытка
Если Номер = 6 Тогда
Выбор = ПрименитьСвоюПолитику("угаданный default", "BOOK");
Если Выбор <> "BOOK" Тогда
ВызватьИсключение "Нельзя принять неподдержанную политику";
КонецЕсли;
Иначе
Предпросмотр(Контекст);
КонецЕсли;
Исключение
Если СтрНайти(ОписаниеОшибки(), Маркер) = 0 Тогда
ВызватьИсключение;
КонецЕсли;
Отказ = Истина;
КонецПопытки;
Если Не Отказ Тогда
ВызватьИсключение "Не получен ожидаемый отказ " + Маркер;
КонецЕсли;
КонецЦикла;
Возврат "Проверены6 отказов на6 отдельных локальных кандидатах";
КонецФункции
Функция ВыполнитьПредпросмотр() Экспорт
ПроверитьСвоюСхему();
СвойUUID = Новый УникальныйИдентификатор;
Контекст = СоздатьКонтекст(СвойUUID);
ТолькоКнига = Предпросмотр(Контекст);
ПроверитьПредпросмотр(ТолькоКнига, СвойUUID, "BOOK", 750);
Если Контекст.Связи.Количество() <> 2 Или Контекст.Связи.Индекс(Контекст.Цена) <> 1 Тогда
ВызватьИсключение "Удаляем только свой подтвержденный элемент цены";
КонецЕсли;
Контекст.Связи.Удалить(Контекст.Цена);
Если Контекст.Связи.Количество() <> 1 Или Контекст.Связи.Получить(0).Имя <> "Категория"
Или Контекст.Связи.Индекс(Контекст.Категория) <> 0 Тогда
ВызватьИсключение "OWN-PREVIEW-DELETE";
КонецЕсли;
Бумага = Предпросмотр(Контекст);
ПроверитьПредпросмотр(Бумага, СвойUUID, "BOOK,PAD", 950);
СвойВыбор = ПрименитьСвоюПолитику(Контекст.Политика, "BOOK");
Если Контекст.Политика = РежимИзмененияСвязанногоЗначения.Очищать Тогда
Если СвойВыбор <> "" Тогда
ВызватьИсключение "OWN-PREVIEW-POLICY-READBACK";
КонецЕсли;
ПояснениеПолитики = "Native Очищать: очищена только собственная переменная выбора";
Иначе
Если СвойВыбор <> "BOOK" Тогда
ВызватьИсключение "OWN-PREVIEW-POLICY-READBACK";
КонецЕсли;
ПояснениеПолитики = "Native НеИзменять: BOOK сохранен в своей переменной, но проверяется новым набором";
КонецЕсли;
Контекст.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КатегорияВыбора", "OFFICE");
Офис = Предпросмотр(Контекст);
ПроверитьПредпросмотр(Офис, СвойUUID, "PEN", 50);
Если СвойВыбор <> "" И Офис.Найти(СвойВыбор, "Код") <> Неопределено Тогда
ВызватьИсключение "Старый BOOK не должен считаться допустимым при OFFICE";
КонецЕсли;
Если Контекст.Связи.Количество() <> 1 Или Контекст.Связи.Получить(0).Имя <> "Категория" Тогда
ВызватьИсключение "Очищаем только собственный подтвержденный локальный кандидат";
КонецЕсли;
Контекст.Связи.Очистить();
Если Контекст.Связи.Количество() <> 0 Тогда
ВызватьИсключение "OWN-PREVIEW-CLEAR";
КонецЕсли;
ВсеТовары = Предпросмотр(Контекст);
ПроверитьПредпросмотр(ВсеТовары, СвойUUID, "BOOK,PAD,PEN", 1000);
ПроверитьТовары(Контекст.ДанныеОбъектов.СвоиТовары, СвойUUID);
Отказы = ПроверитьОтказы(СвойUUID);
Документ = Новый ТабличныйДокумент;
Документ.Область(1, 1).Текст = "СВОЙ ЛОКАЛЬНЫЙ PREVIEW, НЕ стандартная форма выбораСКД";
Документ.Область(2, 1).Текст = "BOOK750 → PAPER950 → OFFICE50 → все1000";
Документ.Область(3, 1).Текст = ПояснениеПолитики;
Документ.Область(4, 1).Текст = Отказы;
Документ.Область(5, 1).Текст = "UUID: " + Строка(СвойUUID);
Номер = 6;
Для Каждого Товар Из ВсеТовары Цикл
Документ.Область(Номер, 1).Текст = Товар.Код;
Документ.Область(Номер, 2).Текст = Товар.Категория;
Для Каждого Поле Из СтрРазделить("Количество,Цена,Сумма", ",") Цикл
Если Поле = "Количество" Тогда
Колонка = 3;
ИначеЕсли Поле = "Цена" Тогда
Колонка = 4;
Иначе
Колонка = 5;
КонецЕсли;
Ячейка = Документ.Область(Номер, Колонка);
Ячейка.СодержитЗначение = Истина;
Ячейка.Значение = Товар[Поле];
КонецЦикла;
Номер = Номер + 1;
КонецЦикла;
Документ.Область(1, 1, 8, 1).ШиринаКолонки = 100;
Документ.Область(1, 2, 8, 5).ШиринаКолонки = 18;
Документ.Область(1, 1, 8, 5).Защита = Истина;
Документ.ТолькоПросмотр = Истина;
Возврат Документ;
КонецФункции
#КонецЕслиПолный модуль своей обычной формы
Общие → Общие формы → УчебныйЛокальныйВыбор85 → Модуль
Thick ordinary client; настоящая кнопкаВыполнить85, не вызов обработчика вручную.
Процедура Выполнить85(Кнопка)
Если Кнопка.Имя <> "Выполнить85" Тогда
ВызватьИсключение "Нужна собственная кнопкаВыполнить85";
КонецЕсли;
НовыйРезультат = УчебныйПредпросмотр85.ВыполнитьПредпросмотр();
Если ТипЗнч(НовыйРезультат) <> Тип("ТабличныйДокумент") Тогда
ВызватьИсключение "Нет полностью проверенного результата локального preview";
КонецЕсли;
Результат85 = НовыйРезультат;
КонецПроцедурыПолный модуль обычного приложения
Корень конфигурации → Модуль обычного приложения
Thick ordinary startup event.
Процедура ПриНачалеРаботыСистемы()
СвояФорма = ПолучитьОбщуюФорму("УчебныйЛокальныйВыбор85");
Если ТипЗнч(СвояФорма) <> Тип("Форма") Тогда
ВызватьИсключение "Подготовьте собственную обычную общую форму";
КонецЕсли;
СвояФорма.Открыть();
КонецПроцедурыРазбор по шагам
Создаем и полностью проверяем своиBOOK/PAD/PEN с реальнымUUID. Builder схемы использует ровно те же типы колонок и известное имя объектаСвоиТовары.
Собственная схема → источник настроек → компоновщик → его реальные Настройки → фактические доступные параметры → настоящий ТоварВыбора → GetChoice*. Проверяем каждый nullable результат; ничего не конструируем вместо недоступной коллекции.
ЦенаМин=200 — настоящийПараметрВыбора. Две реальные связи имеют известныеИмя иПолеКомпоновкиДанных, реальные индексы и проверенный порядок послеСдвинуть. ПолитикуИзменениеЗначения только читаем.
Наш потребитель проверяет whitelist имени/пути поля и отсутствие дубликатов, затем получает категорию из реальных настроек собственного нового компоновщика и цену из собственного параметра. Только эти данные становятся параметрами собственного запроса к частной ВТ.
Проверяем BOOK750; удаляем только свой элемент Цена и проверяем BOOK/PAD950; меняем категорию своего компоновщика native setter на OFFICE и проверяем PEN50; очищаем только свой подтвержденный кандидат и проверяем все1000.
Фактический native режимОчищать/НеИзменять применяем только к своей переменной выбора. СохраненныйBOOK не становится допустимым дляOFFICE. Это демонстрация собственного обработчика политики, а не автоматический эффект СКД.
Каждый из6 отказов получает свой свежий полный контекст. Проверяем конкретную ошибку до запроса; нет подавления неожиданной ошибки и нет восстановления чужого состояния.
Только после всех проверок полный модуль обычной формы получает итоговыйТабличныйДокумент. Настройки и коллекции не сериализуются, стандартная форма выбора не открывается, источникиИБ не читаются.
Как проверить результат
При ручном запуске ожидаются четыре подтвержденных состава:BOOK=750; BOOK/PAD=950; PEN=50; BOOK/PAD/PEN=1000. В каждой строкеUUID именно своего набора, количества/цены/суммы остаются числами.
В отладчике новаяЦена послеВставить(0) имеет индекс0, послеСдвинуть(Цена,1) индекс1, Категория индекс0; послеУдалить остается толькоКатегория, послеОчистить элементов0.
Протокол политики отражает реальный native режим, не угаданный default. ПриНеИзменять прежнийBOOK остается в своей переменной, но не принимается в наборOFFICE.
Все6 ожидаемых отказов подтверждаются своими маркерами. При OWN-PREVIEW-NO-AVAILABLE не продолжайте: фактические доступные параметры компоновщика не подтвердились; нельзя считать это успешным уроком.
Запуск, пиксельный вид формы и source-bound доступные поля компоновщика не проверялись здесь. Пройдите весь ручной протокол на своей новойИБ; статические проверки подтверждают только код/контракты.
Ожидаемый результат
Ожидаемый при ручном запуске результат: локальный ownpreview с проверенными составами750/950/50/1000, реальной readonly политикой и6 отрицательными проверками; запуск1С не проверялся.
На что обратить внимание
Связи/параметры создаются native методамиGetChoice*/Добавить/Вставить. У них нет придуманного конструктора; Поле имеет настоящий типПолеКомпоновкиДанных, а не строку или неизвестное поле.
ИзменениеЗначения только для чтения и доступно на клиенте. Весь процесс thick ordinary; не переносите его в серверный общий модуль или тонкую форму. Компоновщик новый собственный, без чужих пользовательских/фиксированных настроек. Его реальные Настройки читаются без сериализации/копирования.
ДоступныеПараметры могут быть Неопределено у настроек без источника. Обязательный fail-stop не заменяет runtime доказательство успешной инициализации; неизвестный объект не подставляется.
Полученные GetChoice коллекции являются локальными кандидатами для нашего потребителя. Не обещаем, что их изменение сохраняет связи в исходной схеме/компоновщике или настраивает стандартную форму выбора. Только значение категории меняется документированным УстановитьЗначениеПараметра у нашего нового memory компоновщика.
МетодСвязи.Найти исключен: rawFind3984 заявляетПараметрВыбора вместоСвязьПараметраВыбора. Сериализация связей исключена: typepage ошибочно ссылается наAppearanceTemplateArea. Эти противоречия не обходятся выдуманными контрактами.
Сдвинуть/Удалить принимают настоящий элемент, не произвольный индекс. Индексы проверяются до и после операции; очистка допустима только своего кандидата с точным ожидаемым составом.
ПараметрЦенаМин здесь — собственный протокол preview, не имя специальной системной команды. Условия запроса создаются фиксированным кодом; имена/поля из коллекции проверяются whitelist, не конкатенируются в SQL/BSL.
Построитель схемы описывает объектный набор с реальным именем и типами, но native процессор компоновки не запускается. Результат рассчитывает наш полностью показанный запрос к собственной таблице; это не native output СКД.
Нет файлов, сети, служб, OS-команд, настроек хранилищ, печати, записейmetadata/ИБ, восстановления рабочей конфигурации или резервных копий. Чтение native контрактов/static tests не равны runtime проверке.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.