Получает форму или форму клиентского приложения. Перед получением осуществляется поиск уже открытой такой же формы. Поиск осуществляется по типу формы, значениям ключевых параметров формы, владельцу формы, пользовательскому ключу уникальности. Если в параметре <Уникальность> передано значение Истина, то поиск уже открытых форм не осуществляется.
Синтаксис
ПолучитьФорму(<ИмяФормы>, <Параметры>, <Владелец>, <Уникальность>, <Окно>, <НавигационнаяСсылка>)Полное описание, параметры и ограничения
Глобальный контекст.ПолучитьФорму (Global context.GetForm)
Глобальный контекст (Global context)
ПолучитьФорму (GetForm)
Доступен, начиная с версии 8.2.
Синтаксис:
ПолучитьФорму(<ИмяФормы>, <Параметры>, <Владелец>, <Уникальность>, <Окно>, <НавигационнаяСсылка>)
Параметры:
<ИмяФормы> (обязательный)
Тип: Строка.
Имя формы. Образуется как полный путь к объекту метаданных Форма (например, "Справочник.Контрагенты.Форма.ФормаОбъекта", "ОбщаяФорма.ФормаСохраненияФайла") или как полный путь к прикладному объекту, дополненный именем формы по умолчанию (например, "Справочник.Товары.ФормаВыбора").
Имена форм по умолчанию:
ФормаОбъекта (ObjectForm) - форма объекта по умолчанию;
ФормаГруппы (FolderForm) - форма группы по умолчанию;
ФормаЗаписи (RecordForm) - форма записи регистра по умолчанию;
ФормаСписка (ListForm) - форма списка по умолчанию;
ФормаВыбора (ChoiceForm) - форма выбора по умолчанию;
ФормаВыбораГруппы (FolderChoiceForm) - форма выбора группы по умолчанию;
ФормаКонстант (ConstantsForm) - форма констант по умолчанию для обычного режима, установленная как форма констант для конфигурации;
Форма (Form) - форма константы, отчета и обработки по умолчанию;
ОбщаяФорма (CommonForm) - общая форма;
ФормаНастроек (SettingsForm) - форма настроек отчета по умолчанию;
ФормаЗагрузки (LoadForm) - форма загрузки настроек;
ФормаСохранения (SaveForm) - форма сохранения настроек;
ФормаВарианта (VariantForm) - форма редактирования варианта отчета;
ФормаЗагрузкиПользовательскихНастроекОтчетов (ReportUserSettingsLoadForm) - форма загрузки настроек отчета;
ФормаСохраненияПользовательскихНастроекОтчетов (ReportUserSettingsSaveForm) - форма сохранения настроек отчета;
ФормаЗагрузкиВариантовОтчетов (ReportVariantsLoadForm) - форма загрузки варианта отчета;
ФормаСохраненияВариантовОтчетов (ReportVariantsSaveForm) - форма сохранения варианта отчета;
ФормаЗагрузкиНастроекДанныхФорм (FormDataSettingsLoadForm) - форма загрузки настроек данных форм;
ФормаСохраненияНастроекДанныхФорм (FormDataSettingsSaveForm) - форма сохранения настроек данных форм;
ФормаПоиска (SearchForm) - форма полнотекстового поиска в данных;
ФормаИсторииИзмененийИсторииДанных (DataHistoryChangeHistoryForm) - форма истории изменений, отображает список версий данных, параметры см. Системная форма истории изменений истории данных;
ФормаДанныхВерсииИсторииДанных (DataHistoryVersionDataForm) - форма данных версии, отображающая отчет "Данные версии", параметры см. Системная форма данных версии истории данных;
ФормаРазличийВерсийИсторииДанных (DataHistoryVersionDifferencesForm) - форма различий версий истории данных, отображающая отчет "Различия версий", параметры см. Системная форма различий версий истории данных.
Например, для получения общей формы "ОбщиеНастройки" следует в модуле написать код:
Форма = ПолучитьФорму("ОбщаяФорма.ОбщиеНастройки");
Для внешних отчетов и обработок имя формы задается следующим образом:
ВнешнийОтчет.<имя отчета>.Форма.<имя формы>;
ВнешнийОтчет.<имя отчета>.<имя стандартной формы>;
ВнешняяОбработка.<имя обработки>.Форма.<имя формы>;
ВнешняяОбработка.<имя обработки>.<имя стандартной формы>.
При этом внешний отчет или обработка должны быть предварительно зарегистрированы в системе.
<Параметры> (необязательный)
Тип: Структура.
Параметры формы. Ключ структуры - имя параметра, а значение - значение параметра формы. Имя элемента должно совпадать с именем параметра структуры.
П = Новый Структура("Ключ", Поставщик);
Форма = ПолучитьФорму("Справочник.Контрагенты.ФормаОбъекта", П);
Форма.Открыть();
<Владелец> (необязательный)
Владелец формы - форма или элемент управления другой формы.
<Уникальность> (необязательный)
Тип: Произвольный.
В данном параметре может быть задан некоторый ключ, значение которого будет использоваться для поиска уже открытых форм. Если будет найдена форма с таким же ключом уникальности, вместо открытия новой формы будет активизирована найденная форма.
Ложь - искать форму с ключом уникальности по умолчанию, Истина - не искать форму вообще, любое другое значение устанавливает ключ уникальности, по которому будет произведен поиск.
Значение по умолчанию: Ложь.
<Окно> (необязательный)
Тип: ОкноКлиентскогоПриложения.
Окно приложения, в котором будет открыта форма.
Применимо только для формы клиентского приложения. Окном может быть только основное окно приложения или вспомогательное окно формы.
<НавигационнаяСсылка> (необязательный)
Тип: Строка, Неопределено.
Если содержит значение, отличное от Неопределено, то это значение присваивается свойству НавигационнаяСсылка формы, полученной в результате вызова данного метода, и свойство АвтоНавигационнаяСсылка этой формы устанавливается в Ложь.
Значение по умолчанию: Неопределено.
Возвращаемое значение:
Тип: Форма, ФормаКлиентскогоПриложения, Неопределено.
Неопределено - если в обработчике ПриСозданииНаСервере установлен признак отказа от создания формы.
Описание:
Получает форму или форму клиентского приложения. Перед получением осуществляется поиск уже открытой такой же формы.
Поиск осуществляется по типу формы, значениям ключевых параметров формы, владельцу формы, пользовательскому ключу уникальности.
Если в параметре <Уникальность> передано значение Истина, то поиск уже открытых форм не осуществляется.
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение (клиент).
Вызов метода выполняет обращение к серверу.
Примечание:
В тонком и веб-клиенте получает только форму клиентского приложения.
Обычные формы внешних обработок не поддерживаются.
Если при получении обычной формы в параметре <ИмяФормы> указано не стандартное имя формы, передаваемые параметры не обрабатываются.
См. также:
Глобальный контекст, метод ОткрытьФорму
Глобальный контекст, метод ОткрытьФормуМодально
Глобальный контекст, метод ПолучитьОбщуюФорму
Использование в версии:
Доступен, начиная с версии 8.2.
Описание изменено в версии 8.3.21.
Методическая информация
Практические примеры
Своя управляемая форма документа: запись, реальные движения, перечитывание и безопасный явный выбор
Новичок вручную готовит отдельную пустую CF, один собственный документ и регистр. На настоящем Объект управляемой формы проверяет время09:30→00:00, native форму Записать(Структура), перепроведение2/200→3/300 без дублей, Прочитать0 и явную передачу своей ссылки в форму-владелец. Это полный учебный процесс, а не пример с неизвестным исходным объектом.
Где и как запускать
1С8.5.1.1343 Windows, тонкий клиент, управляемое приложение, Такси; новая собственная файловая ИБ. MAIN — модуль настоящей managed ФормаДокумента собственного Документ.Уч85Заявка. Серверные и клиентские директивы обязательны. Native extension catalog1649, не ordinary Форма/catalog56. Здесь подготовлены только исходники и статические проверки; 1С/ИБ/движения/UI/сеть не запускались.
Подготовка
Работайте только в собственной Windows VM/учебной среде, не в УТ/КА/УНФ/БП, не в копии рабочей базы с чужими данными. Самостоятельно вручную создайте новую пустую файловую ИБ в C:\1c-labs\OwnManagedDoc85_b369c9c1-6d85-489d-a571-e23297a90d44\IB. Этот урок не создаёт каталоги/ИБ и ничего не скачивает.
Создайте новую CF Уч85УправляемыйДокумент, основной режим запуска Управляемое приложение, интерфейс Такси, платформу8.5.1.1343. Не переносите код в ordinary форму; native Расширение документа здесь означает Расширение формы клиентского приложения для документа.
В этой новой CF вручную создайте роль Уч85Стенд: право Администрирование нужно native ПолучитьПользователей0, чтение/добавление/изменение/проведение только своего Уч85Заявка и чтение/запись Уч85Итоги нужны процессу. Подготовьте единственного собственного пользователя ИБ Уч85Док_b369c9c1 с этой ролью только изолированного стенда, не выдавайте её в рабочих базах. Серверный код получает настоящего аутентифицированного пользователя и массив всех пользователей ИБ, проверяет ровно одного, одинаковые имя и UUID; этот фактический UUID далее сохраняется в своих данных и сверяется перед каждой записью. Вручную подставлять UUID в код не нужно. Не меняйте scope guards для обхода отказа.
UUID b369c9c1-6d85-489d-a571-e23297a90d44 — только метка стенда/пути. Новый UUID сценария создаёт native Новый УникальныйИдентификатор в собственной форме запуска. Действительный UUID пользователя получают из native ТекущийПользователь. Реальный UUID самой ИБ код не измеряет.
Сопоставьте native СтрокаСоединенияИнформационнойБазы() с точным File="C:\1c-labs\OwnManagedDoc85_b369c9c1-6d85-489d-a571-e23297a90d44\IB";. Если реальная строка иная, остановитесь и разберите адрес; не разрешайте Srvr/Ref/production адреса, не заменяйте guard на поиск подстроки.
В CF не должно быть справочников, иных документов, иных регистров, расширений, обменов, фоновых/регламентных заданий, разделителей и данных. Используйте только одну учебную сессию. Guards — ограничения собственного примера, не многопользовательская блокировка и не абсолютная защита от произвольного кода.
В Конфигураторе создайте Документы → Уч85Заявка. Проведение Разрешить, оперативное проведение Запретить, запись движений при проведении Записывать выбранные, удаление движений Автоматически. Номер строковый с автонумерацией; Дата включает дату и время. Оставьте штатные Ссылка/Проведен/ПометкаУдаления, не подменяйте Проведен вручную.
Реквизиты документа: Метка85, Пользователь85, Сценарий85 — Строка36; Количество — Число3,0 неотрицательное; Сумма — Число15,2 неотрицательное. Табличных частей и других реквизитов нет. Для пользовательского UUID подходит именно строка36, не значение из произвольного справочника.
Создайте РегистрНакопления Уч85Итоги, вид Остатки. Измерения Метка85, Пользователь85, Сценарий85 — Строка36; ресурсы Количество Число3,0 и Сумма Число15,2. Единственный регистратор — Документ.Уч85Заявка. На вкладке Движения документа включите ровно этот регистр. Проверяется физическая таблица движений, не виртуальный остаток с неизвестным периодом.
В Документ.Уч85Заявка → Модуль объекта вставьте полностью OBJECT. Native ПередЗаписью(Отказ,РежимЗаписи,РежимПроведения) имеет3 параметра; ОбработкаПроведения(Отказ,РежимПроведения)2. Эти события вызывает сама платформа при записи; вручную их никогда не вызывайте. Amount считается до записи объекта, движения формируются внутри штатной транзакции проведения.
Создайте Общий модуль Уч85ДокСтенд: Сервер=True, Вызов сервера=True, Клиент управляемого приложения=False, Глобальный=False, Привилегированный=False, Повторное использование возвращаемых значений Не использовать. Вставьте полностью SERVER. Модуль не создаёт/записывает/удаляет объекты: он проверяет адрес, пользователя, metadata и собственный readback.
Мастером Документ.Уч85Заявка → Формы создайте управляемую ФормаДокумента и назначьте её основной формой документа. Основной реквизит Объект должен иметь тип ДокументОбъект.Уч85Заявка. Именно эта metadata даёт native extension. Не создавайте расширение через Новый и не переименовывайте общую форму/переменную в документ ради совпадения имени.
В ФормаДокумента создайте параметр Сценарий85 Строка36. Native РежимВыбора и ПараметрыВыбора не дублируйте custom реквизитами: при открытии ПараметрыВыбора принимает Структура, одноимённое native свойство формы принимает ФиксированнаяСтруктура. Ключ в этом запуске отсутствует сознательно — native создаёт новый документ; чужой Ключ не передаётся.
Дополнительные реквизиты ФормаДокумента: Сценарий85 Строка36, СвояСсылка85 ДокументСсылка.Уч85Заявка, Этап85 Число1,0, НеизвестныйИсход85/ОтправкаНачата85/СогласиеНаСвоиДвеЗаписи85/СогласиеНаСбросСвоих99 Булево, Статус85 Строка500, Навигация85 Строка1000. Для этих дополнительных реквизитов СохраняемыеДанные=False: они только состояние формы, не изменяемые сохраняемые данные документа. Поля Объект.Дата/Количество/Сумма, статус и навигация — ТолькоПросмотр=True; согласия — обычные флажки. Этап/ссылку/UUID/flags пользователю не редактировать.
В модуль ФормаДокумента вставьте полностью MAIN/FORM. В свойствах формы события ПриСозданииНаСервере → ПриСозданииНаСервере2; ПередЗаписьюНаСервере → ПередЗаписьюНаСервере3. Клиентские document ПередЗаписью2 и ПослеЗаписи1 не назначайте: в них запрещены вызовы серверных методов формы. Не копируйте object ПередЗаписью3 в client событие с2 параметрами.
Создайте команды ФормаДокумента ПервоеПроведение85, Перепроведение85, ПеречитатьСвою85, ПодготовитьВыбор85, ПередатьСвоюСсылку85. Каждая Действие=одноимённая процедура(Команда), кнопка Тип=КнопкаФормы, ИмяКоманды=эта команда. Кнопки расположите в указанном порядке; стандартные Записать/Провести/ПровестиИЗакрыть/ОтменаПроведения не показывайте. Server event дополнительно запрещает стандартную запись вне подготовленной команды.
Создайте ОбщаяФорма.Уч85ДокЗапуск, управляемая общая форма без основного прикладного реквизита. Её реквизиты: Статус85 Строка500, ВыбраннаяЗаявка85 ДокументСсылка.Уч85Заявка, Навигация85 Строка1000. Все3 СохраняемыеДанные=False и только для просмотра. Добавьте команду СоздатьСвоюЗаявку85 с одноимённым действием(Команда) и кнопкой этой команды. Не добавляйте поле выбора другого документа.
В Уч85ДокЗапуск вставьте полностью LAUNCHER. События формы: ПриСозданииНаСервере2 и ОбработкаВыбора(ВыбранноеЗначение,ИсточникВыбора)2. Это событие владельца-формы, НЕ одноимённое событие поля ввода с другим набором параметров. ПодготовитьПрием85 — собственная экспортная процедура, не native callback.
В Модуль управляемого приложения вставьте полностью APPLICATION и назначьте native ПриНачалеРаботыСистемы без параметров. Вначале он проверяет пустоту собственного стенда и только затем открывает свою общую форму. Компиляцию CF и запуск нового собственного клиента выполните вручную; здесь это не выполнялось.
Перед первым запуском проверьте вручную: документная таблица пуста, регистр пуст, одна сессия, единственный нужный пользователь/адрес/вкладка Движения, текущая CF именно своя. Не переносите данные и не выполняйте автоматическое удаление/rollback/очистку после урока. После завершения сохранённый собственный документ остаётся в стенде; повторный старт намеренно остановится.
Native АвтоВремя только для записи: setter НеИспользовать сбрасывает ненулевое время нового документа в00:00; это НЕ сохранение09:30. Native ИспользоватьРежимПроведения и ПриЗаписиПерепроводить на клиенте только чтение, поэтому setters находятся только в серверном ПриСозданииНаСервере.
Native ПараметрыВыбора не документирует универсальную грамматику фильтров. Наши3 ключа — явная прикладная проверка равенства собственной метки, UUID и количества3; не используйте её для незнакомых форм/условий/провайдеров. ВыборДоступен приложение вычисляет после независимого readback.
Путь передачи выбора явный: реальная своя форма-владелец хранит actual child-instance, UUID и подготовленный ownDocRef; child выключает РежимВыбора перед native ОповеститьОВыборе(ownDocRef), которое уведомляет владельца и закрывает по ЗакрыватьПриВыборе=True. Это не утверждение, что default ChoiceMode всегда возвращает DocRef: default native закрытие передаёт произвольный основной реквизит.
Если CF не компилируется, raw native property/handler не совпадает или native Записать не даёт ожидаемого результата — остановите ручной протокол и покажите точную ошибку. Не заменяйте реальные данные ожидаемыми числами, не вызывайте Posting вручную и не ослабляйте guards. Статические тесты ниже не являются запуском1С.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Паспорт = Уч85ДокСтенд.ПроверитьПустойСтенд85();
ЗначениеСценария = Неопределено;
ЗначениеКритериев = Неопределено;
ЗначениеРежима = Неопределено;
Если Не Параметры.Свойство("Сценарий85", ЗначениеСценария)
Или Не Параметры.Свойство("ПараметрыВыбора", ЗначениеКритериев)
Или Не Параметры.Свойство("РежимВыбора", ЗначениеРежима) Тогда
Отказ = Истина;
ВызватьИсключение "Форму открывает только собственная учебная форма-владелец с полными параметрами.";
КонецЕсли;
Уч85ДокСтенд.ПроверитьСценарий85(ЗначениеСценария);
Если ТипЗнч(ЗначениеКритериев) <> Тип("Структура") Или ЗначениеРежима <> Ложь Тогда
Отказ = Истина;
ВызватьИсключение "Параметр ПараметрыВыбора — Структура; новая заявка ещё не открывается для выбора.";
КонецЕсли;
Сценарий85 = ЗначениеСценария;
ЭтаФорма.ПараметрыВыбора = Новый ФиксированнаяСтруктура(ЗначениеКритериев);
ПроверитьКритерии85();
Заявка = ЭтаФорма.РеквизитФормыВЗначение("Объект");
Если ТипЗнч(Заявка) <> Тип("ДокументОбъект.Уч85Заявка") Или Не Заявка.ЭтоНовый() Тогда
Отказ = Истина;
ВызватьИсключение "Ожидается новая настоящая форма собственного документа с основным реквизитом Объект.";
КонецЕсли;
Объект.Метка85 = Паспорт.Метка;
Объект.Пользователь85 = Паспорт.Пользователь;
Объект.Сценарий85 = Сценарий85;
Объект.Дата = Дата(2026, 1, 2, 9, 30, 0);
Объект.Количество = 2;
Объект.Сумма = 200;
ЭтаФорма.АвтоВремя = РежимАвтоВремя.НеИспользовать;
ЭтаФорма.ИспользоватьРежимПроведения = ИспользованиеРежимаПроведения.Неоперативный;
ЭтаФорма.ПриЗаписиПерепроводить = Истина;
ЭтаФорма.РежимВыбора = Ложь;
ЭтаФорма.ВыборДоступен = Ложь;
ЭтаФорма.ЗакрыватьПриВыборе = Истина;
Этап85 = 0;
НеизвестныйИсход85 = Ложь;
ОтправкаНачата85 = Ложь;
Статус85 = "Подготовлена своя новая заявка2/200; дата09:30 ещё не записана.";
КонецПроцедуры
&НаСервере
Процедура ПроверитьКритерии85()
Критерии = ЭтаФорма.ПараметрыВыбора;
Если ТипЗнч(Критерии) <> Тип("ФиксированнаяСтруктура") Или Критерии.Количество() <> 3
Или Критерии.Метка85 <> "b369c9c1-6d85-489d-a571-e23297a90d44"
Или Критерии.Сценарий85 <> Сценарий85 Или Критерии.Количество <> 3 Тогда
ВызватьИсключение "Изменены точные собственные критерии: метка, UUID сценария, количество3.";
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если Не НеизвестныйИсход85 Или (Этап85 <> 0 И Этап85 <> 1)
Или ОтправкаНачата85 Или ЭтаФорма.РежимВыбора Тогда
Отказ = Истина;
ВызватьИсключение "Запись разрешена только своей подготовленной командой; стандартное сохранение запрещено.";
КонецЕсли;
ПроверитьКритерии85();
Если ТекущийОбъект.Сценарий85 <> Сценарий85
Или ЭтаФорма.ИспользоватьРежимПроведения <> ИспользованиеРежимаПроведения.Неоперативный
Или Не ЭтаФорма.ПриЗаписиПерепроводить Тогда
Отказ = Истина;
ВызватьИсключение "Изменены UUID, собственные параметры проведения или перепроведения.";
КонецЕсли;
ПроверенныйРежим = Неопределено;
Если Не ПараметрыЗаписи.Свойство("РежимЗаписи", ПроверенныйРежим) Тогда
Отказ = Истина;
ВызватьИсключение "Нет native РежимЗаписи в структуре записи формы.";
КонецЕсли;
Если Этап85 = 0 Тогда
ПроверенноеПроведение = Неопределено;
Если ПроверенныйРежим <> РежимЗаписиДокумента.Проведение
Или Не ПараметрыЗаписи.Свойство("РежимПроведения", ПроверенноеПроведение)
Или ПроверенноеПроведение <> РежимПроведенияДокумента.Неоперативный
Или ТекущийОбъект.Количество <> 2 Тогда
Отказ = Истина;
ВызватьИсключение "Первое проведение требует оба native предопределённых параметра и количество2.";
КонецЕсли;
Иначе
Если ПроверенныйРежим <> РежимЗаписиДокумента.Запись
Или ТекущийОбъект.Ссылка <> СвояСсылка85 Или ТекущийОбъект.Количество <> 3 Тогда
Отказ = Истина;
ВызватьИсключение "Ожидается обычная запись именно своей сохранённой проведённой заявки2→3.";
КонецЕсли;
КонецЕсли;
Уч85ДокСтенд.ПроверитьПередЗаписью85(ТекущийОбъект);
КонецПроцедуры
&НаКлиенте
Процедура ПервоеПроведение85(Команда)
Если Не СогласиеНаСвоиДвеЗаписи85 Или Этап85 <> 0 Или НеизвестныйИсход85 Или ОтправкаНачата85 Тогда
ВызватьИсключение "Нужно явное согласие на две учебные записи в новой собственной базе; повтор запрещён.";
КонецЕсли;
Если Объект.Количество <> 2 Или Объект.Сумма <> 200
Или Объект.Дата <> Дата(2026, 1, 2, 9, 30, 0)
Или ЭтаФорма.ИспользоватьРежимПроведения <> ИспользованиеРежимаПроведения.Неоперативный
Или Не ЭтаФорма.ПриЗаписиПерепроводить Тогда
ВызватьИсключение "Начальные собственные данные или read-only клиентские свойства изменены.";
КонецЕсли;
ПараметрыЗаписи = Новый Структура("РежимЗаписи,РежимПроведения", РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
НеизвестныйИсход85 = Истина;
Если Не ЭтаФорма.Записать(ПараметрыЗаписи) Тогда
ВызватьИсключение "Форма вернула Ложь. Исход отдельно проверяет человек; автоматического повтора нет.";
КонецЕсли;
Паспорт = ПодтвердитьСвоюЗапись85(2, 200);
СвояСсылка85 = Паспорт.Ссылка;
Этап85 = 1;
НеизвестныйИсход85 = Ложь;
ЭтаФорма.ВыборДоступен = Ложь;
Статус85 = "Readback: свой документ2/200, дата00:00, ровно одно реальное движение2/200.";
КонецПроцедуры
&НаКлиенте
Процедура Перепроведение85(Команда)
Если Этап85 <> 1 Или НеизвестныйИсход85 Или ОтправкаНачата85
Или Объект.Ссылка <> СвояСсылка85 Или Объект.Количество <> 2 Или Объект.Сумма <> 200 Тогда
ВызватьИсключение "Нет точного собственного состояния после первого успешного проведения.";
КонецЕсли;
ПодтвердитьСвоюЗапись85(2, 200);
Объект.Количество = 3;
ПараметрыЗаписи = Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Запись);
НеизвестныйИсход85 = Истина;
Если Не ЭтаФорма.Записать(ПараметрыЗаписи) Тогда
ВызватьИсключение "Обычная запись формы вернула Ложь; нельзя слепо переписывать или повторять.";
КонецЕсли;
ПодтвердитьСвоюЗапись85(3, 300);
Этап85 = 2;
НеизвестныйИсход85 = Ложь;
ЭтаФорма.ВыборДоступен = Истина;
Статус85 = "Readback3/300: перепроведение заменило собственное движение, не добавило второе5/500.";
КонецПроцедуры
&НаСервере
Функция ПодтвердитьСвоюЗапись85(Количество, Сумма)
ПроверитьКритерии85();
Если Объект.Сценарий85 <> Сценарий85 Или (Этап85 > 0 И Объект.Ссылка <> СвояСсылка85) Тогда
ВызватьИсключение "Ссылка или UUID данных формы изменены.";
КонецЕсли;
Паспорт = Уч85ДокСтенд.ПаспортСвоейЗаявки85(Объект.Ссылка, Сценарий85, Количество, Сумма);
Если Объект.Количество <> Паспорт.Количество Или Объект.Сумма <> Паспорт.Сумма
Или Объект.Дата <> Паспорт.Дата Или Не Объект.Проведен Тогда
ВызватьИсключение "Данные реальной управляемой формы не совпали с независимым чтением базы.";
КонецЕсли;
Возврат Паспорт;
КонецФункции
&НаКлиенте
Процедура ПеречитатьСвою85(Команда)
Если Этап85 <> 2 Или НеизвестныйИсход85 Или ОтправкаНачата85 Или Не СогласиеНаСбросСвоих99 Тогда
ВызватьИсключение "Нужно явное согласие потерять только намеренно введённые собственные99, без записи.";
КонецЕсли;
ПодтвердитьСвоюЗапись85(3, 300);
Объект.Количество = 99;
Если Объект.Ссылка <> СвояСсылка85 Или Объект.Количество <> 99 Тогда
ВызватьИсключение "Изменено не собственное ожидаемое поле.";
КонецЕсли;
НеизвестныйИсход85 = Истина;
ЭтаФорма.Прочитать();
ПодтвердитьСвоюЗапись85(3, 300);
Этап85 = 3;
НеизвестныйИсход85 = Ложь;
Статус85 = "Native Прочитать() восстановило своё сохранённое3/300; движения остались ровно одни.";
КонецПроцедуры
&НаКлиенте
Процедура ПодготовитьВыбор85(Команда)
Если Этап85 <> 3 Или НеизвестныйИсход85 Или ОтправкаНачата85 Тогда
ВызватьИсключение "Сначала нужны обе записи и явное native перечитывание своего документа.";
КонецЕсли;
Паспорт = ПодтвердитьСвоюЗапись85(3, 300);
Навигация85 = ЭтаФорма.ПолучитьНавигационнуюСсылкуОбъекта();
Если Навигация85 <> Паспорт.Навигация Или ПустаяСтрока(Навигация85)
Или Объект.Ссылка <> СвояСсылка85 Тогда
ВызватьИсключение "Внутренняя навигационная строка не совпала с именно своей сохранённой ссылкой.";
КонецЕсли;
ЭтаФорма.РежимВыбора = Истина;
ЭтаФорма.ВыборДоступен = Объект.Метка85 = ЭтаФорма.ПараметрыВыбора.Метка85
И Объект.Сценарий85 = ЭтаФорма.ПараметрыВыбора.Сценарий85
И Объект.Количество = ЭтаФорма.ПараметрыВыбора.Количество;
Если Не ЭтаФорма.РежимВыбора Или Не ЭтаФорма.ВыборДоступен Тогда
ВызватьИсключение "Собственные критерии выбора не выполнены.";
КонецЕсли;
Этап85 = 4;
Статус85 = "Готов явный выбор своей сохранённой заявки3/300. Ссылка показана текстом, не открывается.";
КонецПроцедуры
&НаКлиенте
Процедура ПередатьСвоюСсылку85(Команда)
Если Этап85 <> 4 Или НеизвестныйИсход85 Или ОтправкаНачата85
Или Не ЭтаФорма.РежимВыбора Или Не ЭтаФорма.ВыборДоступен
Или Не ЭтаФорма.ЗакрыватьПриВыборе Или Объект.Ссылка <> СвояСсылка85 Тогда
ВызватьИсключение "Выбор разрешён один раз, только из своей подготовленной формы.";
КонецЕсли;
Паспорт = ПодтвердитьСвоюЗапись85(3, 300);
Если Навигация85 <> Паспорт.Навигация
Или ЭтаФорма.ПолучитьНавигационнуюСсылкуОбъекта() <> Навигация85 Тогда
ВызватьИсключение "Навигационная строка собственного документа изменена.";
КонецЕсли;
ОтправкаНачата85 = Истина;
ЭтаФорма.ВладелецФормы.ПодготовитьПрием85(ЭтаФорма, СвояСсылка85, Сценарий85, Навигация85);
ЭтаФорма.РежимВыбора = Ложь;
Если ЭтаФорма.РежимВыбора Или Не ЭтаФорма.ЗакрыватьПриВыборе Тогда
ВызватьИсключение "Сбой подготовки явной передачи без стандартного ChoiceMode при закрытии.";
КонецЕсли;
ЭтаФорма.ОповеститьОВыборе(СвояСсылка85);
КонецПроцедурыSERVER — полный серверный паспорт собственного стенда и независимые запросы
Своя новая CF → Общие → Общие модули → Уч85ДокСтенд → Модуль.
Общий модуль Сервер=True/ВызовСервера=True, не глобальный/не привилегированный. Проверка exact ownFileIB/currentIBUserUUID/metadata/record count и чтение только своей ссылки/UUID; native DB calls только в authoredsource.
Функция ПаспортСтенда85() Экспорт
ОжидаемоеСоединение = "File=""C:\1c-labs\OwnManagedDoc85_b369c9c1-6d85-489d-a571-e23297a90d44\IB"";";
Если СтрокаСоединенияИнформационнойБазы() <> ОжидаемоеСоединение Тогда
ВызватьИсключение "Разрешена только новая собственная файловая учебная база с точным путём.";
КонецЕсли;
Если Метаданные.Документы.Количество() <> 1
Или Метаданные.Документы.Найти("Уч85Заявка") = Неопределено
Или Метаданные.РегистрыНакопления.Количество() <> 1
Или Метаданные.РегистрыНакопления.Найти("Уч85Итоги") = Неопределено
Или Метаданные.Справочники.Количество() <> 0
Или Метаданные.РегистрыСведений.Количество() <> 0
Или Метаданные.РегистрыБухгалтерии.Количество() <> 0
Или Метаданные.РегистрыРасчета.Количество() <> 0 Тогда
ВызватьИсключение "Стенд должен содержать только свой документ и один свой регистр накопления.";
КонецЕсли;
МДДокумента = Метаданные.Документы.Уч85Заявка;
МДРегистра = Метаданные.РегистрыНакопления.Уч85Итоги;
Если МДДокумента.Проведение <> Метаданные.СвойстваОбъектов.Проведение.Разрешить
Или МДДокумента.ОперативноеПроведение <> Метаданные.СвойстваОбъектов.ОперативноеПроведение.Запретить
Или МДДокумента.УдалениеДвижений <> Метаданные.СвойстваОбъектов.УдалениеДвижений.УдалятьАвтоматически
Или МДДокумента.ЗаписьДвиженийПриПроведении <> Метаданные.СвойстваОбъектов.ЗаписьДвиженийПриПроведении.ЗаписыватьВыбранные
Или МДРегистра.ВидРегистра <> Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки
Или МДДокумента.Движения.Количество() <> 1 Или Не МДДокумента.Движения.Содержит(МДРегистра) Тогда
ВызватьИсключение "Реальные read-only metadata проведения, записи, удаления и включённого своего регистра изменены.";
КонецЕсли;
Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Если Пользователь = Неопределено Или Пользователи.Количество() <> 1 Тогда
ВызватьИсключение "Нужен единственный реальный пользователь новой своей учебной базы.";
КонецЕсли;
Если Пользователь.Имя <> "Уч85Док_b369c9c1"
Или Пользователи[0].Имя <> Пользователь.Имя
Или Пользователи[0].УникальныйИдентификатор <> Пользователь.УникальныйИдентификатор Тогда
ВызватьИсключение "UUID аутентифицированного пользователя не совпал с единственным настоящим пользователем ИБ, не UUID пути.";
КонецЕсли;
Возврат Новый Структура("Метка,Пользователь", "b369c9c1-6d85-489d-a571-e23297a90d44", Строка(Пользователь.УникальныйИдентификатор));
КонецФункции
Функция КоличествоЗаписей85(ИмяТаблицы)
Если ИмяТаблицы <> "Документ.Уч85Заявка" И ИмяТаблицы <> "РегистрНакопления.Уч85Итоги" Тогда
ВызватьИсключение "Запрещена произвольная таблица запроса.";
КонецЕсли;
Запрос = Новый Запрос("ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Число ИЗ " + ИмяТаблицы);
Выборка = Запрос.Выполнить().Выбрать();
Если Не Выборка.Следующий() Тогда
ВызватьИсключение "Нет строки результата подсчёта.";
КонецЕсли;
Возврат Выборка.Число;
КонецФункции
Процедура ПроверитьСценарий85(Сценарий) Экспорт
Если ТипЗнч(Сценарий) <> Тип("Строка") Или СтрДлина(Сценарий) <> 36 Тогда
ВызватьИсключение "Сценарий должен быть строкой настоящего нового UUID.";
КонецЕсли;
Идентификатор = Новый УникальныйИдентификатор(Сценарий);
Если НРег(Строка(Идентификатор)) <> НРег(Сценарий) Тогда
ВызватьИсключение "Недопустимый UUID сценария.";
КонецЕсли;
КонецПроцедуры
Функция ПроверитьПустойСтенд85() Экспорт
Паспорт = ПаспортСтенда85();
Если КоличествоЗаписей85("Документ.Уч85Заявка") <> 0
Или КоличествоЗаписей85("РегистрНакопления.Уч85Итоги") <> 0 Тогда
ВызватьИсключение "Стенд не пуст. Повторное создание, очистка и перезапись не выполняются.";
КонецЕсли;
Возврат Паспорт;
КонецФункции
Процедура ПроверитьСвойОбъект85(Заявка) Экспорт
Паспорт = ПаспортСтенда85();
Если ТипЗнч(Заявка) <> Тип("ДокументОбъект.Уч85Заявка") Тогда
ВызватьИсключение "Ожидается реальный объект собственного документа, а не данные формы или чужой объект.";
КонецЕсли;
ПроверитьСценарий85(Заявка.Сценарий85);
Если Заявка.Метка85 <> Паспорт.Метка Или Заявка.Пользователь85 <> Паспорт.Пользователь
Или Заявка.ПометкаУдаления Или (Заявка.Количество <> 2 И Заявка.Количество <> 3) Тогда
ВызватьИсключение "Не совпали собственные данные, пользователь или допустимое количество.";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьПередЗаписью85(Заявка, ПроверятьДвижения = Истина) Экспорт
ПроверитьСвойОбъект85(Заявка);
Если Заявка.Сумма <> 200 Тогда
ВызватьИсключение "Изменена исходная собственная сумма200; до записи её не исправляем молча.";
КонецЕсли;
Если Заявка.ЭтоНовый() Тогда
ПроверитьПустойСтенд85();
Если Заявка.Количество <> 2 Или Заявка.Проведен
Или (Заявка.Дата <> Дата(2026, 1, 2, 9, 30, 0) И Заявка.Дата <> Дата(2026, 1, 2)) Тогда
ВызватьИсключение "Новый документ изменён относительно собственной подготовки.";
КонецЕсли;
Иначе
Если ПроверятьДвижения Тогда
ПаспортСвоейЗаявки85(Заявка.Ссылка, Заявка.Сценарий85, 2, 200);
Иначе
ПаспортДокумента85(Заявка.Ссылка, Заявка.Сценарий85, 2, 200);
КонецЕсли;
Если Заявка.Количество <> 3 Или Заявка.Дата <> Дата(2026, 1, 2)
Или Не Заявка.Проведен Тогда
ВызватьИсключение "Разрешено только одно изменение собственной проведённой заявки 2→3.";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПаспортДокумента85(Ссылка, Сценарий, Количество, Сумма)
Паспорт = ПаспортСтенда85();
ПроверитьСценарий85(Сценарий);
Если ТипЗнч(Ссылка) <> Тип("ДокументСсылка.Уч85Заявка") Или Ссылка.Пустая()
Или (Количество <> 2 И Количество <> 3) Или Сумма <> Количество * 100 Тогда
ВызватьИсключение "Недопустимый собственный ожидаемый паспорт.";
КонецЕсли;
Если КоличествоЗаписей85("Документ.Уч85Заявка") <> 1 Тогда
ВызватьИсключение "В стенде должна быть ровно одна собственная заявка.";
КонецЕсли;
Запрос = Новый Запрос(
"ВЫБРАТЬ З.Ссылка, З.Дата, З.Количество, З.Сумма, З.Проведен, З.ПометкаУдаления,
| З.Метка85, З.Пользователь85, З.Сценарий85
|ИЗ Документ.Уч85Заявка КАК З
|ГДЕ З.Ссылка = &Ссылка И З.Метка85 = &Метка
| И З.Пользователь85 = &Пользователь И З.Сценарий85 = &Сценарий");
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("Метка", Паспорт.Метка);
Запрос.УстановитьПараметр("Пользователь", Паспорт.Пользователь);
Запрос.УстановитьПараметр("Сценарий", Сценарий);
Выборка = Запрос.Выполнить().Выбрать();
Если Не Выборка.Следующий() Тогда
ВызватьИсключение "Своя сохранённая заявка с точными UUID не найдена.";
КонецЕсли;
Если Выборка.Дата <> Дата(2026, 1, 2) Или Выборка.Количество <> Количество
Или Выборка.Сумма <> Сумма Или Не Выборка.Проведен Или Выборка.ПометкаУдаления Тогда
ВызватьИсключение "Независимый readback документа не совпал: время00:00, количество, сумма, проведение.";
КонецЕсли;
Если Выборка.Следующий() Тогда
ВызватьИсключение "Неожиданный дубль документа.";
КонецЕсли;
Возврат Новый Структура("Ссылка,Сценарий,Количество,Сумма,Дата,Навигация", Ссылка, Сценарий, Количество, Сумма, Дата(2026, 1, 2), ПолучитьНавигационнуюСсылку(Ссылка));
КонецФункции
Функция ПаспортСвоейЗаявки85(Ссылка, Сценарий, Количество, Сумма) Экспорт
Документ = ПаспортДокумента85(Ссылка, Сценарий, Количество, Сумма);
Паспорт = ПаспортСтенда85();
Если КоличествоЗаписей85("РегистрНакопления.Уч85Итоги") <> 1 Тогда
ВызватьИсключение "В стенде должно быть ровно одно движение, не дубли и не5/500.";
КонецЕсли;
Движения = Новый Запрос(
"ВЫБРАТЬ Д.Регистратор, Д.Период, Д.Активность, Д.ВидДвижения, Д.Количество, Д.Сумма
|ИЗ РегистрНакопления.Уч85Итоги КАК Д
|ГДЕ Д.Регистратор = &Ссылка И Д.Метка85 = &Метка
| И Д.Пользователь85 = &Пользователь И Д.Сценарий85 = &Сценарий");
Движения.УстановитьПараметр("Ссылка", Ссылка);
Движения.УстановитьПараметр("Метка", Паспорт.Метка);
Движения.УстановитьПараметр("Пользователь", Паспорт.Пользователь);
Движения.УстановитьПараметр("Сценарий", Сценарий);
СтрокаДвижения = Движения.Выполнить().Выбрать();
Если Не СтрокаДвижения.Следующий() Тогда
ВызватьИсключение "Нет собственного движения native ОбработкаПроведения.";
КонецЕсли;
Если СтрокаДвижения.Регистратор <> Ссылка Или СтрокаДвижения.Период <> Дата(2026, 1, 2)
Или Не СтрокаДвижения.Активность Или СтрокаДвижения.ВидДвижения <> ВидДвиженияНакопления.Приход
Или СтрокаДвижения.Количество <> Количество Или СтрокаДвижения.Сумма <> Сумма Тогда
ВызватьИсключение "Реальное движение не заменено на ожидаемые собственные 2/200 или3/300.";
КонецЕсли;
Если СтрокаДвижения.Следующий() Тогда
ВызватьИсключение "Движение продублировано: вместо замены получено накопление.";
КонецЕсли;
Возврат Документ;
КонецФункцииOBJECT — полный модуль собственного документа и реальные движения
Своя новая CF → Документы → Уч85Заявка → Модуль объекта.
Модуль объекта собственный Документ.Уч85Заявка; native ПередЗаписью3/ОбработкаПроведения2 на сервере в транзакции. Пишет только собственные движения включённого Уч85Итоги; здесь не исполнялся.
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Уч85ДокСтенд.ПроверитьПередЗаписью85(ЭтотОбъект, Ложь);
Если РежимЗаписи <> РежимЗаписиДокумента.Проведение
Или РежимПроведения <> РежимПроведенияДокумента.Неоперативный Тогда
Отказ = Истина;
ВызватьИсключение "Учебная заявка записывается только с реальным неоперативным проведением.";
КонецЕсли;
Сумма = Количество * 100;
КонецПроцедуры
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Уч85ДокСтенд.ПроверитьСвойОбъект85(ЭтотОбъект);
Если РежимПроведения <> РежимПроведенияДокумента.Неоперативный
Или Дата <> Дата(2026, 1, 2) Или Сумма <> Количество * 100
Или Движения.Уч85Итоги.Количество() <> 0 Тогда
Отказ = Истина;
ВызватьИсключение "Неверный режим, дата, сумма или непустой подготовленный набор своих движений.";
КонецЕсли;
Движения.Уч85Итоги.Записывать = Истина;
Движение = Движения.Уч85Итоги.Добавить();
Движение.Период = Дата;
Движение.Активность = Истина;
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Движение.Метка85 = Метка85;
Движение.Пользователь85 = Пользователь85;
Движение.Сценарий85 = Сценарий85;
Движение.Количество = Количество;
Движение.Сумма = Сумма;
КонецПроцедурыLAUNCHER — полная собственная managed форма-владелец
Своя новая CF → Общие → Общие формы → Уч85ДокЗапуск → Модуль.
Общая managed форма, own GetForm factory/actual child-instance и native generic owner ОбработкаВыбора2. Не input-field handler; server OnCreate2 и client one-shot reception.
Перем СвояФорма85;
Перем ЗапускНачат85;
Перем ПриемПодготовлен85;
Перем ПриемНачат85;
Перем ОжидаемаяСсылка85;
Перем ОжидаемыйСценарий85;
Перем ОжидаемаяНавигация85;
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Уч85ДокСтенд.ПроверитьПустойСтенд85();
Статус85 = "Своя новая пустая база подтверждена; создание и две записи требуют согласия в форме документа.";
КонецПроцедуры
&НаКлиенте
Процедура СоздатьСвоюЗаявку85(Команда)
Если ЗапускНачат85 = Истина Тогда
ВызватьИсключение "Урок запускается один раз. Другой объект не создаём и не ищем чужие формы.";
КонецЕсли;
Уч85ДокСтенд.ПроверитьПустойСтенд85();
ЗапускНачат85 = Истина;
ПриемПодготовлен85 = Ложь;
ПриемНачат85 = Ложь;
Идентификатор = Новый УникальныйИдентификатор;
ОжидаемыйСценарий85 = Строка(Идентификатор);
Критерии = Новый Структура("Метка85,Сценарий85,Количество", "b369c9c1-6d85-489d-a571-e23297a90d44", ОжидаемыйСценарий85, 3);
ПараметрыФормы = Новый Структура("Сценарий85,ПараметрыВыбора,РежимВыбора", ОжидаемыйСценарий85, Критерии, Ложь);
СвояФорма85 = ПолучитьФорму("Документ.Уч85Заявка.Форма.ФормаДокумента", ПараметрыФормы, ЭтаФорма, Истина);
Если СвояФорма85 = Неопределено Или ТипЗнч(СвояФорма85) <> Тип("ФормаКлиентскогоПриложения")
Или СвояФорма85.ВладелецФормы <> ЭтаФорма Тогда
ВызватьИсключение "Не получена собственная новая managed форма документа с этим реальным владельцем.";
КонецЕсли;
СвояФорма85.Открыть();
КонецПроцедуры
&НаКлиенте
Процедура ПодготовитьПрием85(Источник, Ссылка, Сценарий, Навигация) Экспорт
Если СвояФорма85 = Неопределено Или Источник <> СвояФорма85
Или ПриемПодготовлен85 = Истина Или ПриемНачат85 = Истина Или Сценарий <> ОжидаемыйСценарий85
Или ТипЗнч(Ссылка) <> Тип("ДокументСсылка.Уч85Заявка") Тогда
ВызватьИсключение "Подготовка приёма допустима только от единственного своего child-instance и UUID.";
КонецЕсли;
Паспорт = Уч85ДокСтенд.ПаспортСвоейЗаявки85(Ссылка, Сценарий, 3, 300);
Если Навигация <> Паспорт.Навигация Тогда
ВызватьИсключение "Передана не точная собственная внутренняя навигационная строка.";
КонецЕсли;
ОжидаемаяСсылка85 = Паспорт.Ссылка;
ОжидаемаяНавигация85 = Паспорт.Навигация;
ПриемПодготовлен85 = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ПриемПодготовлен85 <> Истина Или ПриемНачат85 = Истина Или ИсточникВыбора <> СвояФорма85
Или ТипЗнч(ВыбранноеЗначение) <> Тип("ДокументСсылка.Уч85Заявка")
Или ВыбранноеЗначение <> ОжидаемаяСсылка85 Тогда
ВызватьИсключение "Чужой, повторный или произвольный default payload не принимается. Запись не выполняется.";
КонецЕсли;
ПриемНачат85 = Истина;
Паспорт = Уч85ДокСтенд.ПаспортСвоейЗаявки85(ВыбранноеЗначение, ОжидаемыйСценарий85, 3, 300);
Если Паспорт.Навигация <> ОжидаемаяНавигация85 Тогда
ВызватьИсключение "После native уведомления независимый паспорт собственной ссылки изменился.";
КонецЕсли;
ВыбраннаяЗаявка85 = Паспорт.Ссылка;
Навигация85 = Паспорт.Навигация;
Статус85 = "Native ОбработкаВыбора2 приняла свою ссылку3/300 один раз; новых записей и открытия URL нет.";
КонецПроцедурыAPPLICATION — полный старт своего управляемого приложения
Своя новая CF → Открыть модуль управляемого приложения → ПриНачалеРаботыСистемы.
Тонкий клиент собственной новой CF, native ПриНачалеРаботыСистемы0; read-only server guard перед открытием собственного launcher. Native global owner не объявляется фиктивным типом.
Процедура ПриНачалеРаботыСистемы()
Уч85ДокСтенд.ПроверитьПустойСтенд85();
ОткрытьФорму("ОбщаяФорма.Уч85ДокЗапуск");
КонецПроцедурыРазбор по шагам
В своей новой пустой ИБ запустите тонкий клиент под единственным подготовленным пользователем. Общая форма проверит address/user/metadata/нулевые counts. Нажмите СоздатьСвоюЗаявку85 один раз: native ПолучитьФорму с exact metadata name, owner=ЭтаФорма, Уникальность=Истина создаст новую настоящую managed форму документа без Ключ.
Проверьте в форме свои начальные2/200 и дату02.01.2026 09:30. ВыборДоступен=False, поскольку требуемое приложением количество3 ещё не достигнуто. Отметьте СогласиеНаСвоиДвеЗаписи85: оно относится только к собственному одноразовому учебному процессу.
Нажмите ПервоеПроведение85. Перед native Form.Записать(Структура) устанавливается флаг неизвестного исхода; структура содержит оба predefined keys разных enum types. Server BeforeWrite3 и реальный object BeforeWrite3 запрещают чужое/неожиданное состояние; object Amount=2×100, native Posting2 формирует ровно одно incoming движение собственного регистра.
Независимый запрос в SERVER обязан прочитать реально сохранённый документ и одно движение2/200 с теми же recorder/marker/user/scenario, датой00:00, Проведен=True и Активность=True. Только после успешного readback сохраняется фактическая собственная ссылка и снимается unknown-outcome flag. Время09:30 не обещается сохранить.
Нажмите Перепроведение85. Перед изменением перепроверяется сохранённое2/200; только собственное поле количества меняется на3. Обычная запись формы передаёт РежимЗаписи=Запись, РежимПроведения не задаётся специально: свойства формы разрешают автоматическое неоперативное перепроведение. Native object event должен получить проведение, иначе урок честно откажет.
После второй native записи независимые реальные данные должны быть3/300, одна прежняя собственная ссылка, один документ и ОДНО движение3/300. Значения5/500 или два движения — ошибка замены/metadata. Старые движения удаляет native механизм только этого своего документа, не наш произвольный cleanup-код.
Отметьте СогласиеНаСбросСвоих99 и нажмите ПеречитатьСвою85. Команда проверяет собственное saved3/300, намеренно меняет только своё несохранённое количество на99 и вызывает native Прочитать() без аргументов. После actual readback форма опять3/300; никаких записей или повторного проведения на этом этапе нет.
Нажмите ПодготовитьВыбор85. ПолучитьНавигационнуюСсылкуОбъекта() вызывается без обоих optional внешних параметров, возвращает внутреннюю строку своей ссылки и сравнивается с server native ПолучитьНавигационнуюСсылку(ownRef). URL не открывается, внешнее хранилище ссылок не заполняется. РежимВыбора=True и собственные exact критерии дают ВыборДоступен=True.
Нажмите ПередатьСвоюСсылку85. Проверяются exact own state/3/300/link/child-owner и одноразовость, владелец вооружается своей проверенной ссылкой. РежимВыбора=False readback исключает default отправку при закрытии в режиме выбора; native ОповеститьОВыборе отправляет именно нашу сохранённую DocRef и закрывает по ЗакрыватьПриВыборе=True.
Native ОбработкаВыбора2 владельца сравнивает фактический ИсточникВыбора с сохранённым actual child-instance и exact ownDocRef/UUID. До приёма результата одноразовый флаг установлен; последующий независимый server readback должен подтвердить3/300/link. Только тогда поле ВыбраннаяЗаявка85 показывает свою ссылку. Чужие формы/массивы/неизвестные payload/повтор отклоняются без writes.
Сохраните ручной протокол успеха либо точного отказа, не перезапускайте запись автоматически. Документ/движение остаются в своей новой учебной базе; следующий запуск отказом сообщает непустоту вместо очистки. Здесь такого ручного протокола ещё нет: runtime0.
Как проверить результат
Статически: PRIMARY10 уникальны, main uses все native methods/properties, source metadata actual DocForm, raw native10+support/event/enum pages сверяются с установленным shcntx_ru.hbk8.5.1.1343; пять native checkers должны вернуть0 mismatches.
Вручную: неверный File/CF/userUUID/пользователь/непустая ИБ/другая ссылка/несоответствие marker/scenario/количества → отказ до записи. На стороне сервера параметры и независимые данные проверяются повторно; это не доказательство защиты от произвольного привилегированного кода.
Вручную: первая native запись даёт readback2/200, Date02.01.2026 00:00, PostedTrue, физическая таблица own register содержит ровно1 active incoming запись своего recorder/UUID. Нет записи счётчика после Posting и нет ручного присваивания Posted.
Вручную: обычная запись уже проведённой заявки с own RepostOnWriteTrue заменяет одну запись2/200 на одну3/300. Проверить не только сумму, но own registrar/dimensions/date/activity/type и глобальный count1 внутри доказанно своей пустой CF.
Вручную: после deliberate99 native read возвращает сохранённое3/300; количество записей/движений не меняется. Навигационная строка0args совпадает с серверной своей ссылкой, не открывается и не создаёт внешние параметры.
Вручную: native Notify с ChoiceModeFalse всё же вызывает реальную wired ОбработкаВыбора2 владельца и закрывает дочернюю форму по CloseOnChoiceTrue; сообщение выбрано один раз. Default ChoiceMode/mainattr type и exact-once callback здесь не измерены: обязательно подтвердить собственным ручным UI протоколом.
Статически/модель: отказ/исключение/partial неизвестность не снимают guard перед retry, неверный источник/payload/link отсекается, native события не вызываются руками, никакого actual1C/DB/UI/network/print/CF/files provisioning/backups не выполнено.
Ожидаемый результат
Ожидаемый ручной результат: один свой документ02.01.2026 00:00 с количеством3 и суммой300, одно своё активное приходное движение3/300, native перечитанная форма и полученная собственной формой-владельцем ссылка. Здесь существуют только authoredsource/static tests; этот результат в1С не исполнялся и не измерялся.
На что обратить внимание
Короткое имя Расширение документа в выгрузке не даёт право использовать ordinary документную форму. PRIMARY10 связаны с native catalog1649 managed document extension и actual metadata main Объект.
РежимАвтоВремя.НеИспользовать сбрасывает ненулевое время нового документа в00:00. АвтоВремя write-only нельзя читать для baseline/getter/assertion; проверяется реально сохранённая дата.
ИспользоватьРежимПроведения имеет enum ИспользованиеРежимаПроведения; РежимПроведения predefined parameter/event имеет другой enum РежимПроведенияДокумента. Нельзя подменять типы одинаково названным Неоперативный.
Form.Write принимает одну Структура и возвращает Булево, DocObject.Write принимает другие параметры и не возвращает этот native Bool. Успешный Bool без независимого saved readback ещё не доказывает нужный результат.
Native ПередЗаписьюНаСервере формы имеет3 параметра и исполняется вне транзакции; object ПередЗаписью тоже3, но другие параметры/контекст и выполняется внутри транзакции. Posting2 не заменяется ручным вызовом.
Сумма вычисляется в object ПередЗаписью до записи. Не полагайтесь на сохранение реквизитов, назначенных уже в Posting: факт проведения проверяется настоящим собственным движением, а не фиктивным persisted counter.
Вне транзакции server формы до второй записи проверяет полный старый паспорт2/200 с движением; inside object ПередЗаписью проверяется собственный старый документ без предположения, в какой момент native удалит прежние движения. После завершённой записи снова обязателен полный независимый паспорт с ровно одним новым движением.
Автоматическое удаление движений, Записывать выбранные и включённый own регистр — обязательная metadata. Непустой набор/два движения/5/500 не маскируются Clear/пересчётом ожидаемых данных.
Client setters UsePostingMode/RepostOnWrite недоступны: assignments находятся в серверном OnCreate. Document client BeforeWrite/AfterWrite имеют специальные запреты серверных вызовов; данный урок их вообще не использует.
ДанныеФормыСтруктура на клиенте — модель данных, не ДокументОбъект. Настоящий server объект получают native РеквизитФормыВЗначение("Объект") и проверяют concrete metadata type.
ПараметрыВыбора formparam — Структура; native property — ФиксированнаяСтруктура. Приложение явно проверяет свои3 равенства, а не придумывает универсальные правила/Отбор.*/операторы неизвестных форм.
Прочитать() может сбросить несохранённое. Урок делает это только с отдельным явным согласием после own-link/passport проверки и специально введёнными99; другие пользовательские изменения не discard автоматически.
GetObjectURL имеет два optional параметра: задавать нужно оба либо ни одного. Используем0, не создаём внешнее хранилище данных ссылок; сама URL строка не является доказательством доверия или права изменить объект.
Default ChoiceMode при закрытии передаёт значение основного реквизита, native generic ОбработкаВыбора2 допускает arbitrary/array. Наш явный Notify отправляет concrete ownDocRef и заранее выключает ChoiceMode; generic default payload всегдаDocRef не обещается.
Native Notify не требует ChoiceModeTrue по собственному контракту и закрывает по CloseOnChoice. РежимВыбораFalse перед Notify обоснован raw условием default отправки при закрытии; фактическое число событий/закрытие нужно подтвердить вручную, а owner one-shot отклоняет повтор.
Read-only поля формы не абсолютная защита, server guards не криптографическая авторизация/многопользовательская синхронизация, SafeMode на время object Posting/BeforeWrite нативно отключается. Только собственный известный исходник новой CF/VM, не production.
Если запись/перечитывание/уведомление завершились с исключением или неизвестным исходом, никакого retry/blindrestore/delete/перезаписи другого документа. Сначала человек независимо проверяет свою ИБ и фиксирует точную ошибку.
UUID пользователя ИБ — не UUID базы; UUID метки пути — тоже не native IBUUID. Сценарий отдельно создаёт настоящий fresh UUID; реальный UUID самой ИБ не измеряется.
Автоматически повторить урок в той же непустой ИБ нельзя. Код ничего не чистит и не делает резервных копий; ручная подготовка нового собственного стенда — отдельное действие пользователя.
Статические Python models/native checkers не являются BSL-компилятором и не доказали native form command→repost→notification в работающей1С. Runtime, записей, UI, сети и provisioning в этой работе0.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Перейти к своей карточке списка и передать активную ссылку наблюдателю
В собственном динамическом списке создаются две реальные учебные карточки. Переход устанавливает текущую строку, а оповещение активизации передаёт ссылку подчинённой форме, открытой с конкретным владельцем.
Где и как запускать
Полный модуль собственной управляемой формы списка; серверная запись двух своих элементов и клиентские позиционирование/оповещение.
Подготовка
Создайте с нуля пустую конфигурацию УчебныеОповещенияФорм85 на платформе8.5.1.1343, управляемое приложение, Такси. Без рабочих данных, расширений, подписок, разделителей и чужих обработчиков.
Справочники → УчебныеКарточки85: неиерархический, Наименование длиной80, стандартная автонумерация кода. Добавьте реквизит Метка85 типа Строка длиной36. В новом справочнике исходно нет ни одного элемента.
Создайте управляемую форму списка УчебныйСписок85 и назначьте основной формой списка. Основной реквизит Список типа ДинамическийСписок, главная таблица Справочник.УчебныеКарточки85, без произвольного запроса. Таблица формы Карточки привязана к Список; в ней выводятся Код и Наименование.
В списке создайте реквизиты Метка85 типа Строка36, ПерваяКарточка85, ВтораяКарточка85, НоваяКарточка85 типа СправочникСсылка.УчебныеКарточки85, ПодтверждаюПустойСтенд типа Булево и Итог85 типа Строка неограниченной длины. Ссылки, метку и Итог показывайте только для просмотра.
Добавьте команды и кнопки ПодготовитьСвоиКарточки85, ОткрытьНаблюдателя85, ПерейтиККниге85, ПерейтиКРучке85, ОткрытьСвойРедактор85. Действия — одноимённые процедуры основного модуля списка. Назначьте форме ОбработкаЗаписиНового с точной сигнатурой из модуля.
Общие формы → УчебныйНаблюдатель85, управляемая. Параметр Метка85 типа Строка36; реквизиты Метка85 Строка36, АктивнаяКарточка85 типа СправочникСсылка.УчебныеКарточки85 и Итог85 Строка. Все отображаемые поля только для просмотра. Вставьте модуль наблюдателя и назначьте ПриСозданииНаСервере и ОбработкаАктивизации.
Общие формы → УчебныйРедактор85, управляемая. Параметр Метка85 Строка36; реквизиты Метка85 Строка36, Наименование85 Строка80, СозданнаяКарточка85 типа СправочникСсылка.УчебныеКарточки85, ПодтверждаюЗапись85 Булево, Итог85 Строка. Метка, ссылка и итог только для просмотра; добавьте кнопку ЗаписатьСвоюНовую85 и назначьте ПриСозданииНаСервере.
Справочник → Формы → УчебнаяКарточка85, управляемая форма объекта, основная форма объекта. Основной реквизит Объект автоматически связан с учебным справочником. Добавьте несохраняемые реквизиты ПодтверждаюОпыт85 Булево и Итог85 Строка, команду ПроверитьСвоюБлокировку85 и её кнопку; модуль объектной формы указан отдельно.
Нажмите F7 и обновите только новый стенд. runtimeVerifiedScenarios=0: 1С здесь не запускалась, учебные элементы не создавались, блокировки и оповещения не выполнялись. Код и проверки подготовлены статически.
Вручную откройте свой список, подтвердите пустой стенд и подготовьте две карточки. Подготовка реально записывает Книга и Ручка только при вашем будущем запуске; обе получают один новый UUID. Повторная подготовка непустого справочника отклоняется, автоматического удаления данных нет.
Все дополнительные модули вставляются в свои отдельные формы, не в основной модуль списка. Открывайте наблюдателя и редактор только кнопками списка: ПолучитьФорму передаёт реального владельца, метку и ключ уникальности. Отдельно открытая общая форма не является тем же опытом.
&НаКлиенте
Перем Наблюдатель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
УчебныеОповещенияФорм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);
Если ИмяКарточки = "" Или СтрДлина(ИмяКарточки) > 80 Тогда
ВызватьИсключение "Укажите учебное наименование длиной1–80 символов";
КонецЕсли;
Своя = Справочники.УчебныеКарточки85.СоздатьЭлемент();
Своя.Наименование = ИмяКарточки;
Своя.Метка85 = Метка85;
Своя.Записать();
СозданнаяКарточка85 = Своя.Ссылка;
Возврат СозданнаяКарточка85;
КонецФункцииРазбор по шагам
Серверная подготовка допускается только в пустом учебном справочнике. Книга и Ручка записываются одной транзакцией; метка и обе реальные ссылки возвращаются клиенту после фиксации.
ОповеститьОбИзменении получает реальный тип собственного справочника после фактического изменения нескольких объектов. Он обновляет динамические списки с главной таблицей, а не произвольные таблицы без неё.
ПолучитьФорму открывает наблюдателя с ЭтаФорма в параметре Владелец. Метка передаётся параметром и ключом уникальности; она не заменяет отношение владения.
ВыполнитьПереход получает собственную сохранённую ссылку Книга или Ручка, которая относится к главной таблице основного динамического списка.
ОповеститьОбАктивизации явно передаёт ту же реальную ссылку подчинённой форме. Её ОбработкаАктивизации проверяет источник, владельца, имя формы, метку и тип ссылки.
В обработчике активизации выполняются только чтение клиентских простых полей и установка локальных реквизитов. Серверные методы формы, ПолучитьОбъект и чтение реквизитов ссылки не вызываются.
Как проверить результат
После подготовки список содержит две реальные карточки с общей меткой; второй запуск подготовки непустого справочника отклоняется.
После завершения ПерейтиККниге85 текущая строка списка — Книга, а поле наблюдателя содержит ссылку на Книга.
После ПерейтиКРучке85 текущая строка и ссылка наблюдателя относятся к Ручка.
Проверяйте результат после возврата команды и отображения формы. Закрытый наблюдатель не обязан получать событие; снова откройте его собственной кнопкой.
Ожидаемый результат
Два реальных сохранённых объекта используются для позиционирования и передачи активизации, без подмены ссылки текстом.
На что обратить внимание
Главная таблица и основной динамический список обязательны для ВыполнитьПереход. Переход не создаёт объект и не выполняет поиск по его названию.
ОповеститьОбАктивизации направляется подчинённым формам; форма без переданного владельца не становится наблюдателем только из-за одинаковой метки.
ОповеститьОбИзменении очищает клиентские кэши и уведомляет списки; он не сохраняет изменённые данные. Здесь запись завершена до оповещения.
ОбработкаАктивизации не должна обращаться к серверным методам формы или менять свойства с серверным вызовом. Не добавляйте в неё получение объекта ссылки ради красивого текста.
Метка — контроль собственной партии, не механизм авторизации. Стенд должен быть новым и пустым, без других сеансов и чужих обработчиков.
Две записи остаются в учебном стенде. В этом коде нет их удаления, удаления чужого справочника или попытки очистить production.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.