КонстантыМенеджер.ПолучитьФорму

Методы · GetForm

Получает форму для управления константами.

Синтаксис

ПолучитьФорму(<Форма>, <Владелец>, <КлючУникальности>)

Примеры платформы

Константы.ПолучитьФорму().ОткрытьМодально();
Полное описание, параметры и ограничения

КонстантыМенеджер.ПолучитьФорму (ConstantsManager.GetForm)

КонстантыМенеджер (ConstantsManager)

ПолучитьФорму (GetForm)

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

Синтаксис:
ПолучитьФорму(<Форма>, <Владелец>, <КлючУникальности>)
Параметры:

<Форма> (необязательный)
Тип: Строка, ОбъектМетаданных: Форма.
Имя формы, как оно задано в конфигураторе, или объект описания метаданного требуемой формы. Если параметр не указан, то используется основная форма, заданная в конфигураторе.

<Владелец> (необязательный)
Тип: Форма; Элемент управления.
Объект, который будет являться владельцем открываемой формы.

<КлючУникальности> (необязательный)
Тип: Произвольный.
В данном параметре может быть задан некоторый ключ, значение которого будет использоваться для поиска уже открытых форм.
При поиске учитываются значения свойств открытых форм соответствующим значениям параметров метода. Если найдена открытая форма (по совпадению всех параметров), то она будет возвращена вместо новой формы.
Если из некой формы (один и тот же владелец) требуется открывать новые экземпляры другой формы, то при каждом вызове метода значение данного параметра должно быть уникально (в рамках соответствующих значений свойств открытых форм).
Значение параметра присваивается свойству открываемой формы КлючУникальности.
Следует учитывать, что при получении формы из "объекта" система получает форму для конкретного экземпляра объекта с учетом совокупности переданных параметров, в то время как для "ссылки" всегда существует только один объект в базе данных и форма получается одна (для одинаковой совокупности параметров).
Возвращаемое значение:
Тип: Форма, Неопределено.
Неопределено - если в обработчике ПриСозданииНаСервере установлен признак отказа от создания формы.
Описание:

Получает форму для управления константами.

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

Толстый клиент.

Пример:

Константы.ПолучитьФорму().ОткрытьМодально();

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

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

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

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

Две настоящие factory обычной формы констант: менеджер и подготовленный набор

Полный процесс собственной настройки скидки счета1000 в новой пустой CF: три typed константы, настоящий wizard-owner, сохраненные10/900→15/850→20/800. Ordinary и managed — два отдельных запуска; отмена не возвращает уже сохраненное значение.

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

Толстый обычный клиент. MAIN=ORDINARY_HUB; Своя CF → Общие → Общие формы → Уч85ЗапускКонстантОбычный → Модуль. Код только авторский, runtime1С/БД/UI0.

Подготовка

  1. Этот урок только для вручную созданной новой собственной файловой ИБ C:\1c-labs\OwnConstants85_92dd7148-2742-46b7-86fd-338fd0f86c64\IB. Не используйте копию рабочей базы. GUID в имени каталога — метка учебного пути, НЕ UUID информационной базы. Авторство/статические тесты не создают каталог, CF, пользователя или значения; реальных вызовов1С/БД/UI/сети0.

  2. В Конфигураторе8.5.1.1343 создайте пустую конфигурацию Уч85СобственныеКонстанты. Режим совместимости=Не использовать. В настройках редактирования выберите Управляемое приложение и обычное приложение: это именно условие выбора двух типов формы в native мастере. Первый отдельный запуск сделайте толстым обычным клиентом, после полного закрытия — толстым управляемым Windows/Такси; одновременно только один собственный сеанс. Никаких фоновых/регламентных заданий, подписок событий, общих реквизитов/разделителей, истории, расширений, планов обмена, иных прикладных объектов или RLS.

  3. Создайте ровно три константы: Уч85СкидкаПроцент:Число2,0 неотрицательное; Уч85Метка:Строка36 фиксированная; Уч85Пользователь:Строка36 фиксированная. Нет разделителей данных, поэтому функциональный конструктор конкретного КонстантаКлючЗначения дает ключ со всеми полями по умолчанию. Пустой() здесь относится к полям КЛЮЧА, а не к сохраненному значению скидки10/15/20.

  4. Создайте единственного пользователя Уч85Константы_92dd7148 с аутентификацией1С и собственной ролью полного чтения/изменения этих трех констант, использования своих форм/общего модуля и административным правом Администрирование для ПолучитьПользователей. Отключите RLS. Не добавляйте других пользователей. Физическое отсутствие иных сеансов проверьте вручную; код не доказывает конкурентную изоляцию.

  5. Общие → Общие формы → Добавить → в мастере выберите именно Форма констант, НЕ произвольная форма. Создайте Уч85НастройкиОбычная, Тип формы=Обычная, выберите все три константы. В редакторе проверьте реальный основной реквизит Набор:КонстантыНабор и связи трех полей с Набор.Уч85СкидкаПроцент/Уч85Метка/Уч85Пользователь. Мастер создает реальную константную форму: просто назвать произвольный реквизит Набор недостаточно для получения native расширения. ОсновнаяФормаКонстант metadata всегда Неопределено по native контракту и в guard не используется.

  6. Повторите именно мастер Форма констант для Уч85НастройкиУправляемая, Тип формы=Управляемая, все три константы, основной Набор:КонстантыНабор. Реквизит Набор управляемой формы на клиенте представлен данными формы, поэтому сервер получает настоящий КонстантыНабор через РеквизитФормыВЗначение("Набор"). Не создавайте Новый Расширение констант или произвольную форму вместо factory.

  7. Ручная первоначальная подготовка выполняется ДО установки VALUE_MODULE/обработчиков запуска. В отдельной своей константной форме вручную сохраните Уч85СкидкаПроцент=10, Уч85Метка=92dd7148-2742-46b7-86fd-338fd0f86c64, Уч85Пользователь=строковый UUID реального единственного пользователя. Получите его локально в Конфигураторе/отладчике выражением Строка(ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор) под этим пользователем; не подставляйте GUID каталога вместо user UUID. Закройте подготовительный клиент. Первоначальная ручная запись — отдельное осознанное действие ученика, не скрытый bootstrap-код.

  8. Создайте общий модуль Уч85КонстантыСтенд: Сервер=True, Вызов сервера=True, Клиент обычного приложения=True, Клиент управляемого приложения=False, Глобальный=False, Привилегированный=False, повторное использование возвращаемых значений=Не использовать. Вставьте полный COMMON. В ordinary код компилируется на толстом клиенте; managed вызывает экспортные серверные методы. Модуль только читает значения/схему; записи БД в нем нет.

  9. После ручного fixture в модуль менеджера значения КАЖДОЙ из трех собственных констант вставьте полный VALUE_MODULE. Native ПередЗаписью(Отказ)1 работает с настоящим ЭтотОбъект:КонстантаМенеджерЗначения.<Имя>; проверяет readonly ОбменДанными и proposed значение, не пишет другое значение и не отключает Загрузка. Это не ПередЗаписьюНаСервере формы3. Native прямо предупреждает: на время этого обработчика безопасный режим отключается, кроме обработчиков в расширении. Поэтому это учебный workflow, не sandbox произвольного кода; любых иных условий не обещаем.

  10. В Уч85НастройкиОбычная вставьте полный ORDINARY_FORM. Добавьте СогласиеНаИзменение85:Булево и Статус85:Строка500. Все три связанные константные поля и статус ТолькоПросмотр=True; согласие редактируемое. Кнопки СохранитьПятнадцать85 и ОтменитьИЗакрыть85 назначьте на одноименные native Нажатие(Кнопка)1. События самой формы: ПередОткрытием2, ПередЗакрытием2; событие расширения констант ПередЗаписью1. Стандартные кнопки Записать/ОК не показывайте; неподготовленная native запись отказана событием. Native события не вызывайте вручную.

  11. Создайте произвольную ОБЫЧНУЮ ОбщаяФорма.Уч85ЗапускКонстантОбычный, без основного прикладного реквизита. Две кнопки ЧерезМенеджер85/ЧерезНабор85 и одноименные native Нажатие(Кнопка)1, ПередОткрытием2; вставьте ORDINARY_HUB. Manager.GetForm и actual Set.GetForm передают точный ОбъектМетаданныхФорма, настоящую свою обычную форму-владельца и новый УникальныйИдентификатор. Их native return Форма/Неопределено и thick-only — не перенаправляйте эти вызовы к managed форме.

  12. В Уч85НастройкиУправляемая вставьте MANAGED_FORM. Реквизиты: НеизвестныйИсход85,РазрешенаЗапись85,РазрешеноЗакрытие85,СогласиеНаИзменение85:Булево; ТекущаяСкидка85:Число2,0; Статус85:Строка500. Для дополнительных реквизитов СохраняемыеДанные=False; все кроме согласия ТолькоПросмотр=True. Команды СохранитьДвадцать85,Перечитать85,ОтменитьИЗакрыть85 с одноименными действиями(Команда)1; кнопки привязаны к собственным командам. Native ПриСозданииНаСервере2,ПередЗаписьюНаСервере3,ПередЗакрытием4; стандартную запись/закрытие не подменяйте ручными вызовами событий.

  13. Создайте произвольную УПРАВЛЯЕМУЮ ОбщаяФорма.Уч85ЗапускКонстантУправляемый без основного прикладного реквизита. Команда ОткрытьНастройки85 с одноименным действием(Команда)1, вставьте MANAGED_HUB. Здесь глобальная ПолучитьФорму дает actual managed форму из wizard-константного metadata. Одно окно на запуск launcher: после отмены без записи можно полностью закрыть свой клиент и повторно запустить; после неизвестного исхода повтор запрещен.

  14. Переменная ОткрытиеВыдано85 объявлена явно &НаКлиенте; серверу она не передается и никогда не означает persisted разрешение БД. Ordinary экспортный initializer допускается только при свежем НеизвестныйИсход85=Неопределено; до первого чтения ставитTrue, сбрасываетFalse лишь после всех проверок. Повторный initializer не может стереть ошибку. Managed ПриСозданииНаСервере сначала проверяет saved полный источник, затем явно вызывает native Прочитать0 на сервере и лишь затем конвертирует Набор: заполнение при Standard=False не предполагается.

  15. Модуль обычного приложения=ORDINARY_APPLICATION, модуль управляемого приложения=MANAGED_APPLICATION; в каждом native ПриНачалеРаботыСистемы0. После подготовки сначала запустите только ordinary: baseline10/900, отмена первой формы без записи, затем отдельное окно через набор и осознанная запись15/850. Закройте собственные окна и ВЕСЬ ordinary клиент. Отдельно запустите managed с baseline15/850 и осознанно запишите20/800. Не запускайте обе части одновременно и не меняйте исходные значения для обхода отказа.

  16. Три managed страницы уже присутствуют в установленной справке/guide documentation под длинным именем Расширение формы клиентского приложения для констант; JSON тип назван Расширение констант, поэтому apiKeys=[] сохранены. Exact nativeTopicBindings связывают только три эти темы и alias; не меняют docs и не кредитуют одноименное ordinary расширение.

Перем СвояФорма85;

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Отказ = Истина;
    Уч85КонстантыСтенд.Снимок85();
    Отказ = Ложь;
КонецПроцедуры

Процедура ЧерезМенеджер85(Кнопка)
    Если Кнопка <> ЭлементыФормы.ЧерезМенеджер85 Тогда
        ВызватьИсключение "Не та собственная кнопка.";
    КонецЕсли;
    ПроверитьПредыдущееОкно85();
    Уч85КонстантыСтенд.Снимок85();
    КлючОкна85 = Новый УникальныйИдентификатор;
    СвояФорма85 = Константы.ПолучитьФорму(Метаданные.ОбщиеФормы.Уч85НастройкиОбычная, ЭтаФорма, КлючОкна85);
    ПроверитьПолученную85(КлючОкна85);
    СвояФорма85.Открыть();
КонецПроцедуры

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

Процедура ПроверитьПредыдущееОкно85()
    Если СвояФорма85 <> Неопределено И СвояФорма85.Открыта() Тогда
        ВызватьИсключение "Сначала явно закройте свое предыдущее окно; неизвестные формы не затрагиваем.";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьПолученную85(КлючОкна85)
    Если ТипЗнч(СвояФорма85) <> Тип("Форма") Или СвояФорма85.ВладелецФормы <> ЭтаФорма
        Или СвояФорма85.КлючУникальности <> КлючОкна85 Тогда
        ВызватьИсключение "Не получена именно ordinary форма с собственным владельцем/ключом.";
    КонецЕсли;
    СвояФорма85.ПодтвердитьИсточник85(ЭтаФорма, КлючОкна85);
КонецПроцедуры
COMMON — полный модуль

Своя CF → Общие → Общие модули → Уч85КонстантыСтенд

Общий серверный/ordinary клиентский модуль, Вызов сервера=True

Функция ПроверитьСтенд85() Экспорт
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnConstants85_92dd7148-2742-46b7-86fd-338fd0f86c64\IB"";" Или Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
        ВызватьИсключение "Только новая собственная файловая CF без совместимости, не рабочая база.";
    КонецЕсли;
    Если Метаданные.Константы.Количество() <> 3 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0
        Или Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0
        Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0
        Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0
        Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0
        Или Метаданные.ПланыОбмена.Количество() <> 0 Тогда
        ВызватьИсключение "Нужна ровно собственная схема трех констант без разделителей/чужих объектов.";
    КонецЕсли;
    Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0 Тогда
        ВызватьИсключение "Расширения запрещены в своем стенде.";
    КонецЕсли;
    Ожидаемые85 = Новый Структура("Уч85СкидкаПроцент,Уч85Метка,Уч85Пользователь", Тип("Число"), Тип("Строка"), Тип("Строка"));
    Для Каждого Поле85 Из Ожидаемые85 Цикл
        Описание85 = Метаданные.Константы.Найти(Поле85.Ключ);
        Если Описание85 = Неопределено Или Описание85.Тип.Типы().Количество() <> 1
            Или Не Описание85.Тип.СодержитТип(Поле85.Значение) Тогда
            ВызватьИсключение "Реальный тип/имя собственной константы отличается.";
        КонецЕсли;
    КонецЦикла;
    Если Метаданные.ОбщиеФормы.Уч85НастройкиОбычная.ТипФормы <> Метаданные.СвойстваОбъектов.ТипФормы.Обычная
        Или Метаданные.ОбщиеФормы.Уч85НастройкиУправляемая.ТипФормы <> Метаданные.СвойстваОбъектов.ТипФормы.Управляемая Тогда
        ВызватьИсключение "Нужны две настоящие формы констант разных типов, не перенаправление ordinary к managed.";
    КонецЕсли;
    Пользователь85 = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Пользователь85 = Неопределено Тогда
        ВызватьИсключение "Не получен реальный пользователь.";
    КонецЕсли;
    Все85 = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если Все85.Количество() <> 1 Или Пользователь85.Имя <> "Уч85Константы_92dd7148"
        Или Все85[0].Имя <> Пользователь85.Имя
        Или Все85[0].УникальныйИдентификатор <> Пользователь85.УникальныйИдентификатор Тогда
        ВызватьИсключение "Только единственный свой аутентифицированный пользователь с административным правом.";
    КонецЕсли;
    Возврат Строка(Пользователь85.УникальныйИдентификатор);
КонецФункции

Процедура ПроверитьМенеджер85(Менеджер85) Экспорт
    Пользователь85 = ПроверитьСтенд85();
    Если ТипЗнч(Менеджер85) <> Тип("КонстантаМенеджерЗначения.Уч85СкидкаПроцент")
        И ТипЗнч(Менеджер85) <> Тип("КонстантаМенеджерЗначения.Уч85Метка")
        И ТипЗнч(Менеджер85) <> Тип("КонстантаМенеджерЗначения.Уч85Пользователь") Тогда
        ВызватьИсключение "Не собственный настоящий менеджер значения.";
    КонецЕсли;
    Если Менеджер85.ОбменДанными.Загрузка <> Ложь
        Или Менеджер85.ОбменДанными.Отправитель <> Неопределено
        Или Менеджер85.ОбменДанными.Получатели.Количество() <> 0 Тогда
        ВызватьИсключение "Учебная настройка не записывается в режиме загрузки/обмена.";
    КонецЕсли;
    Если Менеджер85.Метаданные() = Метаданные.Константы.Уч85СкидкаПроцент Тогда
        Если ТипЗнч(Менеджер85.Значение) <> Тип("Число")
            Или (Менеджер85.Значение <> 10 И Менеджер85.Значение <> 15 И Менеджер85.Значение <> 20) Тогда
            ВызватьИсключение "Допускается только собственная скидка10/15/20.";
        КонецЕсли;
    ИначеЕсли Менеджер85.Метаданные() = Метаданные.Константы.Уч85Метка Тогда
        Если Менеджер85.Значение <> "92dd7148-2742-46b7-86fd-338fd0f86c64" Тогда
            ВызватьИсключение "Нельзя менять собственную метку.";
        КонецЕсли;
    ИначеЕсли Менеджер85.Метаданные() = Метаданные.Константы.Уч85Пользователь Тогда
        Если Менеджер85.Значение <> Пользователь85 Тогда
            ВызватьИсключение "Нельзя менять действительный UUID своего пользователя.";
        КонецЕсли;
    Иначе
        ВызватьИсключение "Чужое metadata даже при похожем имени.";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьНабор85(Набор85, Скидка85) Экспорт
    Если ТипЗнч(Набор85) <> Тип("КонстантыНабор") Тогда
        ВызватьИсключение "Не настоящий native набор собственной формы.";
    КонецЕсли;
    Если ТипЗнч(Набор85.Уч85СкидкаПроцент) <> Тип("Число") Или Набор85.Уч85СкидкаПроцент <> Скидка85
        Или Набор85.Уч85Метка <> "92dd7148-2742-46b7-86fd-338fd0f86c64"
        Или Набор85.Уч85Пользователь <> ПроверитьСтенд85() Тогда
        ВызватьИсключение "Проверяются все три actual поля полного собственного набора.";
    КонецЕсли;
КонецПроцедуры

Функция Снимок85(ОжидаемаяСкидка85 = 0) Экспорт
    Пользователь85 = ПроверитьСтенд85();
    Ключ85 = Новый(Тип("КонстантаКлючЗначения.Уч85СкидкаПроцент"));
    Если ТипЗнч(Ключ85) <> Тип("КонстантаКлючЗначения.Уч85СкидкаПроцент")
        Или Ключ85.Метаданные() <> Метаданные.Константы.Уч85СкидкаПроцент Или Ключ85.Пустой() <> Истина Тогда
        ВызватьИсключение "Нужен настоящий typed ключ своей константы без полей разделителей.";
    КонецЕсли;
    Набор85 = Константы.СоздатьНабор("Уч85СкидкаПроцент,Уч85Метка,Уч85Пользователь");
    Набор85.Прочитать();
    Скидка85 = Набор85.Уч85СкидкаПроцент;
    Если Скидка85 <> 10 И Скидка85 <> 15 И Скидка85 <> 20 Тогда
        ВызватьИсключение "Чужое/неподготовленное сохраненное значение скидки.";
    КонецЕсли;
    Если ОжидаемаяСкидка85 <> 0 И Скидка85 <> ОжидаемаяСкидка85 Тогда
        ВызватьИсключение "Изменился сохраненный baseline; запись запрещена.";
    КонецЕсли;
    ПроверитьНабор85(Набор85, Скидка85);
    Менеджер85 = Константы.Уч85СкидкаПроцент.СоздатьМенеджерЗначения();
    Менеджер85.Прочитать();
    ПроверитьМенеджер85(Менеджер85);
    Если Менеджер85.Значение <> Скидка85 Тогда
        ВызватьИсключение "Отдельный fresh менеджер не подтвердил сохраненную скидку.";
    КонецЕсли;
    Запрос85 = Новый Запрос;
    Запрос85.Текст =
    "ВЫБРАТЬ Уч85СкидкаПроцент КАК Скидка, Уч85Метка КАК Метка,
    | Уч85Пользователь КАК Пользователь, 1000 * (100 - Уч85СкидкаПроцент) / 100 КАК Сумма
    |ИЗ Константы";
    Таблица85 = Запрос85.Выполнить().Выгрузить();
    Если Таблица85.Количество() <> 1 Или Таблица85.Колонки.Количество() <> 4
        Или ТипЗнч(Таблица85[0].Скидка) <> Тип("Число") Или Таблица85[0].Скидка <> Скидка85
        Или Таблица85[0].Метка <> Набор85.Уч85Метка Или Таблица85[0].Пользователь <> Пользователь85
        Или Таблица85[0].Сумма <> 1000 * (100 - Скидка85) / 100 Тогда
        ВызватьИсключение "Весь источник и независимый native запрос900/850/800 не совпали.";
    КонецЕсли;
    Возврат Новый Структура("Скидка,Метка,Пользователь,Сумма", Таблица85[0].Скидка, Таблица85[0].Метка, Таблица85[0].Пользователь, Таблица85[0].Сумма);
КонецФункции

Процедура СравнитьСнимки85(До85, После85) Экспорт
    Если До85.Количество() <> 4 Или После85.Количество() <> 4 Тогда
        ВызватьИсключение "Изменился весь состав пакета.";
    КонецЕсли;
    Для Каждого Поле85 Из До85 Цикл
        Если Поле85.Значение <> После85[Поле85.Ключ] Тогда
            ВызватьИсключение "Отмена/перечитывание не подтвердили все сохраненные значения.";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры
ORDINARY_FORM — полный модуль

Своя CF → Общие → Общие формы → Уч85НастройкиОбычная → Модуль

Толстый обычный клиент, основной реквизит КонстантыНабор

Перем НеизвестныйИсход85;
Перем РазрешенаЗапись85;
Перем РазрешеноЗакрытие85;
Перем СнимокОткрытия85;

Процедура ПодтвердитьИсточник85(Владелец85, Ключ85) Экспорт
    Если НеизвестныйИсход85 <> Неопределено Тогда
        ВызватьИсключение "Initializer только для свежей формы; не сбрасывает неизвестный исход.";
    КонецЕсли;
    НеизвестныйИсход85 = Истина;
    Если ВладелецФормы <> Владелец85 Или КлючУникальности <> Ключ85 Или ТипЗнч(Набор) <> Тип("КонстантыНабор") Тогда
        ВызватьИсключение "Не подтвержден свой native источник формы констант.";
    КонецЕсли;
    СнимокОткрытия85 = Уч85КонстантыСтенд.Снимок85();
    Набор.Прочитать();
    Уч85КонстантыСтенд.ПроверитьНабор85(Набор, СнимокОткрытия85.Скидка);
    НеизвестныйИсход85 = Ложь;
    РазрешенаЗапись85 = Ложь;
    РазрешеноЗакрытие85 = Ложь;
КонецПроцедуры

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Отказ = Истина;
    Если СнимокОткрытия85 = Неопределено Или ВладелецФормы = Неопределено Тогда
        ВызватьИсключение "Открывайте только из своего подготовленного launcher, не стандартной команды.";
    КонецЕсли;
    Уч85КонстантыСтенд.СравнитьСнимки85(СнимокОткрытия85, Уч85КонстантыСтенд.Снимок85());
    Отказ = Ложь;
КонецПроцедуры

Процедура СохранитьПятнадцать85(Кнопка)
    Если Кнопка <> ЭлементыФормы.СохранитьПятнадцать85 Или НеизвестныйИсход85
        Или СогласиеНаИзменение85 <> Истина Или СнимокОткрытия85.Скидка <> 10 Тогда
        ВызватьИсключение "Нужно свое согласие только на10→15; при неизвестном исходе повтор запрещен.";
    КонецЕсли;
    Уч85КонстантыСтенд.СравнитьСнимки85(СнимокОткрытия85, Уч85КонстантыСтенд.Снимок85(10));
    Уч85КонстантыСтенд.ПроверитьНабор85(Набор, 10);
    Набор.Уч85СкидкаПроцент = 15;
    РазрешенаЗапись85 = Истина;
    НеизвестныйИсход85 = Истина;
    Попытка
        Если ЭтаФорма.ЗаписатьВФорме() <> Истина Тогда
            ВызватьИсключение "Native ordinary WriteInForm0=False; остановитесь без повторов/rollback.";
        КонецЕсли;
        Набор.Прочитать();
        После85 = Уч85КонстантыСтенд.Снимок85(15);
        Уч85КонстантыСтенд.ПроверитьНабор85(Набор, 15);
        Если После85.Сумма <> 850 Тогда
            ВызватьИсключение "Не подтвержден фактический результат15%/850.";
        КонецЕсли;
        СнимокОткрытия85 = После85;
        НеизвестныйИсход85 = Ложь;
        Статус85 = "Обычная форма: nativeTrue, полный источник15/850, метка и пользователь неизменны.";
    Исключение
        РазрешенаЗапись85 = Ложь;
        НеизвестныйИсход85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

Процедура ПередЗаписью(Отказ)
    Отказ = Истина;
    Если РазрешенаЗапись85 <> Истина Или НеизвестныйИсход85 <> Истина Тогда
        ВызватьИсключение "Неподготовленная native ordinary запись запрещена.";
    КонецЕсли;
    Уч85КонстантыСтенд.Снимок85(10);
    Уч85КонстантыСтенд.ПроверитьНабор85(Набор, 15);
    РазрешенаЗапись85 = Ложь;
    Отказ = Ложь;
КонецПроцедуры

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

Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Если РазрешеноЗакрытие85 <> Истина Тогда
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры
MANAGED_FORM — полный модуль

Своя CF → Общие → Общие формы → Уч85НастройкиУправляемая → Модуль

Толстый управляемый клиент и сервер, точные директивы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Отказ = Истина;
    До85 = Уч85КонстантыСтенд.Снимок85(15);
    ЭтаФорма.Прочитать();
    Уч85КонстантыСтенд.ПроверитьНабор85(РеквизитФормыВЗначение("Набор"), 15);
    НеизвестныйИсход85 = Ложь;
    РазрешенаЗапись85 = Ложь;
    РазрешеноЗакрытие85 = Ложь;
    ТекущаяСкидка85 = До85.Скидка;
    Статус85 = "Управляемая форма стартовала после ordinary: сохранены15%/850.";
    Отказ = Ложь;
КонецПроцедуры

&НаСервере
Процедура ПодготовитьДвадцать85()
    Если НеизвестныйИсход85 Или ТекущаяСкидка85 <> 15 Или СогласиеНаИзменение85 <> Истина Тогда
        ВызватьИсключение "Нужно отдельное собственное согласие на15→20.";
    КонецЕсли;
    Уч85КонстантыСтенд.Снимок85(15);
    Уч85КонстантыСтенд.ПроверитьНабор85(РеквизитФормыВЗначение("Набор"), 15);
    Набор.Уч85СкидкаПроцент = 20;
    РазрешенаЗапись85 = Истина;
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    Отказ = Истина;
    Если РазрешенаЗапись85 <> Истина Или НеизвестныйИсход85 <> Истина
        Или ПараметрыЗаписи.Количество() <> 1 Или ПараметрыЗаписи.Метка85 <> "92dd7148-2742-46b7-86fd-338fd0f86c64" Тогда
        ВызватьИсключение "Запись не подготовлена собственной managed командой.";
    КонецЕсли;
    Уч85КонстантыСтенд.Снимок85(15);
    Уч85КонстантыСтенд.ПроверитьНабор85(ТекущийОбъект, 20);
    РазрешенаЗапись85 = Ложь;
    Отказ = Ложь;
КонецПроцедуры

&НаСервере
Функция ПроверитьПрочитанное85(Скидка85)
    После85 = Уч85КонстантыСтенд.Снимок85(Скидка85);
    Уч85КонстантыСтенд.ПроверитьНабор85(РеквизитФормыВЗначение("Набор"), Скидка85);
    Возврат После85.Сумма;
КонецФункции

&НаКлиенте
Процедура СохранитьДвадцать85(Команда)
    Если Команда.Имя <> "СохранитьДвадцать85" Или НеизвестныйИсход85 Тогда
        ВызватьИсключение "Чужая команда или неизвестный исход.";
    КонецЕсли;
    ПодготовитьДвадцать85();
    НеизвестныйИсход85 = Истина;
    Попытка
        Если ЭтаФорма.Записать(Новый Структура("Метка85", "92dd7148-2742-46b7-86fd-338fd0f86c64")) <> Истина Тогда
            ВызватьИсключение "Native managed Write=False; никаких автоматических повторов.";
        КонецЕсли;
        ЭтаФорма.Прочитать();
        Если ПроверитьПрочитанное85(20) <> 800 Тогда
            ВызватьИсключение "Полный свежий источник не подтвердил20%/800.";
        КонецЕсли;
        ТекущаяСкидка85 = 20;
        НеизвестныйИсход85 = Ложь;
        Статус85 = "Managed ЗаписатьTrue, Прочитать0, независимый fullset/query/freshValueManager20%/800.";
    Исключение
        РазрешенаЗапись85 = Ложь;
        НеизвестныйИсход85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура Перечитать85(Команда)
    Если Команда.Имя <> "Перечитать85" Или НеизвестныйИсход85 Тогда
        ВызватьИсключение "Не маскируем неизвестный результат перечитыванием.";
    КонецЕсли;
    ЭтаФорма.Прочитать();
    Сумма85 = ПроверитьПрочитанное85(ТекущаяСкидка85);
    Статус85 = "Native Прочитать0 подтвердил сохраненную скидку" + Строка(ТекущаяСкидка85) + " и сумму" + Строка(Сумма85);
КонецПроцедуры

&НаКлиенте
Процедура ОтменитьИЗакрыть85(Команда)
    Если Команда.Имя <> "ОтменитьИЗакрыть85" Или НеизвестныйИсход85 Тогда
        ВызватьИсключение "Отмена не означает rollback неизвестной записи.";
    КонецЕсли;
    Если ПроверитьПрочитанное85(ТекущаяСкидка85) <> 1000 * (100 - ТекущаяСкидка85) / 100 Тогда
        ВызватьИсключение "Сохраненное значение изменилось.";
    КонецЕсли;
    РазрешеноЗакрытие85 = Истина;
    ЭтаФорма.Модифицированность = Ложь;
    Закрыть();
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Если РазрешеноЗакрытие85 <> Истина Тогда
        Отказ = Истина;
        ТекстПредупреждения = "Завершите явно только собственную форму; неизвестный исход исследуется вручную.";
    КонецЕсли;
КонецПроцедуры
MANAGED_HUB — полный модуль

Своя CF → Общие → Общие формы → Уч85ЗапускКонстантУправляемый → Модуль

Толстый управляемый клиент, вызов экспортов общего серверного модуля

&НаКлиенте
Перем ОткрытиеВыдано85;

&НаКлиенте
Процедура ОткрытьНастройки85(Команда)
    Если Команда.Имя <> "ОткрытьНастройки85" Или ОткрытиеВыдано85 = Истина Тогда
        ВызватьИсключение "Не та собственная команда.";
    КонецЕсли;
    Уч85КонстантыСтенд.Снимок85(15);
    ОткрытиеВыдано85 = Истина;
    Форма85 = ПолучитьФорму("ОбщаяФорма.Уч85НастройкиУправляемая", , ЭтаФорма, Истина);
    Если ТипЗнч(Форма85) <> Тип("ФормаКлиентскогоПриложения")
        Или Форма85.ИмяФормы <> "ОбщаяФорма.Уч85НастройкиУправляемая" Или Форма85.ВладелецФормы <> ЭтаФорма Тогда
        ВызватьИсключение "Не получена настоящая своя managed форма констант.";
    КонецЕсли;
    Форма85.Открыть();
КонецПроцедуры
VALUE_MODULE — полный модуль

Своя CF → Константы → каждая из трех собственных констант → Модуль менеджера значения

Модуль менеджера значения, сервер/толстый клиент

Процедура ПередЗаписью(Отказ)
    Отказ = Истина;
    Уч85КонстантыСтенд.ПроверитьМенеджер85(ЭтотОбъект);
    Отказ = Ложь;
КонецПроцедуры
ORDINARY_APPLICATION — полный модуль

Своя CF → Модуль обычного приложения

Модуль обычного приложения, толстый обычный клиент

Процедура ПриНачалеРаботыСистемы()
    Уч85КонстантыСтенд.Снимок85();
    ОткрытьФорму("ОбщаяФорма.Уч85ЗапускКонстантОбычный");
КонецПроцедуры
MANAGED_APPLICATION — полный модуль

Своя CF → Модуль управляемого приложения

Модуль управляемого приложения, толстый управляемый клиент

Процедура ПриНачалеРаботыСистемы()
    Уч85КонстантыСтенд.Снимок85(15);
    ОткрытьФорму("ОбщаяФорма.Уч85ЗапускКонстантУправляемый");
КонецПроцедуры

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

  1. Вручную подготовьте именно свою новую CF, пользователя и три значения10/UUID-пакета/actual-user-UUID, затем установите полные модули и genuine native события. Запуск выполняет ученик, не авторский тест.

  2. Обычный запуск: ЧерезМенеджер85 создает отдельную ordinary форму; без согласия сохранение отказано. ОтменитьИЗакрыть85 проверяет весь baseline10/900 и не пишет.

  3. ЧерезНабор85 создает новое собственное ordinary окно через настоящий предварительно прочитанный КонстантыНабор. Отметьте согласие и единожды СохранитьПятнадцать85. NativeTrue → actual set.Read0 → full query/fresh manager confirms15/850. ОтменитьИЗакрыть85 оставляет15, не восстанавливает10.

  4. Закройте весь обычный клиент. Новый отдельный толстый managed запуск допускается только при сохраненных15/850. ОткрытьНастройки85 дает свое единственное managed окно через точный metadata-name; исходная форма-data преобразуется в native КонстантыНабор только на сервере.

  5. Отметьте отдельное согласие, единожды СохранитьДвадцать85: native ЗаписатьTrue/Прочитать0, реальный fullset/manager/query подтверждают20/800 и обе неизменные UUID-строки. Перечитать85 только читает, ОтменитьИЗакрыть85 не делает новую запись.

  6. При False/исключении/несовпадении readback неизвестный исход остаетсяTrue; не повторяйте, не закрывайте как будто запись отменена, не восстанавливайте baseline вслепую. Вручную исследуйте только собственную ИБ. Принудительное завершение не доказывает rollback.

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

  1. ExactFile/CF/compatibility/platform8.5.1.1343/current-user/count1/metadata3/sharedattributes0/extensions0 проверяются до любой будущей записи через свежий Снимок85. Одновременные сеансы запрещены вручную, readback не доказывает конкурентную атомарность.

  2. КонстантыНабор содержит ровно явно выбранные три своих поля; у native набора нет выдуманного Количество/итератора. Свежий value manager читает реально сохраненное значение, полный запрос без WHERE/ТОП возвращает одну строку всех трех полей и сумму из actual скидки.

  3. Пустой native typed ключ проверяет собственную metadata-константу и поля ключа по умолчанию при отсутствии разделителей. Сохраненная скидка при этом10/15/20, не пустая. Не передавайте ключ в Константы.Имя.Получить0 и не создавайте абстрактный <Имя константы>.

  4. ОбменДанными readonly: только чтение native Загрузка=False/Отправитель=Undefined/Получатели0. BeforeWrite actual value manager1 отдельно от ordinary form1 и managed server form3. Native callbacks вызываются платформой, никогда вручную.

  5. Обе формы созданы genuine мастером Форма констант. GetForm manager/set толькоthick и возвращает обычную Форма/Undefined; managed использует собственный глобальный factory. Все PRIMARY реально находятся в MAIN, supporting-only методы не кредитуются.

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

Новичок получает два полностью подготовленных маршрута собственной настройки: обычная форма сохраняет скидку10→15 и счет900→850, отдельная managed форма15→20 и850→800; три фактических источника подтверждают весь пакет, отмена/чтение не записывают. Пока проверены исходники и native контракты, не исполнение1С.

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

  1. Native ПередЗаписьюНаСервере3 выполняется вне транзакции; форму, набор и value manager нельзя считать общей доказанной атомарной операцией. Не обещаем rollback/автовосстановление или успешную компиляцию без ручного испытания.

  2. Режим совместимости нельзя заменить одной проверкой версии платформы. Общий серверный модуль и native форма имеют разные клиентские/серверные контексты.

  3. Снимаем Модифицированность лишь после явной проверки сохраненного полного источника и согласованного закрытия; стандартные кнопки/крестик до явного завершения запрещены учебным протоколом, это не sandbox произвольного кода.

  4. При выключенном обработчике/иных настройках прав/скрытых строках/ошибке типизации остановитесь. Не отключайте проверки и не переключайте Загрузка=True.

  5. История и два legacy комментария исключены. UserUUID/метку не выводите в сеть/журнал; собственный путь и маркер не подменяют native идентичность информационной базы.

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

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

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

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

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