Глобальный контекст.ОткрытьФорму

Методы · OpenForm

Открывает и возвращает форму или управляемую форму. В тонком и веб-клиенте только управляемую форму. Перед открытием осуществляется поиск уже открытой такой же формы. Поиск осуществляется по типу формы, значениям ключевых параметров формы, владельцу формы, пользовательскому ключу уникальности. Для следующих форм при попытке обнаружить открытую форму владелец не учитывается и метод вернет уже открытую форму: ФормаОбъекта, ФормаЗаписи, ФормаНабораЗаписей, ФормаКонстант. Можно открывать уже полученную форму. В этом случае в параметрах передается уже полученная форма и окно, в котором открыть форму. Можно открыть форму по имени. В этом случае в параметры передаются имя формы, параметры формы, владелец, ключ уникальности и окно, в котором должна быть открыта форма.

Синтаксис

ОткрытьФорму(<ИмяФормы>, <Параметры>, <Владелец>, <Уникальность>, <Окно>, <НавигационнаяСсылка>, <ОписаниеОповещенияОЗакрытии>, <РежимБлокировкиПриОткрытииОкна>, <РежимОтображенияОкна>)
ОткрытьФорму(<Форма>, <Окно>)
Полное описание, параметры и ограничения

Глобальный контекст.ОткрытьФорму (Global context.OpenForm)

Глобальный контекст (Global context)

ОткрытьФорму (OpenForm)

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

Вариант синтаксиса: По имени

Синтаксис:
ОткрытьФорму(<ИмяФормы>, <Параметры>, <Владелец>, <Уникальность>, <Окно>, <НавигационнаяСсылка>, <ОписаниеОповещенияОЗакрытии>, <РежимБлокировкиПриОткрытииОкна>, <РежимОтображенияОкна>)
Параметры:

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

ФормаГруппы (FolderForm) - форма группы по умолчанию;

ФормаЗаписи (RecordForm) - форма записи регистра по умолчанию;

ФормаСписка (ListForm) - форма списка по умолчанию;

ФормаВыбора (ChoiceForm) - форма выбора по умолчанию;

ФормаВыбораГруппы (FolderChoiceForm) - форма выбора группы по умолчанию;

ФормаКонстант (ConstantsForm) - форма констант по умолчанию;

Форма (Form) - форма отчета и обработки по умолчанию;

ФормаНастроек (SettingsForm) - форма настроек отчета по умолчанию;

ФормаЗагрузки (LoadForm) - форма загрузки настроек;

ФормаСохранения (SaveForm) - форма сохранения настроек;

ФормаВарианта (VariantForm) - форма редактирования варианта отчета;

ФормаЗагрузкиПользовательскихНастроекОтчетов (ReportUserSettingsLoadForm) - форма загрузки настроек отчета;

ФормаСохраненияПользовательскихНастроекОтчетов (ReportUserSettingsSaveForm) - форма сохранения настроек отчета;

ФормаЗагрузкиВариантовОтчетов (ReportVariantsLoadForm) - форма загрузки варианта отчета;

ФормаСохраненияВариантовОтчетов (ReportVariantsSaveForm) - форма сохранения варианта отчета;

ФормаЗагрузкиНастроекДанныхФорм (FormDataSettingsLoadForm) - форма загрузки настроек данных форм;

ФормаСохраненияНастроекДанныхФорм (FormDataSettingsSaveForm) - форма сохранения настроек данных форм;

ФормаПоиска (SearchForm) - форма полнотекстового поиска в данных;

ФормаИсторииИзмененийИсторииДанных (DataHistoryChangeHistoryForm) - форма истории изменений, отображает список версий данных, параметры см. Системная форма истории изменений истории данных;

ФормаДанныхВерсииИсторииДанных (DataHistoryVersionDataForm) - форма данных версии, отображающая отчет "Данные версии", параметры см. Системная форма данных версии истории данных;

ФормаРазличийВерсийИсторииДанных (DataHistoryVersionDifferencesForm) - форма различий версий истории данных, отображающая отчет "Различия версий", параметры см. Системная форма различий версий истории данных.
Для внешних отчетов и обработок имя формы задается следующим образом:
ВнешнийОтчет.<имя отчета>.Форма.<имя формы>;

ВнешнийОтчет.<имя отчета>.<имя стандартной формы>;

ВнешняяОбработка.<имя обработки>.Форма.<имя формы>;

ВнешняяОбработка.<имя обработки>.<имя стандартной формы>.
При этом внешний отчет или обработка должны быть предварительно зарегистрированы в системе. Для регистрации отчета следует использовать метод Подключить. Для регистрации обработки следует использовать метод Подключить. <Имя отчета> и <имя обработки> - это имена, под которыми зарегистрированы внешний отчет или обработка.

<Параметры> (необязательный)
Тип: Структура.
Параметры формы. Ключ структуры - имя параметра, а значение - значение параметра формы. Имя элемента должно совпадать с именем параметра структуры.

П = Новый Структура("Ключ", Поставщик);
Форма = ПолучитьФорму("Справочник.Контрагенты.ФормаОбъекта", П);
Форма.Открыть();

<Владелец> (необязательный)
Владелец формы - форма или элемент управления другой формы.

<Уникальность> (необязательный)
Тип: Произвольный.
В данном параметре может быть задан некоторый ключ, значение которого будет использоваться для поиска уже открытых форм. Если будет найдена форма с таким же ключом уникальности, вместо открытия новой формы будет активизирована найденная форма.
Ложь - искать форму с ключом уникальности по умолчанию, Истина - не искать форму вообще, любое другое значение устанавливает ключ уникальности, по которому будет произведен поиск.
Значение по умолчанию: Ложь.

<Окно> (необязательный)
Тип: ОкноКлиентскогоПриложения.
Окно приложения, в котором будет открыта форма.
Применимо только для формы клиентского приложения. Окном может быть только основное окно приложения или вспомогательное окно формы.
Используется только в управляемом приложении.

<НавигационнаяСсылка> (необязательный)
Тип: Строка, Неопределено.
Если содержит значение, отличное от Неопределено, то это значение присваивается свойству НавигационнаяСсылка формы, полученной в результате вызова данного метода, и свойство АвтоНавигационнаяСсылка этой формы устанавливается в Ложь.
Значение по умолчанию: Неопределено.

<ОписаниеОповещенияОЗакрытии> (необязательный)
Тип: ОписаниеОповещения.
Содержит описание процедуры, которая будет вызвана при закрытии формы со следующими параметрами:
<РезультатЗакрытия> - значение, переданное при вызове метода Закрыть открываемой формы,
<ДополнительныеПараметры> - значение, которое было указано при создании объекта ОписаниеОповещения.
Если параметр не указан, то по завершению никакая процедура вызвана не будет.
Используется только в управляемом приложении.

<РежимБлокировкиПриОткрытииОкна> (необязательный)
Тип: РежимБлокировкиПриОткрытииОкнаФормы.
Указывает режим блокировки при открытии окна формы клиентского приложения.
Используется только в управляемом приложении.
Форма, открытая в режиме БлокироватьВладельца, не участвует в поиске уже открытых форм. При попытке открыть такую же форму (с параметром уникальности, установленным в значение Ложь), форма открытая в таком режиме, не будет найдена и будет открыта новая форма.
Значение по умолчанию: Неопределено.

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

Синтаксис:
ОткрытьФорму(<Форма>, <Окно>)
Параметры:

<Форма> (обязательный)
Тип: Форма, ФормаКлиентскогоПриложения.
Форма или форма клиентского приложения. В режиме тонкого и веб-клиентов только форма клиентского приложения.

<Окно> (необязательный)
Тип: ОкноКлиентскогоПриложения.
Окно приложения, в котором будет открыта форма.
Применимо только для формы клиентского приложения. Окном может быть только основное окно приложения или вспомогательное окно формы.
Возвращаемое значение:
Тип: Форма, ФормаКлиентскогоПриложения.

Описание:

Открывает и возвращает форму или управляемую форму. В тонком и веб-клиенте только управляемую форму. Перед открытием осуществляется поиск уже открытой такой же формы. Поиск осуществляется по типу формы, значениям ключевых параметров формы, владельцу формы, пользовательскому ключу уникальности.
Для следующих форм при попытке обнаружить открытую форму владелец не учитывается и метод вернет уже открытую форму:
ФормаОбъекта,

ФормаЗаписи,

ФормаНабораЗаписей,

ФормаКонстант.
Можно открывать уже полученную форму. В этом случае в параметрах передается уже полученная форма и окно, в котором открыть форму.
Можно открыть форму по имени. В этом случае в параметры передаются имя формы, параметры формы, владелец, ключ уникальности и окно, в котором должна быть открыта форма.

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

Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение (клиент).
Вызов метода выполняет обращение к серверу.

Примечание:
Для варианта "По имени" параметры вызова аналогичны параметрам метода ПолучитьФорму.
Обычные формы внешних обработок не поддерживаются.
В управляемом приложении не следует выполнять программное открытие и закрытие одной и той же формы в одном вызове встроенного языка.
Если при открытии обычной формы в параметре <ИмяФормы> указано не стандартное имя формы, передаваемые параметры не обрабатываются.
В процессе выполнения может быть несколько обращений к серверу. Часть из них кэшируются. Как минимум одно обращение к серверу есть всегда и оно не кэшируется. Кэширование зависит от версии платформы и версии конфигурации в целом. Если установлена низкая скорость соединения и не указывается текущая строка, то кэшируется форма выбора. Очистка кэша осуществляется с периодичностью в 20 мин. Удаляются формы, которые не использовались в этот период времени.
См. также:
Глобальный контекст, метод ПолучитьФорму
Глобальный контекст, метод ПолучитьОбщуюФорму
Глобальный контекст, метод ОткрытьФормуМодально

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

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

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

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

Свое клиентское приложение: учебное окно750 и возврат исходного оформления за два настоящих запуска

Настоящий readonly global КлиентскоеПриложение, не неизвестный исходный объект. Window/OS setters работают только внутри настоящего BeforeStart, заголовки — после открытия своего окна. Реальный baseline сохраняется в одном собственном user-scoped ключе и проверенно возвращается при втором ручном старте.

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

Главный APPLICATION целиком в реальный модуль управляемого приложения own УчебноеОкно85. Window/OS setters прямо в ПередНачаломРаботыСистемы(Отказ), title setters после появления окна. SERVER отдельно server-call общий модуль, FORM отдельно actual общая управляемая форма. Два ручных own WindowsThinTaxi/FileIB запуска.

Подготовка

  1. Подготовьте отдельную собственную Windows VM с платформой8.5.1.1343, тонким клиентом и управляемым интерфейсом Такси. Не используйте интерфейс Версия8_5 для этого опыта: native OS-caption setter там игнорируется. Это собственный клиент, не перебор/подключение чужих процессов или COM.

  2. Вручную создайте новый canonical nonzero UUID-marker и собственную пустую FileIB C:\1c-labs\Уч85Окно_<UUID>\. Имя конфигурации УчебноеОкно85. В списке баз зарегистрируйте строго File="C:\1c-labs\Уч85Окно_<UUID>\";. Path-marker не является UUID самой информационной базы; реальный UUID базы в коде не измеряется. Состояние.База содержит только эту метку пути. Другие пути/параметры отвергаются, строка соединения не печатается.

  3. Создайте ровно одного настоящего пользователя IB Уч85Окно_<UUID> с правами чтения списка пользователей и СохранениеДанныхПользователя в этой учебной базе. Список и UUID реального текущего пользователя ИБ проверяются; Состояние.Пользователь сохраняет actualIBUserUUID из ТекущийПользователь().УникальныйИдентификатор, не UUID базы. Это важно, поскольку native settings связаны с именем пользователя и имя может повторно использовать другой IBUser.

  4. Конфигурация пустая: справочников/документов/регистров/общих реквизитов/разделителей/подписок/регламентных заданий/ботов/констант/расширений нет. Не меняйте типовую конфигурацию. Добавьте только указанные ниже свой общий модуль и свою одну общую управляемую форму; другие стартовые модули/обработчики отсутствуют.

  5. Конфигуратор → свойства конфигурации: управляемое приложение, интерфейс Такси. Первый baseline должен иметь Обычный режим окна и настоящий Boolean отображения заголовкаОС: принимаются и True, и False. Учебное значение — противоположное реально полученному, а не guessed default. Код не принимает kiosk/fullscreen baseline. Два исходных текста берутся реальными getters.

  6. Конфигуратор → Общие → Общие модули → УчебноеОкно85: Сервер/Вызов сервера=Да, Клиент/Привилегированный/Глобальный=Нет. Вставьте полный SERVER. ХранилищеСистемныхНастроек доступно серверу, не тонкому клиенту. Работа только с собственным объектным ключом Уч85Окно85_<marker> и ключом настройки СвойЦиклОкна85; ИмяПользователя не передается, поэтому native использует текущего пользователя.

  7. Конфигуратор → Общие → Общие формы → УчебноеОкно85: управляемая форма. Создайте параметры формы МеткаБазы/Nonce (Строка36), реквизиты с теми же именами (Строка36) и Подтверждение (Строка100). Создайте команды ПроверитьОкно/ВернутьСвоиЗаголовки, разместите кнопки и поле подтверждения. Вставьте FORM целиком; событие ПриСозданииНаСервере имеет2параметра и переносит собственные startup parameters в реквизиты.

  8. Конфигуратор → Конфигурация → Открыть модуль управляемого приложения: вставьте APPLICATION целиком. Native ПередНачаломРаботыСистемы(Отказ) настраивает окно до его появления; ПриНачалеРаботыСистемы() после открытия проверяет оформление, задает свои заголовки и открывает только свою общую форму. Не вызывайте эти процедуры вручную и не переносите window/OS setters в форму или обычный helper.

  9. Первый ручной запуск выполните тонким клиентом этой своей базы, задав дополнительный параметр запуска /C"Уч85Окно|<ваш UUID>|ОПЫТ85". ПараметрЗапуска native получает именно /C. Без точных трех частей старт отклоняется; это осознанная учебная фаза, не автоизменение при любом открытии произвольной базы.

  10. Первый BeforeStart сохраняет реально полученные Normal/Boolean OS/two captions в собственном ключе для actual IBUser, затем ставит РабочееМесто и противоположное отображение заголовкаОС. При существующем ключе опыт не повторяется и baseline не перезаписывается. Main-window mode и OS-caption setters оба разрешены только в этом событии.

  11. В РабочемМесте скрываются системное меню и многие панели/горячие клавиши; поэтому ПриНачалеРаботыСистемы открывает заранее подготовленную общую форму, а не требует открыть внешнюю обработку через скрытое меню. Закрытие главного окна остается доступным. Это не киоск/forcefullscreen и не запрет на работу ОС.

  12. После открытия окна native getters проверяют РабочееМесто/свое противоположное значение OS и исходные тексты. Затем задаются собственные заголовок Уч85Окно|Книга750|nonce и краткий Книга750|nonce, оба отдельно читаются. Краткий заголовок вставляется перед системным и отделяется точкой: getter возвращает свое значение, не весь нарисованный ОС-заголовок.

  13. Откройте автоматически показанную свою форму, нажмите ПроверитьОкно и осмотрите настоящее окно вручную. Введите ВОЗВРАТ МОИХ ЗАГОЛОВКОВ85 и нажмите ВернутьСвоиЗаголовки один раз. Возврат разрешен лишь при exact own caption/short/mode/OS/nonce. Два текста возвращаются к real baseline и читаются; если кто-то изменил оформление, код не перезаписывает его.

  14. После подтвержденной фазы ЗаголовкиВозвращены вручную закройте только собственное приложение. Не называйте это полным возвратом окна: Mode/OS нельзя изменить из формы. Сохраненная запись не удаляется. Не запускайте параллельные сеансы и не меняйте конфигурацию/пользователя/интерфейс между двумя стартами.

  15. Второй ручной запуск той же базы/пользователя задайте с /C"Уч85Окно|<тот же UUID-marker пути>|ВОЗВРАТ85". Native BeforeStart проверяет сохраненный actualIBUserUUID реального текущего пользователя ИБ и nonce, фазу и исходные тексты. Режим окна может уже быть исходным из нового запуска либо оставаться нашим РабочимМестом; иные режимы отвергаются. Возвращаются сохраненные Normal/исходный Boolean OS, не guessed defaults.

  16. Второй native OnStart после открытия проверяет фактические mode/OS/caption/short и только затем сохраняет Завершен. Пользователь отдельно осматривает окно. Font getter дает вариант шрифта, не пиксельный размер/имя установленного шрифта; ТипПриложения — настоящий тонкий клиент.

  17. КлиентСИспользованиемАвтономногоСервера по точной native справке проверяет способность данного типа клиента работать с автономным сервером, не факт подключения. В этом fixture явно FileIB; значениеBoolean не объявляется живым соединением с автономным сервером, и сервер не запускается.

  18. Любая ошибка/cancel может оставить собственный state/оформление частично измененными. Ключи/phase не являются общей транзакцией или доказательством скриншота; автоматического blindrestore/retry/deleteall нет. При неизвестном/частичном результате остановитесь и вручную проверьте только свой стенд. При авторстве реальные1С/настройкиБД/UI/процессы/сеть/файлы не изменялись, backup0.

Перем СвояМеткаОкна85;
Перем СвойСтартОкна85;
Перем СвойСнимокОкна85;

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

Процедура ПриНачалеРаботыСистемы()
    Если СвойСнимокОкна85 = Неопределено Тогда
        ВызватьИсключение "Own native BeforeStart не подготовил настоящий сохраненный baseline";
    КонецЕсли;
    Свежий = УчебноеОкно85.ПолучитьСвоеСостояниеОкна85(СвояМеткаОкна85);
    Если Свежий.Nonce <> СвойСнимокОкна85.Nonce Тогда
        ВызватьИсключение "Собственный старт получил чужой nonce";
    КонецЕсли;
    Если СвойСтартОкна85 = "ОПЫТ85" Тогда
        Если Свежий.Фаза <> "Подготовлен" Или КлиентскоеПриложение.ПолучитьРежимОсновногоОкна() <> РежимОсновногоОкнаКлиентскогоПриложения.РабочееМесто
            Или КлиентскоеПриложение.ПолучитьОтображениеЗаголовкаОС() <> Свежий.СвойЗаголовокОС
            Или КлиентскоеПриложение.ПолучитьЗаголовок() <> Свежий.Заголовок
            Или КлиентскоеПриложение.ПолучитьКраткийЗаголовок() <> Свежий.КраткийЗаголовок Тогда
            ВызватьИсключение "Actual own first main-window/baseline не подтвержден; не перезаписываем заголовки";
        КонецЕсли;
        КлиентскоеПриложение.УстановитьЗаголовок(Свежий.СвойЗаголовок);
        КлиентскоеПриложение.УстановитьКраткийЗаголовок(Свежий.СвойКраткий);
        Если КлиентскоеПриложение.ПолучитьЗаголовок() <> Свежий.СвойЗаголовок
            Или КлиентскоеПриложение.ПолучитьКраткийЗаголовок() <> Свежий.СвойКраткий Тогда
            ВызватьИсключение "Own заголовки могли измениться частично, но отдельно не подтверждены. Повтора/автоrestore нет";
        КонецЕсли;
        СвойСнимокОкна85 = УчебноеОкно85.ПеревестиСвоюФазуОкна85(СвояМеткаОкна85, Свежий.Nonce, "Подготовлен", "Показан");
    Иначе
        Если Свежий.Фаза <> "ВозвратНачат" Или КлиентскоеПриложение.ПолучитьРежимОсновногоОкна() <> Свежий.РежимОкна
            Или КлиентскоеПриложение.ПолучитьОтображениеЗаголовкаОС() <> Свежий.ЗаголовокОС
            Или КлиентскоеПриложение.ПолучитьЗаголовок() <> Свежий.Заголовок
            Или КлиентскоеПриложение.ПолучитьКраткийЗаголовок() <> Свежий.КраткийЗаголовок Тогда
            ВызватьИсключение "Исходный real saved own UI baseline после второго старта не подтвержден";
        КонецЕсли;
        СвойСнимокОкна85 = УчебноеОкно85.ПеревестиСвоюФазуОкна85(СвояМеткаОкна85, Свежий.Nonce, "ВозвратНачат", "Завершен");
    КонецЕсли;
    Шрифт = КлиентскоеПриложение.ТекущийВариантОсновногоШрифта();
    ВозможенАвтономный = КлиентскоеПриложение.КлиентСИспользованиемАвтономногоСервера();
    Если ТипЗнч(Шрифт) <> Тип("ВариантОсновногоШрифтаКлиентскогоПриложения") Или ТипЗнч(ВозможенАвтономный) <> Тип("Булево") Тогда
        ВызватьИсключение "Native font/capability types не совпали";
    КонецЕсли;
    Сообщить("Свой thin-client: " + Строка(КлиентскоеПриложение.ТипПриложения()) + "; основной шрифт: " + Строка(Шрифт));
    Сообщить("Способность этого типа клиента работать с автономным сервером: " + Строка(ВозможенАвтономный) + ". Это НЕ факт подключения: наш fixture использует FileIB");
    Сообщить("Own phase: " + СвойСнимокОкна85.Фаза + "; nonce: " + СвойСнимокОкна85.Nonce);
    ОткрытьФорму("ОбщаяФорма.УчебноеОкно85", Новый Структура("МеткаБазы,Nonce", СвояМеткаОкна85, СвойСнимокОкна85.Nonce));
КонецПроцедуры
Полный серверный модуль собственного baseline/phase в одном current-user system-settings ключе

Конфигуратор → Общие → Общие модули → УчебноеОкно85 → Модуль.

Серверный server-call общий модуль; exact ownIB/current realuser и только own scoped native settings. Window/OS client setters здесь отсутствуют.

Функция СохранитьПервоеСостояниеОкна85(МеткаБазы, ИсходноеОкно, ИсходныйОС, ИсходныйЗаголовок, ИсходныйКраткий) Экспорт
    Паспорт = ПроверитьСвоюБазуОкна85(МеткаБазы);
    Если ХранилищеСистемныхНастроек.Загрузить(Паспорт.КлючОбъекта, "СвойЦиклОкна85") <> Неопределено Тогда
        ВызватьИсключение "Own namespace уже содержит состояние; первый запуск не повторяется";
    КонецЕсли;
    Если ТипЗнч(ИсходноеОкно) <> Тип("РежимОсновногоОкнаКлиентскогоПриложения")
        Или ИсходноеОкно <> РежимОсновногоОкнаКлиентскогоПриложения.Обычный
        Или ТипЗнч(ИсходныйОС) <> Тип("Булево")
        Или ТипЗнч(ИсходныйЗаголовок) <> Тип("Строка") Или СтрДлина(ИсходныйЗаголовок) > 512
        Или ТипЗнч(ИсходныйКраткий) <> Тип("Строка") Или СтрДлина(ИсходныйКраткий) > 512 Тогда
        ВызватьИсключение "Нужен реальный Normal/Boolean OScaption собственный baseline и две исходные строки";
    КонецЕсли;
    Nonce = Строка(Новый УникальныйИдентификатор);
    Состояние = Новый Структура("База,Пользователь,Nonce,РежимОкна,ЗаголовокОС,СвойЗаголовокОС,Заголовок,КраткийЗаголовок,СвойЗаголовок,СвойКраткий,Фаза",
        МеткаБазы, Паспорт.Пользователь, Nonce, ИсходноеОкно, ИсходныйОС, Не ИсходныйОС, ИсходныйЗаголовок, ИсходныйКраткий,
        "Уч85Окно | Книга3×250=750 | " + Nonce, "Книга750 | " + Nonce, "Подготовлен");
    ХранилищеСистемныхНастроек.Сохранить(Паспорт.КлючОбъекта, "СвойЦиклОкна85", Состояние);
    Свежий = ПолучитьСвоеСостояниеОкна85(МеткаБазы);
    Если Свежий.Nonce <> Nonce Или Свежий.Фаза <> "Подготовлен" Тогда
        ВызватьИсключение "Запись своего baseline могла произойти, но отдельно не подтверждена; не повторяйте";
    КонецЕсли;
    Возврат Свежий;
КонецФункции

Функция ПолучитьСвоеСостояниеОкна85(МеткаБазы) Экспорт
    Паспорт = ПроверитьСвоюБазуОкна85(МеткаБазы);
    Состояние = ХранилищеСистемныхНастроек.Загрузить(Паспорт.КлючОбъекта, "СвойЦиклОкна85");
    Если ТипЗнч(Состояние) <> Тип("Структура") Тогда
        ВызватьИсключение "Собственный real saved baseline не найден";
    КонецЕсли;
    Если Состояние.База <> МеткаБазы Или Состояние.Пользователь <> Паспорт.Пользователь
        Или ТипЗнч(Состояние.Nonce) <> Тип("Строка") Или СтрДлина(Состояние.Nonce) <> 36
        Или Состояние.РежимОкна <> РежимОсновногоОкнаКлиентскогоПриложения.Обычный
        Или ТипЗнч(Состояние.ЗаголовокОС) <> Тип("Булево") Или ТипЗнч(Состояние.СвойЗаголовокОС) <> Тип("Булево")
        Или Состояние.СвойЗаголовокОС <> (Не Состояние.ЗаголовокОС) Или ТипЗнч(Состояние.Заголовок) <> Тип("Строка")
        Или ТипЗнч(Состояние.КраткийЗаголовок) <> Тип("Строка") Или СтрДлина(Состояние.Заголовок) > 512
        Или СтрДлина(Состояние.КраткийЗаголовок) > 512 Тогда
        ВызватьИсключение "Own namespace/current actualIBUserUUID/baseline passport изменен";
    КонецЕсли;
    UUIDNonce = Новый УникальныйИдентификатор(Состояние.Nonce);
    Если Состояние.Nonce <> Строка(UUIDNonce) Или UUIDNonce = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000")
        Или Состояние.СвойЗаголовок <> "Уч85Окно | Книга3×250=750 | " + Состояние.Nonce
        Или Состояние.СвойКраткий <> "Книга750 | " + Состояние.Nonce Тогда
        ВызватьИсключение "Собственная учебная строка/nonce не подтвердились";
    КонецЕсли;
    Возврат Состояние;
КонецФункции

Функция ПеревестиСвоюФазуОкна85(МеткаБазы, Nonce, ИзФазы, ВФазу) Экспорт
    Паспорт = ПроверитьСвоюБазуОкна85(МеткаБазы);
    Состояние = ПолучитьСвоеСостояниеОкна85(МеткаБазы);
    Если Состояние.Nonce <> Nonce Или Состояние.Фаза <> ИзФазы Тогда
        ВызватьИсключение "Чужой/старый nonce или повтор own phase не принимается";
    КонецЕсли;
    Допустимо = (ИзФазы = "Подготовлен" И ВФазу = "Показан")
        Или (ИзФазы = "Показан" И ВФазу = "ЗаголовкиВозвращены")
        Или (ИзФазы = "ЗаголовкиВозвращены" И ВФазу = "ВозвратНачат")
        Или (ИзФазы = "ВозвратНачат" И ВФазу = "Завершен");
    Если Не Допустимо Тогда
        ВызватьИсключение "Переход не входит в собственный цикл двух ручных запусков";
    КонецЕсли;
    Состояние.Фаза = ВФазу;
    ХранилищеСистемныхНастроек.Сохранить(Паспорт.КлючОбъекта, "СвойЦиклОкна85", Состояние);
    Свежий = ПолучитьСвоеСостояниеОкна85(МеткаБазы);
    Если Свежий.Фаза <> ВФазу Или Свежий.Nonce <> Nonce Тогда
        ВызватьИсключение "Переход own phase мог сохраниться, но отдельно не подтвержден; автоматического повтора нет";
    КонецЕсли;
    Возврат Свежий;
КонецФункции

Функция ПроверитьСвоюБазуОкна85(МеткаБазы)
    ПроверитьСвойПустойСтенд();
    UUIDМетки = Новый УникальныйИдентификатор(МеткаБазы);
    Если МеткаБазы <> Строка(UUIDМетки) Или UUIDМетки = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000") Тогда
        ВызватьИсключение "Own file-path marker должен быть canonical nonzero UUID; это метка пути, не UUID базы и не UUID реального пользователя ИБ";
    КонецЕсли;
    Соединение = "File=""C:\1c-labs\Уч85Окно_" + МеткаБазы + "\"";";
    Если СтрокаСоединенияИнформационнойБазы() <> Соединение Или ПривилегированныйРежим() Тогда
        ВызватьИсключение "Нужна только точная собственная новая FileIB без privileged. Connection string не выводится";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
        ВызватьИсключение "Нужен единственный real ownIBUser";
    КонецЕсли;
    Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
        Или Текущий.Имя <> "Уч85Окно_" + МеткаБазы Или Метаданные.ОбщиеФормы.Количество() <> 1
        Или Метаданные.ОбщиеФормы.УчебноеОкно85.Имя <> "УчебноеОкно85"
        Или Метаданные.Боты.Количество() <> 0 Или Метаданные.Константы.Количество() <> 0 Тогда
        ВызватьИсключение "Own actual user/sole common form/empty metadata не подтверждены";
    КонецЕсли;
    Возврат Новый Структура("КлючОбъекта,Пользователь", "Уч85Окно85_" + МеткаБазы, Строка(Текущий.УникальныйИдентификатор));
КонецФункции

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

Конфигуратор → Общие → Общие формы → УчебноеОкно85 → Модуль.

Клиент-серверный модуль actual общей управляемой формы. Прямые window/OS setters запрещены; settings остаются серверными.

Перем ВозвратЗаголовковНачат85;

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    МеткаБазы = Параметры.МеткаБазы;
    Nonce = Параметры.Nonce;
    Состояние = УчебноеОкно85.ПолучитьСвоеСостояниеОкна85(МеткаБазы);
    Если Состояние.Nonce <> Nonce Тогда
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьОкно(Команда)
    Состояние = ПолучитьСостояниеНаСервере85();
    Если КлиентскоеПриложение.ТипПриложения() <> ТипКлиентскогоПриложения.ТонкийКлиент Тогда
        ВызватьИсключение "Это не наш собственный тонкий клиент";
    КонецЕсли;
    Сообщить("Сохраненная own phase: " + Состояние.Фаза + "; actual window: " + Строка(КлиентскоеПриложение.ПолучитьРежимОсновногоОкна())
        + "; actual OS caption: " + Строка(КлиентскоеПриложение.ПолучитьОтображениеЗаголовкаОС()));
КонецПроцедуры

&НаКлиенте
Процедура ВернутьСвоиЗаголовки(Команда)
    Если ВозвратЗаголовковНачат85 = Истина Или Подтверждение <> "ВОЗВРАТ МОИХ ЗАГОЛОВКОВ85" Тогда
        ВызватьИсключение "Own возврат заголовков одноразовый и требует отдельной фразы";
    КонецЕсли;
    Состояние = ПолучитьСостояниеНаСервере85();
    Если Состояние.Фаза <> "Показан" Или КлиентскоеПриложение.ТипПриложения() <> ТипКлиентскогоПриложения.ТонкийКлиент
        Или КлиентскоеПриложение.ПолучитьЗаголовок() <> Состояние.СвойЗаголовок
        Или КлиентскоеПриложение.ПолучитьКраткийЗаголовок() <> Состояние.СвойКраткий
        Или КлиентскоеПриложение.ПолучитьРежимОсновногоОкна() <> РежимОсновногоОкнаКлиентскогоПриложения.РабочееМесто
        Или КлиентскоеПриложение.ПолучитьОтображениеЗаголовкаОС() <> Состояние.СвойЗаголовокОС Тогда
        ВызватьИсключение "Текущее оформление уже не наш checked snapshot; чужие/частичные значения не перезаписываются";
    КонецЕсли;
    ВозвратЗаголовковНачат85 = Истина;
    КлиентскоеПриложение.УстановитьЗаголовок(Состояние.Заголовок);
    КлиентскоеПриложение.УстановитьКраткийЗаголовок(Состояние.КраткийЗаголовок);
    Если КлиентскоеПриложение.ПолучитьЗаголовок() <> Состояние.Заголовок
        Или КлиентскоеПриложение.ПолучитьКраткийЗаголовок() <> Состояние.КраткийЗаголовок Тогда
        ВызватьИсключение "Own возврат мог произойти частично, но отдельно не подтвержден; не повторяйте";
    КонецЕсли;
    ПодтвердитьЗаголовкиНаСервере85();
    Сообщить("Только два own заголовка возвращены. Window-mode/OS-caption setters из формы запрещены: их восстановит следующий отдельный native BeforeStart с ВОЗВРАТ85");
КонецПроцедуры

&НаСервере
Функция ПолучитьСостояниеНаСервере85()
    Состояние = УчебноеОкно85.ПолучитьСвоеСостояниеОкна85(МеткаБазы);
    Если Состояние.Nonce <> Nonce Тогда
        ВызватьИсключение "Own form nonce не совпал с actual saved state";
    КонецЕсли;
    Возврат Состояние;
КонецФункции

&НаСервере
Процедура ПодтвердитьЗаголовкиНаСервере85()
    УчебноеОкно85.ПеревестиСвоюФазуОкна85(МеткаБазы, Nonce, "Показан", "ЗаголовкиВозвращены");
КонецПроцедуры

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

  1. Native readonly globalfactory дает текущий КлиентскоеПриложение; startup guard требует Thin/Taxi и Boolean OS-caption, исключая неподдерживаемые clients/styles.

  2. ПередНачаломРаботыСистемы имеет1параметр Отказ, OnStart0. Ни формы, ни сообщений/окон не создается до готовности главного окна; оба ограниченных setters находятся прямо в BeforeStart.

  3. Первый baseline взят из реальных getters до изменения, ограничен Normal/Boolean OS и сохраняется только в собственном user-scoped ключе, который изначально отсутствует. Противоположный Boolean используется для видимого собственного опыта.

  4. Сервер проверяет exact emptyFileIB/version/oneactualuser и сохраненный actualIBUserUUID реального пользователя ИБ. UUID самой базы не измеряется; ее поле База содержит marker пути. Settings.Load/Save без имени пользователя используют текущего; чужие ключи/пользователи/настройки не затрагиваются.

  5. После реального открытия своего окна mode/OS и заголовки сверяются. Новые caption/short с own nonce устанавливаются и читаются, не заявляются нарисованными только по return setters.

  6. Форма восстанавливает только два своих текста при совпадении текущего собственного оформления. Ее one-shot flag ставится до setters; partialfailure не запускает повтор или автоматический restore.

  7. Второй настоящий запуск разрешен после возвращенных текстов и подтвержденного состояния. Перед стартом допустимы только original/own window mode; новый клиент не выдается за тот же ОС-процесс.

  8. Восстановление Window/OS происходит только в новом native BeforeStart. OnStart отдельно читает весь original baseline и завершает own saved phase; запись сохраняется для ручной проверки.

  9. Font/тип/standalone capability применяются к текущему реальному клиенту. CapabilityBoolean не доказывает actual autonomous connection или готовый запущенный сервер.

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

  1. После первого старта свое приложение показывает РабочееМесто, противоположное собственному baseline отображение ОС-заголовка и два текста750; главный код не управляет чужими процессами.

  2. Форма подтверждает exact own nonce/current appearance и возвращает исходные два текста; window/OS setters из нее отсутствуют.

  3. После второго старта реальные mode/OS/caption/short совпали с сохраненным исходным baseline, а собственная запись отмечена Завершен.

  4. Возврат не выполняется при другом пользователе/пути/фазе/nonce/измененном оформлении. Partial/cancel не объявляются успешным завершением.

  5. Отчет о способности автономного сервера отделен от фактического FileIB connection. Шрифт прочитан как enum, не выдуманный Windows font.

  6. Нужен ручной запуск и визуальная проверка владельца своего стенда. Здесь native/static проверки, а не runtime/UI/DB результат вашей базы.

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

При двух успешных ручных запусках своего подготовленного WindowsThinTaxi/FileIB стенда native startup события меняют и отдельно возвращают оформление текущего собственного клиента. Исходные значения действительно получены getters и сохранены только в своем ключе текущего пользователя. Здесь runtime0; реальное отображение/перезапуск/настройки вашей базы не выполнялись.

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

  1. КлиентскоеПриложение получается из readonly global property, не constructor и не неизвестный переданный объект. Тот же тип доступен на сервере, но конкретные window/OS methods имеют более узкую client availability.

  2. УстановитьРежимОсновногоОкна и УстановитьОтображениеЗаголовкаОС разрешены исключительно в ПередНачаломРаботыСистемы. Нельзя восстановить их в форме/OnStart/обычном общему helper даже в thin-client.

  3. OS setter реально действует только WindowsThin/ThickTaxi; другие clients/interfaces игнорируют вызов. Getter может вернуть Undefined. Нельзя трактовать игнорирование как успешную UI-операцию.

  4. РабочееМесто скрывает меню, панели и горячие клавиши. Собственная заранее созданная общая форма открывается только после появления главного окна, поэтому опыт не зависит от скрытого пункта открытия EPF.

  5. Краткий заголовок автоматически отделяется точкой и участвует в составном системном заголовке. Getter своего значения не является OCR/скриншотом полного заголовка ОС.

  6. Settings storage scope — IB/имя пользователя. Переименование не загружает старые настройки, повторное использование имени может их наследовать; поэтому сохраненный actualIBUserUUID реального пользователя ИБ проверяется и не заменяется marker пути или UUID самой базы.

  7. Save требует СохранениеДанныхПользователя. Thin не вызывает системное settings storage напрямую; отдельный серверный модуль использует только own keys/currentuser, не стороннюю управленческую базу.

  8. Native startup отказ/exception может произойти после saved state или частичного UI изменения. Restore phase не является общей транзакцией. Не повторяйте первый старт поверх baseline и не удаляйте все system settings.

  9. Между двумя стартами новый процесс может уже иметь часть defaults. Это допустимый original snapshot, не гарантия сохранения setters между процессами. Иные modes/тексты отвергаются, а не слепо перезаписываются.

  10. Saved phase является журналом только собственного учебного цикла, не физической backup copy и не доказательством реального UI без manual inspection. No files/archives/backup APIs.

  11. Название ClientUsesStandaloneServer неоднозначно; exact native описание — способность типа клиента. True не означает actual connection, False из регламентного задания не описывает ваше интерактивное окно.

  12. В собственной VM нужны один реальный пользователь, неизмененная CF/Taxi и отсутствие параллельных сеансов. Автор не запускал1С/ОС/process/network/DB/settings/UI/files, а статические тесты не заменяют ваши runtime проверки.

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

ОткрытьФорму: передать оповещение закрытия седьмым аргументом

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

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

Полный модуль собственной общей управляемой формы УчебныеОкна85. Два экземпляра одной формы, тонкий клиент Windows; создание реквизитов на сервере, открытие/выбор/закрытие на клиенте.

Подготовка

  1. Используйте отдельную пустую учебную конфигурацию 8.5.1.1343 без рабочих данных и тонкий управляемый клиент Windows. Создайте общую управляемую форму УчебныеОкна85; имя в дереве Общие → Общие формы должно совпадать с кодом.

  2. На вкладке Параметры формы создайте Дочерняя, СтартовоеКоличество и КлючЗапроса. Значения передаются как Булево, Число и Строка. У всех трёх снимите Ключевой: пользовательский ключ уникальности задаётся отдельно четвёртым аргументом открытия.

  3. Событию ПриСозданииНаСервере назначьте одноимённую процедуру. Вставьте весь приведённый модуль выбранного урока. Реквизиты, поле количества, команду и кнопку вручную не создавайте: их добавляет код.

  4. Для запуска добавьте в свою учебную обработку пустую управляемую форму и команду ОткрытьУчебноеОкно. Через конструктор обработчика создайте клиентскую процедуру команды и поместите в её тело ровно ОткрытьФорму("ОбщаяФорма.УчебныеОкна85");. Эта внешняя кнопка открывает главное окно, а кнопки внутри урока открывают его дочерний экземпляр.

  5. В каждом уроке используйте отдельную копию своей конфигурации/формы. Все экземпляры создаются из одного полного модуля: главное окно имеет Дочерняя=Ложь, второе получает Дочерняя=Истина и собственные параметры.

  6. Количество главного окна первоначально 3, цена книги 250. В дочернем поле можно выбрать целое количество 1–10; никакой номенклатуры, документов, регистров, файлов, сети и печати не используется.

  7. Запуск в 1С не проверялся. Статические проверки не доказывают появление окна, возврат событий или фактическое поведение темы: выполните контрольные действия только на своём учебном стенде.

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

КонецПроцедуры

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

&НаКлиенте
Процедура ПроверитьСвоёКоличество(Знач Количество)
    Если ТипЗнч(Количество) <> Тип("Число") Тогда
        ВызватьИсключение "Количество должно быть числом";
    КонецЕсли;
    Если Количество < 1 Или Количество > 10 Или Количество <> Цел(Количество) Тогда
        ВызватьИсключение "Выберите целое количество от 1 до 10";
    КонецЕсли;
КонецПроцедуры

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

&НаКлиенте
Процедура ПринятьСвойРезультат(Результат, Знач ОжидаемыйКлюч)
    Если ТипЗнч(Результат) <> Тип("Структура") Тогда
        ВызватьИсключение "Результат собственного окна должен быть структурой";
    КонецЕсли;
    Если Не Результат.Свойство("КлючЗапроса") Или Не Результат.Свойство("Количество") Или Не Результат.Свойство("Сумма") Тогда
        ВызватьИсключение "Неполный собственный результат";
    КонецЕсли;
    Если Результат.КлючЗапроса <> ОжидаемыйКлюч Тогда
        ВызватьИсключение "Результат относится к другому собственному запросу";
    КонецЕсли;
    ПроверитьСвоёКоличество(Результат.Количество);
    Если ТипЗнч(Результат.Сумма) <> Тип("Число") Тогда
        ВызватьИсключение "Сумма собственного результата должна быть числом";
    КонецЕсли;
    Если Результат.Сумма <> Результат.Количество * 250 Тогда
        ВызватьИсключение "Сумма собственного результата не соответствует цене 250";
    КонецЕсли;
    УчебноеКоличество = Результат.Количество;
    Сообщить(УчебноеКоличество = Результат.Количество);
    Сообщить(Результат.Сумма = УчебноеКоличество * 250);
    Сообщить(СтрШаблон("Принято своих книг: %1, сумма: %2", УчебноеКоличество, Результат.Сумма));
КонецПроцедуры

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

  1. Собственная структура параметров содержит роль, стартовое количество и строковый ключ. Дополнительная структура описания хранит снимок владельца.

  2. Аргументы 1–4 задают имя, параметры, владельца и отсутствие поиска других экземпляров. Пятый и шестой явно Неопределено: окно и навигационная ссылка не настраиваются.

  3. Седьмой аргумент — ОписаниеОповещения, восьмой — РежимБлокировкиПриОткрытииОкнаФормы.БлокироватьВладельца. Не подставлять устаревшее перечисление РежимОткрытияОкнаФормы.

  4. Возвращаемая ДочерняяФорма — форма, не выбранное число. Само открытие не выполняет ПринятьСвойРезультат.

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

  6. Закрытие крестиком обрабатывается как отмена; предыдущие собственные данные не заменяются Неопределено.

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

  1. После подтверждения 5 — главное количество 5, сумма 1250 и два контроля Истина. До подтверждения главное поле ещё 3.

  2. Повторите опыт с отменой: количество не меняется и появляется отдельное сообщение об отсутствии результата. Код в инструкции не вызывает обработчик вручную.

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

Результат получен настоящим механизмом закрытия, с точными позициями новых параметров открытия 8.5.1.

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

  1. Не пропускайте позиции 5 и 6 без учёта синтаксиса: сдвиг параметров отдаст описание не в тот аргумент.

  2. Блокировка владельца не означает вызов ОткрытьФормуМодально и не превращает ОткрытьФорму в функцию результата выбора.

  3. Для аварийного закрытия приложения доставку клиентского ответа нельзя обещать. Важные рабочие записи не должны зависеть только от UI-оповещения.

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

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

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

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

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