Добавляет новую запись в набор.
Синтаксис
Добавить()Полное описание, параметры и ограничения
РегистрНакопленияНаборЗаписей.<Имя регистра накопления>.Добавить (AccumulationRegisterRecordSet.<Accumulation register name>.Add)
РегистрНакопленияНаборЗаписей.<Имя регистра накопления> (AccumulationRegisterRecordSet.<Accumulation register name>)
Добавить (Add)
Доступен, начиная с версии 8.0.
Синтаксис:
Добавить()
Возвращаемое значение:
Тип: РегистрНакопленияЗапись.<Имя регистра накопления>.
Описание:
Добавляет новую запись в набор.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Использование в версии:
Доступен, начиная с версии 8.0.
Методическая информация
Практические примеры
Своя управляемая форма документа: запись, реальные движения, перечитывание и безопасный явный выбор
Новичок вручную готовит отдельную пустую 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. Не добавляйте эти объекты в УТ/КА2/УНФ/БП. Режим управления блокировкой данных конфигурации — Управляемый.
Документы → Добавить: УчебноеДвижение85. Номер: Строка длиной 40, автонумерация выключена. Модули объекта и менеджера оставьте пустыми; не добавляйте обработчики, подписки и обязательные пользовательские реквизиты.
Регистры накопления → Добавить: УчебныеОстатки85. Вид регистра Остатки. Единственное измерение КодТовара: Строка 50, индексировать, проверка заполнения Показывать ошибку. Единственный ресурс Количество: Число 12,3, неотрицательное. Дополнительных реквизитов нет.
В списке регистраторов выберите только собственный документ УчебноеДвижение85. Оставьте модули регистра пустыми, использование итогов включённым. Планы обмена, разделители, историю данных и фоновые задания для урока не создавайте.
Обновите конфигурацию базы данных. Создайте серверный общий модуль УчебныеЗадачи и команду собственной обработки. Фрагмент вставьте внутрь ВыполнитьПример() Экспорт; запускайте задачи по отдельности.
Первые задачи работают с незаписанными наборами. Только задачи с пометкой «в собственной транзакции» временно записывают два собственных документа и движения, затем обязательно отменяют транзакцию. В рабочей базе этот код не запускайте.
Если Метаданные.Документы.Количество() <> 1
Или Метаданные.РегистрыНакопления.Количество() <> 1
Или Метаданные.Документы.Найти("УчебноеДвижение85") = Неопределено Тогда
ВызватьИсключение "Разрешены только собственный учебный документ и регистр";
КонецЕсли;
Описание = Метаданные.РегистрыНакопления.Найти("УчебныеОстатки85");
Если Описание = Неопределено Тогда
ВызватьИсключение "Сначала создайте собственный учебный регистр";
КонецЕсли;
Если Описание.ВидРегистра <> Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки
Или Описание.Измерения.Количество() <> 1
Или Описание.Ресурсы.Количество() <> 1
Или Описание.Реквизиты.Количество() <> 0
Или Описание.Измерения.Найти("КодТовара") = Неопределено
Или Описание.Ресурсы.Найти("Количество") = Неопределено Тогда
ВызватьИсключение "Нужен регистр остатков с КодТовара и Количество";
КонецЕсли;
Менеджер = РегистрыНакопления.УчебныеОстатки85;
СсылкаНаНесохраненный = Документы.УчебноеДвижение85.ПолучитьСсылку(Новый УникальныйИдентификатор);
Набор = Менеджер.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(СсылкаНаНесохраненный);
Набор.Прочитать();
Сообщить(Набор.Количество() = 0);
Сообщить(Набор.Выбран());
Сообщить(Не Набор.Модифицированность());
ОписаниеНабора = Набор.Метаданные();
Сообщить(ОписаниеНабора.Имя = "УчебныеОстатки85");
Запись = Набор.Добавить();
Запись.Период = Дата(2026, 9, 15, 10, 0, 0);
Запись.Регистратор = СсылкаНаНесохраненный;
Запись.Активность = Истина;
Запись.ВидДвижения = ВидДвиженияНакопления.Приход;
Запись.Количество = 3;
// КодТовара пока не заполнен намеренно.
Сообщить(Не Набор.ПроверитьЗаполнение());
Запись.КодТовара = "TRAIN-" + Строка(Новый УникальныйИдентификатор);
Сообщить(Набор.ПроверитьЗаполнение());
Сообщить(Набор.Модифицированность());
Сообщить(Не Набор.Выбран());Разбор по шагам
Устанавливаем отбор по собственной новой ссылке ДО Прочитать. Документ по ней не сохраняли, движений для него нет.
После чтения набор пуст, Выбран=Истина и Модифицированность=Ложь. Метаданные подтверждает имя регистра.
Добавляем своё движение обычным Добавить и явно задаём ВидДвижения. Код оставляем пустым только для отрицательного теста.
ПроверитьЗаполнение возвращает Ложь и формирует сообщение по полю КодТовара. Это контролируемая учебная ошибка.
После заполнения кода проверка проходит, набор модифицирован и уже не является неизменённым считанным состоянием. Записи в базу нет.
Как проверить результат
Восемь булевых проверок Истина. Сообщение о незаполненном КодТовара между ними ожидаемо.
Если первая ПроверитьЗаполнение прошла, проверьте настройку измерения «Показывать ошибку», а не убирайте отрицательный тест.
Ожидаемый результат
Новичок понимает, что чтение, изменение и проверка обязательных полей — отдельные этапы до сохранения.
На что обратить внимание
ПроверитьЗаполнение не доказывает бизнес-корректность, наличие регистратора в базе или отсутствие конкурентных изменений.
Прочитать перезаписывает текущий набор в памяти. Здесь он новый; не теряйте несохранённые изменения рабочего набора.
Без отбора по регистратору можно случайно прочитать больше данных; здесь отбор установлен заранее.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.