Расширение формы журнала документов

Типы · Document journal form extension

Дополнительные свойства объекта Форма журнала документов. Используется в случае, если основным реквизитом формы является список документов.

Полное описание, параметры и ограничения

Расширение формы журнала документов (Document journal form extension)

Расширение формы журнала документов (Document journal form extension)

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

Свойства:
ПараметрТекущаяСтрока (CurrentLineParameter)

Описание:

Дополнительные свойства объекта Форма журнала документов. Используется в случае, если основным реквизитом формы является список документов.

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

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

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

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

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

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

Корзина1050: ПросмотрЖурнала85 на своём полном учебном стенде

Часть одного самостоятельного примера: собственные фактические источники/фабрики/формы, учебная копия будущей цены и полный числовой readback.

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

Платформа8.5.1.1343 Windows толстый клиент, ОбычноеПриложение.

Подготовка

  1. Это единый учебный стенд корзины: три исходные строки A/B/C имеют количества2/3/5, цены300/100/30 и суммы600/300/150, всего1050. Оригинальные документы и цены остаются неизменными; отдельная A_COPY на следующую дату позволяет сравнить другой объём и будущую цену. Ниже все результаты ожидаемые: запуск1С здесь не выполнялся.

  2. В отдельной учебной Windows VM вручную создайте НОВУЮ пустую файловую ИБ строго C:\1c-labs\OwnInformationPriceJournal85_f1bd8718-0e22-4a55-9b3c-e6b6d3aa0585\IB. Не копируйте production и не переименовывайте чужую базу. Используйте именно8.5.1.1343, имя конфигурации КорзинаТарифов85, РежимСовместимости=НеИспользовать. В редакторе Сервис → Параметры → Общие выберите редактирование для режима запуска «Управляемое приложение и обычное приложение»; это НЕ свойство metadata. ОсновнойРежимЗапуска пока ОбычноеПриложение. Оба опыта выполняются только толстым клиентом Windows; managed пульт и модуль приложения дополнительно ограничены native препроцессором ТолстыйКлиентУправляемоеПриложение. Thin/web не поддерживаются этим примером.

  3. Создайте одного реального пользователя Тариф85Ученик с ролью ПолныеПрава и правом АктивныеПользователи. Сохраните пользователя; код самостоятельно читает и сравнивает actual UUID. При каждом опыте закройте Конфигуратор и прочие соединения: должен быть один именно текущий клиент. Этот guard не блокирует последующие подключения и не является глобальной блокировкой.

  4. По видимому JSON создайте ровно один непроводимый документ, один НЕЗАВИСИМЫЙ периодический День регистр сведений и один журнал этого документа. У регистра нет регистратора/разделителей, история данных выключена. Не добавляйте каталоги, подписки, фоновые задания или расширения. Точные типы, поля, формы, графы и связи приведены полностью, никаких скрытых assets нет.

  5. Общий модуль УчебныеТарифы85: Сервер=Да, КлиентОбычноеПриложение=Да, ВызовСервера=Да; КлиентУправляемоеПриложение/Глобальный/ВнешнееСоединение/Привилегированный=Нет, повторное использование возвращаемых значений НеИспользовать. Вставьте COMMON без раздела переменных и препроцессорного вырезания процедур. У обычных форм вызывается собственный клиентский экземпляр общего модуля: реальные менеджер записи и набор создаются, читаются и возвращаются локально, не передаются через RPC. У серверных событий вызывается серверный экземпляр. Управляемый пульт получает с сервера только фактическую фиксированную структуру скалярных полей тарифа, затем сам толстый клиент создаёт настоящий ключ записи документированной фабрикой; непрозрачный ключ не возвращается из server RPC. Вставьте DOCUMENT_MODULE в модуль документа с native ПередЗаписью3; RECORDSET_MODULE в модуль набора с ПередЗаписью2. При записи независимого менеджера могут вызываться два набора: пустой удаляет старую запись, второй записывает новую. Проверка допускает пустой набор только при точном собственном отборе Период+Код85; это не публичная команда удаления.

  6. Создайте пять форм регистра по JSON. У обычных форм основной реквизит Запись85 либо Список85/Набор85 с точным реальным типом; у управляемой Запись, который платформа предоставляет как ДанныеФормыСтруктура. Не заменяйте расширения самостоятельным Новый и не передавайте короткий API owner «Расширение записи регистра сведений» в Type. Он только registry label; реальные объекты получены native фабрикой и compiled metadata.

  7. Вставьте все указанные модули обычных форм и управляющих общих форм, назначьте события через свойства. Кнопки обычного приложения вызываются native Нажатие0 с дополнительным первым Элемент; обработчик поэтому принимает ровно Кнопка. Управляемая команда принимает Команда. Объектные/форменные события вручную не вызываются. Служебные managed attrs и основной реквизит объявите по JSON, не храните серверное состояние в клиентских Перем.

  8. В ordinary MAIN КопированиеТарифа85 и СписокНабор85 обе собственные процедуры ПроверитьДочернююЗапись85(Дочерняя) и ОстановитьДочернююЗапись85(Дочерняя) обязательно оставьте Экспорт. Дочерние формы берут реального ВладелецФормы и обращаются к этим процедурам: владелец сверяет именно свой сохранённый child-instance, согласие, этап и private sticky-stop. Не создавайте свойства формы из private Перем. Native ПередЗаписью дочерней формы выполняет ту же защиту даже для стандартной команды записи. При ошибке child останавливается; после подтверждения своего владельца останавливается и MAIN. Если guard владельца отказал, он уже выставил свой stop. Ошибку не лечат повтором или автоматическим восстановлением.

  9. В журнале настройте все шесть граф, каждую на одноимённый реквизит своего единственного документа. Создайте обычную форму ЖурналКорзины85 с настоящим ЖурналДокументовСписок.Корзина85 как основным реквизитом. Все11 колонок имеют точное Данные=имя поля; не подменяйте журнал ДокументСписок или выборкой. Номер.ОтображатьСтандартнуюКартинку=Истина задайте явно; у списка цен Сумма85.ОтображатьСтандартнуюКартинку тоже явно Истина. Это начальная собственная политика, не догадка о platform default.

  10. Вставьте APPLICATION_ORDINARY и APPLICATION_MANAGED в соответствующие реальные модули приложений, подключите native ПриНачалеРаботыСистемы0. Обновите только свою CF, закройте Конфигуратор. Обычный толстый клиент открывает свой пульт. Флажок согласия всюду изначально Ложь; установите его только после понимания будущих операций.

  11. ОДИН раз Подготовить85: создаются три собственных непроводимых документа и три исходных цены. Code выводит суммы настоящего query readback. Частичный отказ не очищается и не повторяется: закончите опыт, вручную анализируйте собственный стенд. Не используйте повторный запуск как обход отказа.

  12. Запись85 открывает управляющую форму. Согласие, первый Шаг85 — реальный loaded record manager A и его обычная форма просмотра. Закройте просмотр, второй Шаг85 — native manager.GetRecordEditingForm с собственным владельцем/UUID, явное копирование всех своих значений и собственный новый ключ A_COPY/11.10.2026. CopyingObjectParameter содержит настоящий исходный менеджер, но не считается гарантией автоматического заполнения. Native WriteInForm0 должен вернуть True; fresh полный регистр4 строки1650, копия600, исходные3 строки1050.

  13. Закройте только собственные редакторы. Набор85: согласие и первый Шаг85 проверяет настоящий список/колонку, меняет и после доказанного собственного состояния восстанавливает политику стандартных значков. Затем создаёт native набор с равенством Период=11.10.2026 и Код85=A_COPY, читает ровно1 запись и получает его реальную форму. Два следующих Шаг85 сохраняют количество2→3→2 при цене300: сумма копии600→900→600; весь регистр1650→1950→1650. Меняется только собственный scoped набор, не исходные цены.

  14. Журнал85: согласие и первый Шаг85 получает настоящее значение ЖурналыДокументовМенеджер, свой manager.GetForm3 и ставит параметр позиции на реальную ссылку A ДО Open. Дождитесь строк, затем Шаг85. Проверяются actual GUI RowData по всем трём настоящим refs и всем11 значениям каждой строки, GUI-сумма1050 отдельно от DB-суммы1050. Undefined означает остановку; query rows вместо GUI не подставляются. Изменение и восстановление icon policy подтверждает только свойства, не отрисованные пиксели.

  15. Полностью закройте обычный клиент. Только в своей CF вручную измените ОсновнойРежимЗапуска на УправляемоеПриложение, обновите её и закройте Конфигуратор. Второй толстый клиент открывает управляемый пульт; согласие и Открыть85 — native GetForm с только что созданным ключом своей существующей копии, explicit owner и no-search Истина. Проверяется реально загруженный record, а не пустой default key.

  16. В управляемой форме согласие и четыре Шаг85: сохранить цену300→350 (копия700/весь регистр1750); создать известный несохранённый буфер400/800 и native Read0 вернуть350/700; сохранить350→300 (600/1650); получить native navigation link0 без external data и сравнить с Global URL для заново созданного ключа из fresh readback. Ключ регистра не является устойчивой ссылкой и не переносится как вечный идентификатор через перезаписи. Ссылка отображается как текст; переход/сеть не вызываются.

  17. При False, неизвестной форме/строке/состоянии или исключении экземпляр останавливается. После частичного действия нет слепого rollback, повторной записи, удаления или автоматического retry. Полному native чтению/статическим тестам не приписываются runtime success, UI-атомарность, пиксели, RLS, историческая неизменность bytes или проверка чужих данных.

Перем До85, Журнал85, Остановка85, Этап85;

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

Процедура Шаг85(Кнопка)
    Если Остановка85 Или Не Согласие85 Или Кнопка <> ЭлементыФормы.Шаг85 Или (Этап85 <> 0 И Этап85 <> 1) Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Неизвестный шаг или нет согласия";
    КонецЕсли;
    Попытка
        Сейчас = УчебныеТарифы85.Источник85();
        УчебныеТарифы85.ПроверитьИсходные85(До85, Сейчас);
        Если Этап85 = 0 Тогда
            Менеджеры = ЖурналыДокументов;
            Если ТипЗнч(Менеджеры) <> Тип("ЖурналыДокументовМенеджер") Тогда
                ВызватьИсключение "Не настоящий менеджер собственных журналов";
            КонецЕсли;
            Журнал85 = Менеджеры.Корзина85.ПолучитьФорму("ЖурналКорзины85", ЭтаФорма, Новый УникальныйИдентификатор);
            Если Журнал85 = Неопределено Тогда
                ВызватьИсключение "Свой журнал не получен";
            КонецЕсли;
            Если ТипЗнч(Журнал85) <> Тип("Форма") Или Журнал85.ВладелецФормы <> ЭтаФорма Тогда
                ВызватьИсключение "Не собственная форма журнала";
            КонецЕсли;
            Журнал85.ПараметрТекущаяСтрока = Сейчас.Документы[0].Ссылка;
            Журнал85.Открыть();
            Этап85 = 1;
            Протокол85 = "Дождитесь отображения трёх своих документов и текущей строки A, затем Шаг85. Параметр позиции не заменяет доставку данных.";
        Иначе
            Поле = Журнал85.ЭлементыФормы.Документы85;
            Колонка = Поле.Колонки.Найти("Номер");
            Если Колонка = Неопределено Или Поле.Данные <> "Список85" Или Поле.Значение <> Журнал85.Список85
                Или ТипЗнч(Журнал85.Список85) <> Тип("ЖурналДокументовСписок.Корзина85") Или Поле.ТекущаяСтрока <> Сейчас.Документы[0].Ссылка Тогда
                ВызватьИсключение "Не собственный журнал с фактически доставленной текущей строкой";
            КонецЕсли;
            Если ТипЗнч(Колонка) <> Тип("КолонкаТабличногоПоля") Или Не Колонка.ОтображатьСтандартнуюКартинку Тогда
                ВызватьИсключение "Не подготовленная политика колонки журнала";
            КонецЕсли;
            СуммаGUI = 0;
            Для Каждого Документ Из Сейчас.Документы Цикл
                Ячейки = Поле.ДанныеСтроки(Документ.Ссылка);
                Если Ячейки = Неопределено Тогда
                    ВызватьИсключение "GUI ещё не отдал свою строку; запрос не подставляется";
                КонецЕсли;
                Если Ячейки.Ссылка <> Документ.Ссылка Или Ячейки.Номер <> Документ.Номер Или Ячейки.Дата <> Документ.Дата
                    Или Ячейки.Проведен <> Документ.Проведен Или Ячейки.ПометкаУдаления <> Документ.ПометкаУдаления
                    Или Ячейки.Код85 <> Документ.Код85 Или Ячейки.Маркер85 <> Документ.Маркер85 Или Ячейки.Пользователь85 <> Документ.Пользователь85
                    Или Ячейки.Количество85 <> Документ.Количество85 Или Ячейки.Цена85 <> Документ.Цена85 Или Ячейки.Сумма85 <> Документ.Сумма85 Тогда
                    ВызватьИсключение "Настоящие ячейки собственного журнала отличаются от базы";
                КонецЕсли;
                СуммаGUI = СуммаGUI + Ячейки.Сумма85;
            КонецЦикла;
            Если СуммаGUI <> 1050 Или СуммаGUI <> Сейчас.ИтогДокументов Тогда
                ВызватьИсключение "Полная GUI-корзина не подтвердилась";
            КонецЕсли;
            Колонка.ОтображатьСтандартнуюКартинку = Ложь;
            Если Колонка.ОтображатьСтандартнуюКартинку Тогда
                ВызватьИсключение "Политика стандартных значков не изменилась";
            КонецЕсли;
            УчебныеТарифы85.ПроверитьИсходные85(До85, УчебныеТарифы85.Источник85());
            Колонка.ОтображатьСтандартнуюКартинку = Истина;
            Если Не Колонка.ОтображатьСтандартнуюКартинку Тогда
                ВызватьИсключение "Восстановление своей политики не подтвердилось";
            КонецЕсли;
            Этап85 = 2;
            Протокол85 = "В трёх настоящих GUI-строках сумма " + Формат(СуммаGUI, "ЧГ=0;ЧДЦ=0") + ". Проверены данные и политика, не пиксели стандартных картинок.";
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Общий модуль УчебныеТарифы85: обычный клиент и сервер

Общие модули → УчебныеТарифы85 → Модуль

Толстый обычный клиент/сервер: отдельные экземпляры общего модуля; обычные менеджер/набор возвращаются локально, не через RPC.

Функция ПроверитьСтенд85() Экспорт
    Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnInformationPriceJournal85_f1bd8718-0e22-4a55-9b3c-e6b6d3aa0585\IB"";" Тогда
        ВызватьИсключение "Только собственная новая файловая база 8.5.1.1343";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
        ВызватьИсключение "Нужен один настоящий пользователь";
    КонецЕсли;
    Если Текущий.Имя <> "Тариф85Ученик" Или Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор Тогда
        ВызватьИсключение "Чужой пользователь";
    КонецЕсли;
    Соединения = ПолучитьСоединенияИнформационнойБазы();
    Если Соединения.Количество() <> 1 Тогда
        ВызватьИсключение "Закройте Конфигуратор и остальные клиенты";
    КонецЕсли;
    Соединение = Соединения[0];
    Если ТипЗнч(Соединение) <> Тип("СоединениеИнформационнойБазы")
        Или Соединение.НомерСоединения <> НомерСоединенияИнформационнойБазы()
        Или Соединение.Пользователь.УникальныйИдентификатор <> Текущий.УникальныйИдентификатор Тогда
        ВызватьИсключение "Не своё единственное соединение";
    КонецЕсли;
    Если Метаданные.Документы.Количество() <> 1 Или Метаданные.РегистрыСведений.Количество() <> 1
        Или Метаданные.ЖурналыДокументов.Количество() <> 1 Или Метаданные.ОбщиеМодули.Количество() <> 1
        Или Метаданные.ОбщиеФормы.Количество() <> 5 Или Метаданные.Справочники.Количество() <> 0
        Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0
        Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0
        Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0
        Или Метаданные.РегламентныеЗадания.Количество() <> 0
        Или Метаданные.РегистрыСведений.ЦенаКорзины85.РежимЗаписи <> Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый
        Или Метаданные.РегистрыСведений.ЦенаКорзины85.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.День
        Или Метаданные.Документы.СтрокаКорзины85.Проведение <> Метаданные.СвойстваОбъектов.Проведение.Запретить Тогда
        ВызватьИсключение "Другой состав или режим собственного стенда";
    КонецЕсли;
    Модуль = Метаданные.ОбщиеМодули.УчебныеТарифы85;
    Если Не Модуль.Сервер Или Не Модуль.КлиентОбычноеПриложение Или Не Модуль.ВызовСервера
        Или Модуль.КлиентУправляемоеПриложение Или Модуль.Глобальный Или Модуль.Привилегированный
        Или Модуль.ПовторноеИспользованиеВозвращаемыхЗначений <> Метаданные.СвойстваОбъектов.ПовторноеИспользованиеВозвращаемыхЗначений.НеИспользовать Тогда
        ВызватьИсключение "Нужны отдельные ordinary/server экземпляры без кеширования и привилегий";
    КонецЕсли;
    Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0 Тогда
        ВызватьИсключение "Расширения запрещены";
    КонецЕсли;
    Возврат Строка(Текущий.УникальныйИдентификатор);
КонецФункции

Функция Ожидаемое85(Код) Экспорт
    Если Код = "A" Тогда
        Возврат Новый ФиксированнаяСтруктура("Количество,Цена,Сумма,Минуты", 2, 300, 600, 0);
    ИначеЕсли Код = "B" Тогда
        Возврат Новый ФиксированнаяСтруктура("Количество,Цена,Сумма,Минуты", 3, 100, 300, 1);
    ИначеЕсли Код = "C" Тогда
        Возврат Новый ФиксированнаяСтруктура("Количество,Цена,Сумма,Минуты", 5, 30, 150, 2);
    КонецЕсли;
    ВызватьИсключение "Неизвестный собственный код";
КонецФункции

Функция Источник85() Экспорт
    Пользователь = ПроверитьСтенд85();
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ Ссылка, Номер, Дата, Проведен, ПометкаУдаления, Код85, Маркер85, Пользователь85, Количество85, Цена85, Сумма85 ИЗ Документ.СтрокаКорзины85 УПОРЯДОЧИТЬ ПО Код85";
    Документы = Запрос.Выполнить().Выгрузить();
    Документы.Колонки.Добавить("Версия85", Новый ОписаниеТипов("Строка"));
    Если Документы.Количество() > 3 Тогда
        ВызватьИсключение "Лишние документы в своём стенде";
    КонецЕсли;
    Коды = "ABC";
    ИтогДокументов = 0;
    Для Индекс = 0 По Документы.Количество() - 1 Цикл
        Строка = Документы[Индекс];
        Код = Сред(Коды, Индекс + 1, 1);
        Эталон = Ожидаемое85(Код);
        Если ТипЗнч(Строка.Ссылка) <> Тип("ДокументСсылка.СтрокаКорзины85") Или Строка.Ссылка.Пустая() Тогда
            ВызватьИсключение "Не настоящая собственная ссылка";
        КонецЕсли;
        Объект = Строка.Ссылка.ПолучитьОбъект();
        Если Объект.ЭтоНовый() Или Объект.Ссылка <> Строка.Ссылка Или Объект.Номер = "" Или Объект.Проведен Или Объект.ПометкаУдаления
            Или Объект.Код85 <> Код Или Объект.Маркер85 <> "f1bd8718-0e22-4a55-9b3c-e6b6d3aa0585" Или Объект.Пользователь85 <> Пользователь
            Или Объект.Дата <> Дата(2026, 10, 10, 12, Эталон.Минуты, 0)
            Или Объект.Количество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";
    Цены = Запрос.Выполнить().Выгрузить();
    Если Цены.Количество() <> 0 И Цены.Количество() <> 3 И Цены.Количество() <> 4 Тогда
        ВызватьИсключение "Неизвестное или частичное состояние цен";
    КонецЕсли;
    Копия = Неопределено;
    ИтогЦен = 0;
    Для Каждого Строка Из Цены Цикл
        ПроверитьСтроку85(Строка, Пользователь);
        Если Строка.Код85 = "A_COPY" Тогда
            Если Копия <> Неопределено Тогда
                ВызватьИсключение "Больше одной своей копии";
            КонецЕсли;
            Копия = Новый ФиксированнаяСтруктура("Период,Код85,Количество85,Цена85,Сумма85", Строка.Период, Строка.Код85, Строка.Количество85, Строка.Цена85, Строка.Сумма85);
        КонецЕсли;
        ИтогЦен = ИтогЦен + Строка.Сумма85;
    КонецЦикла;
    Если Цены.Количество() = 3 И Копия <> Неопределено Или Цены.Количество() = 4 И Копия = Неопределено Тогда
        ВызватьИсключение "Нарушен состав исходных цен и одной копии";
    КонецЕсли;
    Если Цены.Количество() > 0 Тогда
        Для Каждого Код Из Новый Структура("A,B,C") Цикл
            Найденные = Цены.НайтиСтроки(Новый Структура("Код85", Код.Ключ));
            Если Найденные.Количество() <> 1 Тогда
                ВызватьИсключение "Отсутствует исходная цена или есть дубль";
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    Если ПроверитьСтенд85() <> Пользователь Тогда
        ВызватьИсключение "Пользователь изменился";
    КонецЕсли;
    Возврат Новый ФиксированнаяСтруктура("Документы,Цены,Копия,ИтогДокументов,ИтогЦен,Пользователь", Документы, Цены, Копия, ИтогДокументов, ИтогЦен, Пользователь);
КонецФункции

Процедура ПроверитьСтроку85(Строка, Пользователь) Экспорт
    Если Строка.Маркер85 <> "f1bd8718-0e22-4a55-9b3c-e6b6d3aa0585" Или Строка.Пользователь85 <> Пользователь
        Или Строка.Сумма85 <> Строка.Количество85 * Строка.Цена85 Тогда
        ВызватьИсключение "Не собственные данные строки цены";
    КонецЕсли;
    Если Строка.Код85 = "A_COPY" Тогда
        Если Строка.Период <> Дата(2026, 10, 11) Или (Строка.Количество85 <> 2 И Строка.Количество85 <> 3)
            Или (Строка.Цена85 <> 300 И Строка.Цена85 <> 350) Или (Строка.Количество85 = 3 И Строка.Цена85 <> 300) Тогда
            ВызватьИсключение "Не своё разрешённое состояние будущего тарифа";
        КонецЕсли;
    Иначе
        Эталон = Ожидаемое85(Строка.Код85);
        Если Строка.Период <> Дата(2026, 10, 10) Или Строка.Количество85 <> Эталон.Количество
            Или Строка.Цена85 <> Эталон.Цена Или Строка.Сумма85 <> Эталон.Сумма Тогда
            ВызватьИсключение "Исходную цену изменять нельзя";
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьИсходные85(До, Сейчас) Экспорт
    Если До.Пользователь <> Сейчас.Пользователь Или Сейчас.Документы.Количество() <> 3 Или Сейчас.Цены.Количество() < 3
        Или Сейчас.ИтогДокументов <> 1050 Тогда
        ВызватьИсключение "Потеряны собственные исходные данные";
    КонецЕсли;
    Для Индекс = 0 По 2 Цикл
        Если До.Документы[Индекс].Ссылка <> Сейчас.Документы[Индекс].Ссылка Или До.Документы[Индекс].Номер <> Сейчас.Документы[Индекс].Номер
            Или До.Документы[Индекс].Версия85 <> Сейчас.Документы[Индекс].Версия85 Тогда
            ВызватьИсключение "Изменились настоящие исходные документы";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Функция СвойМенеджер85(Копия) Экспорт
    Сейчас = Источник85();
    Если Сейчас.Документы.Количество() <> 3 Или Сейчас.Цены.Количество() < 3 Или Копия И Сейчас.Копия = Неопределено Тогда
        ВызватьИсключение "Сначала подготовьте свой источник";
    КонецЕсли;
    Запись = РегистрыСведений.ЦенаКорзины85.СоздатьМенеджерЗаписи();
    Запись.Период = ?(Копия, Дата(2026, 10, 11), Дата(2026, 10, 10));
    Запись.Код85 = ?(Копия, "A_COPY", "A");
    Запись.Прочитать();
    Если ТипЗнч(Запись) <> Тип("РегистрСведенийМенеджерЗаписи.ЦенаКорзины85") Или Не Запись.Выбран() Тогда
        ВызватьИсключение "Не считана настоящая собственная запись";
    КонецЕсли;
    ПроверитьСтроку85(Запись, Сейчас.Пользователь);
    Возврат Запись;
КонецФункции

Функция СвойНабор85() Экспорт
    Сейчас = Источник85();
    Если Сейчас.Копия = Неопределено Тогда
        ВызватьИсключение "Своя будущая цена ещё не создана";
    КонецЕсли;
    Набор = РегистрыСведений.ЦенаКорзины85.СоздатьНаборЗаписей();
    Набор.Отбор.Период.Установить(Дата(2026, 10, 11));
    Набор.Отбор.Код85.Установить("A_COPY");
    Набор.Прочитать();
    Если ТипЗнч(Набор) <> Тип("РегистрСведенийНаборЗаписей.ЦенаКорзины85") Или Набор.Количество() <> 1 Тогда
        ВызватьИсключение "Не считан единственный собственный набор копии";
    КонецЕсли;
    ПроверитьСтроку85(Набор[0], Сейчас.Пользователь);
    Возврат Набор;
КонецФункции

Функция СвойКлюч85() Экспорт
    Сейчас = Источник85();
    Если Сейчас.Копия = Неопределено Тогда
        ВызватьИсключение "Нет сохранённой собственной копии";
    КонецЕсли;
    Возврат РегистрыСведений.ЦенаКорзины85.СоздатьКлючЗаписи(Новый Структура("Период,Код85", Сейчас.Копия.Период, Сейчас.Копия.Код85));
КонецФункции

Процедура ПроверитьНабор85(Набор) Экспорт
    Сейчас = Источник85();
    Если Сейчас.Документы.Количество() <> 3 Или Набор.Количество() > 3 Тогда
        ВызватьИсключение "Не подготовлена своя корзина";
    КонецЕсли;
    Если Набор.Отбор.Период.Использование И Набор.Отбор.Код85.Использование Тогда
        Если Набор.Отбор.Период.Значение <> Дата(2026, 10, 11) Или Набор.Отбор.Код85.Значение <> "A_COPY" Или Набор.Количество() > 1 Тогда
            ВызватьИсключение "Можно записывать только ключ собственной копии";
        КонецЕсли;
        Для Каждого Строка Из Набор Цикл
            ПроверитьСтроку85(Строка, Сейчас.Пользователь);
            Если Строка.Код85 <> "A_COPY" Или Строка.Период <> Дата(2026, 10, 11) Тогда
                ВызватьИсключение "Строка вне своего точного отбора";
            КонецЕсли;
        КонецЦикла;
    Иначе
        Если Набор.Отбор.Период.Использование Или Набор.Отбор.Код85.Использование Или Сейчас.Цены.Количество() <> 0 Или Набор.Количество() <> 3 Тогда
            ВызватьИсключение "Полный набор допускается только для первой подготовки";
        КонецЕсли;
        Для Индекс = 0 По 2 Цикл
            Строка = Набор[Индекс];
            Если Строка.Код85 <> Сред("ABC", Индекс + 1, 1) Тогда
                ВызватьИсключение "Не три собственные исходные цены";
            КонецЕсли;
            ПроверитьСтроку85(Строка, Сейчас.Пользователь);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Функция Подготовить85(Согласие) Экспорт
    Если Согласие <> Истина Тогда
        ВызватьИсключение "Подтвердите первую подготовку своего стенда";
    КонецЕсли;
    До = Источник85();
    Если До.Документы.Количество() <> 0 Или До.Цены.Количество() <> 0 Тогда
        ВызватьИсключение "Повтор и очистка после частичной подготовки запрещены";
    КонецЕсли;
    Набор = РегистрыСведений.ЦенаКорзины85.СоздатьНаборЗаписей();
    Для Индекс = 0 По 2 Цикл
        Код = Сред("ABC", Индекс + 1, 1);
        Эталон = Ожидаемое85(Код);
        Документ = Документы.СтрокаКорзины85.СоздатьДокумент();
        Документ.Дата = Дата(2026, 10, 10, 12, Эталон.Минуты, 0);
        Документ.Код85 = Код;
        Документ.Маркер85 = "f1bd8718-0e22-4a55-9b3c-e6b6d3aa0585";
        Документ.Пользователь85 = До.Пользователь;
        Документ.Количество85 = Эталон.Количество;
        Документ.Цена85 = Эталон.Цена;
        Документ.Сумма85 = Эталон.Сумма;
        Документ.Записать(РежимЗаписиДокумента.Запись);
        Строка = Набор.Добавить();
        Строка.Период = Дата(2026, 10, 10);
        Строка.Код85 = Код;
        Строка.Маркер85 = Документ.Маркер85;
        Строка.Пользователь85 = До.Пользователь;
        Строка.Количество85 = Эталон.Количество;
        Строка.Цена85 = Эталон.Цена;
        Строка.Сумма85 = Эталон.Сумма;
    КонецЦикла;
    ПроверитьНабор85(Набор);
    Набор.Записать();
    После = Источник85();
    Если После.Документы.Количество() <> 3 Или После.Цены.Количество() <> 3 Или После.ИтогДокументов <> 1050 Или После.ИтогЦен <> 1050 Тогда
        ВызватьИсключение "Первая подготовка не подтверждена";
    КонецЕсли;
    Возврат После;
КонецФункции
Модуль документа СтрокаКорзины85

Документы → СтрокаКорзины85 → Модуль объекта

Сервер/толстый клиент собственного объекта; native BeforeWrite3.

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Попытка
        Сейчас = УчебныеТарифы85.Источник85();
        Если РежимЗаписи <> РежимЗаписиДокумента.Запись Или Не ЭтотОбъект.ЭтоНовый() Или Сейчас.Документы.Количество() >= 3 Или Сейчас.Цены.Количество() <> 0 Тогда
            ВызватьИсключение "Документы создаются только при первой подготовке, существующие не записываются";
        КонецЕсли;
        Код = Сред("ABC", Сейчас.Документы.Количество() + 1, 1);
        Эталон = УчебныеТарифы85.Ожидаемое85(Код);
        Если ЭтотОбъект.Код85 <> Код Или ЭтотОбъект.Маркер85 <> "f1bd8718-0e22-4a55-9b3c-e6b6d3aa0585"
            Или ЭтотОбъект.Пользователь85 <> Сейчас.Пользователь Или ЭтотОбъект.Дата <> Дата(2026, 10, 10, 12, Эталон.Минуты, 0)
            Или ЭтотОбъект.Количество85 <> Эталон.Количество Или ЭтотОбъект.Цена85 <> Эталон.Цена Или ЭтотОбъект.Сумма85 <> Эталон.Сумма
            Или ЭтотОбъект.ПометкаУдаления Или ЭтотОбъект.Проведен Тогда
            ВызватьИсключение "Нарушена собственная единственная подготовка корзины";
        КонецЕсли;
    Исключение
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Модуль набора ЦенаКорзины85

Регистры сведений → ЦенаКорзины85 → Модуль набора записей

Сервер/толстый клиент собственного набора, native BeforeWrite2.

Процедура ПередЗаписью(Отказ, Замещение)
    Попытка
        УчебныеТарифы85.ПроверитьНабор85(ЭтотОбъект);
    Исключение
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Оригинальная цена: обычная форма

ЦенаКорзины85 → Формы → ИсходнаяЗапись85 → Модуль

Обычный толстый клиент, actual loaded record manager.

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

Процедура ПередЗаписью(Отказ)
    Отказ = Истина;
    ВызватьИсключение "Оригинал открыт только для просмотра; форма его не записывает";
КонецПроцедуры
Новая цена: обычная форма

ЦенаКорзины85 → Формы → КопияЗаписи85 → Модуль

Обычный толстый клиент, настоящий основной Запись85 и CopyingObjectParameter.

Перем Остановка85, До85;

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

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

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

ЦенаКорзины85 → Формы → НаборЦен85 → Модуль

Обычный толстый клиент, real scoped main Набор85.

Перем Остановка85;

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

Процедура ПередЗаписью(Отказ)
    ВладелецПодтвержден = Ложь;
    Попытка
        Владелец = ЭтаФорма.ВладелецФормы;
        Если ТипЗнч(Владелец) <> Тип("Форма") Тогда
            ВызватьИсключение "У набора нет настоящего собственного владельца";
        КонецЕсли;
        Владелец.ПроверитьДочернююЗапись85(ЭтаФорма);
        ВладелецПодтвержден = Истина;
        Если Остановка85 Тогда
            ВызватьИсключение "Экземпляр набора остановлен";
        КонецЕсли;
        Сейчас = УчебныеТарифы85.Источник85();
        УчебныеТарифы85.ПроверитьНабор85(Набор85);
        Если Сейчас.Копия = Неопределено Или Набор85.Количество() <> 1 Тогда
            ВызватьИсключение "Нет своей сохранённой копии";
        КонецЕсли;
        Строка = Набор85[0];
        Если Строка.Цена85 <> 300 Или Сейчас.Копия.Цена85 <> 300 Или Строка.Количество85 = Сейчас.Копия.Количество85 Тогда
            ВызватьИсключение "Набор меняет только количество своей копии2↔3 при цене300";
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        Отказ = Истина;
        Если ВладелецПодтвержден Тогда
            Владелец.ОстановитьДочернююЗапись85(ЭтаФорма);
        КонецЕсли;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Обычная форма списка цен

ЦенаКорзины85 → Формы → СписокЦен85 → Модуль

Обычный толстый клиент, real РегистрСведенийСписок и GUI data binding.

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

Журналы документов → Корзина85 → Формы → ЖурналКорзины85 → Модуль

Обычный толстый клиент, real ЖурналДокументовСписок и parameter positioning.

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

Общие формы → ПультЦен85 → Модуль

Обычный толстый клиент, собственная общая форма.

Перем Остановка85;

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

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

Общие формы → ПультЦенУправляемый85 → Модуль

Управляемый толстый клиент/сервер по директивам: RPC возвращает скалярные поля, native ключ создаётся локально толстым клиентом.

&НаСервере
Функция СвойТарифНаСервере85()
    Сейчас = УчебныеТарифы85.Источник85();
    Если Сейчас.Копия = Неопределено Тогда
        ВызватьИсключение "Сначала создайте свой тариф";
    КонецЕсли;
    Если Сейчас.Копия.Количество85 <> 2 Или Сейчас.Копия.Цена85 <> 300 Или Сейчас.ИтогЦен <> 1650 Тогда
        ВызватьИсключение "Завершите восстановление своего ordinary опыта";
    КонецЕсли;
    Возврат Сейчас.Копия;
КонецФункции

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

&НаКлиенте
Процедура Открыть85(Команда)
    #Если ТолстыйКлиентУправляемоеПриложение Тогда
    Если Остановка85 Или Не Согласие85 Или Открыто85 Или Команда.Имя <> "Открыть85" Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Разрешена одна собственная форма после согласия";
    КонецЕсли;
    Попытка
        Тариф = СвойТарифНаСервере85();
        Если ТипЗнч(Тариф) <> Тип("ФиксированнаяСтруктура") Или Тариф.Период <> Дата(2026, 10, 11)
            Или Тариф.Код85 <> "A_COPY" Или Тариф.Количество85 <> 2 Или Тариф.Цена85 <> 300 Или Тариф.Сумма85 <> 600 Тогда
            ВызватьИсключение "Сервер не подтвердил свои числовые поля тарифа";
        КонецЕсли;
        Ключ = РегистрыСведений.ЦенаКорзины85.СоздатьКлючЗаписи(Новый Структура("Период,Код85", Тариф.Период, Тариф.Код85));
        Если ТипЗнч(Ключ) <> Тип("РегистрСведенийКлючЗаписи.ЦенаКорзины85") Или Ключ.Период <> Тариф.Период Или Ключ.Код85 <> Тариф.Код85 Тогда
            ВызватьИсключение "Не получен настоящий локальный ключ своей записи";
        КонецЕсли;
        Форма = ПолучитьФорму("РегистрСведений.ЦенаКорзины85.Форма.УправляемаяЗапись85", Новый Структура("Ключ", Ключ), ЭтаФорма, Истина);
        Если Форма = Неопределено Тогда
            ВызватьИсключение "Своя управляемая форма не получена";
        КонецЕсли;
        Если ТипЗнч(Форма) <> Тип("ФормаКлиентскогоПриложения") Или Форма.ВладелецФормы <> ЭтаФорма
            Или Форма.Запись.Код85 <> "A_COPY" Или Форма.Запись.Период <> Дата(2026, 10, 11) Тогда
            ВызватьИсключение "Не собственная запись, загруженная реальным ключом";
        КонецЕсли;
        Открыто85 = Истина;
        Форма.Открыть();
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
    #Иначе
        Остановка85 = Истина;
        ВызватьИсключение "Этот собственный опыт требует управляемый толстый клиент";
    #КонецЕсли
КонецПроцедуры
Приложение ordinary

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

Обычный толстый клиент, native OnStart0.

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

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

Управляемый толстый клиент, native OnStart0.

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

Общие формы → КопированиеТарифа85 → Модуль

Обычный толстый клиент, свой controller.

Перем До85, ИсходнаяФорма85, КопияФорма85, ИсходнаяЗапись85, Остановка85, Этап85;

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

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

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

Процедура Шаг85(Кнопка)
    Если Остановка85 Или Не Согласие85 Или Кнопка <> ЭлементыФормы.Шаг85 Или (Этап85 <> 0 И Этап85 <> 1) Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Неизвестный шаг или нет согласия";
    КонецЕсли;
    Попытка
        Сейчас = УчебныеТарифы85.Источник85();
        УчебныеТарифы85.ПроверитьИсходные85(До85, Сейчас);
        Если Сейчас.Копия <> Неопределено Тогда
            ВызватьИсключение "Свою копию уже создали";
        КонецЕсли;
        Если Этап85 = 0 Тогда
            ИсходнаяЗапись85 = УчебныеТарифы85.СвойМенеджер85(Ложь);
            ИсходнаяФорма85 = ИсходнаяЗапись85.ПолучитьФорму("ИсходнаяЗапись85", ЭтаФорма, Новый УникальныйИдентификатор);
            Если ИсходнаяФорма85 = Неопределено Тогда
                ВызватьИсключение "Форма своего оригинала не получена";
            КонецЕсли;
            Если ТипЗнч(ИсходнаяФорма85) <> Тип("Форма") Или ИсходнаяФорма85.ВладелецФормы <> ЭтаФорма Или ИсходнаяФорма85.Запись85 <> ИсходнаяЗапись85 Тогда
                ВызватьИсключение "Не свой исходный объект формы";
            КонецЕсли;
            ИсходнаяФорма85.Открыть();
            Этап85 = 1;
            Протокол85 = "Просмотрите исходный тариф A: количество2, цена300, сумма600. Закройте только эту свою форму, затем Шаг85.";
        Иначе
            Если ИсходнаяФорма85.Открыта() Тогда
                ВызватьИсключение "Сначала закройте просмотр своего оригинала";
            КонецЕсли;
            КопияФорма85 = РегистрыСведений.ЦенаКорзины85.ПолучитьФормуРедактированияЗаписи("КопияЗаписи85", ЭтаФорма, Новый УникальныйИдентификатор);
            Если КопияФорма85 = Неопределено Тогда
                ВызватьИсключение "Своя форма новой цены не получена";
            КонецЕсли;
            Если ТипЗнч(КопияФорма85) <> Тип("Форма") Или КопияФорма85.ВладелецФормы <> ЭтаФорма Тогда
                ВызватьИсключение "Чужая форма цены";
            КонецЕсли;
            Новая = КопияФорма85.Запись85;
            Если ТипЗнч(Новая) <> Тип("РегистрСведенийМенеджерЗаписи.ЦенаКорзины85") Или Новая.Выбран() Тогда
                ВызватьИсключение "Нужен настоящий несчитанный менеджер своей новой записи";
            КонецЕсли;
            Новая.Период = Дата(2026, 10, 11);
            Новая.Код85 = "A_COPY";
            Новая.Маркер85 = ИсходнаяЗапись85.Маркер85;
            Новая.Пользователь85 = ИсходнаяЗапись85.Пользователь85;
            Новая.Количество85 = ИсходнаяЗапись85.Количество85;
            Новая.Цена85 = ИсходнаяЗапись85.Цена85;
            Новая.Сумма85 = Новая.Количество85 * Новая.Цена85;
            КопияФорма85.ПараметрОбъектКопирования = ИсходнаяЗапись85;
            КопияФорма85.Открыть();
            Если КопияФорма85.ПараметрОбъектКопирования <> ИсходнаяЗапись85 Или Новая.Период <> Дата(2026, 10, 11) Или Новая.Код85 <> "A_COPY" Тогда
                ВызватьИсключение "Источник копирования или собственный ключ изменились";
            КонецЕсли;
            УчебныеТарифы85.ПроверитьИсходные85(До85, УчебныеТарифы85.Источник85());
            Если Не КопияФорма85.ЗаписатьВФорме() Тогда
                ВызватьИсключение "Создание копии отменено, повтор запрещён";
            КонецЕсли;
            После = УчебныеТарифы85.Источник85();
            УчебныеТарифы85.ПроверитьИсходные85(До85, После);
            Если После.Копия = Неопределено Тогда
                ВызватьИсключение "Сохранённая копия не найдена";
            КонецЕсли;
            Если После.Копия.Количество85 <> 2 Или После.Копия.Цена85 <> 300 Или После.Копия.Сумма85 <> 600 Или После.ИтогЦен <> 1650 Тогда
                ВызватьИсключение "Фактические данные своей копии не совпали";
            КонецЕсли;
            Этап85 = 2;
            Протокол85 = "Будущий тариф реально записан: " + Формат(После.Копия.Сумма85, "ЧГ=0;ЧДЦ=0") + "; все цены: " + Формат(После.ИтогЦен, "ЧГ=0;ЧДЦ=0");
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Полный MAIN: список и набор

Общие формы → СписокНабор85 → Модуль

Обычный толстый клиент, свой controller.

Перем До85, СписокФорма85, НаборФорма85, СвойНабор85, Остановка85, Этап85;

Процедура ПроверитьДочернююЗапись85(Дочерняя) Экспорт
    Если Дочерняя <> НаборФорма85 Или Остановка85 Или Не Согласие85 Или (Этап85 <> 1 И Этап85 <> 2) Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Запись разрешена только своему набору после согласия владельца";
    КонецЕсли;
КонецПроцедуры

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

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

Процедура Шаг85(Кнопка)
    Если Остановка85 Или Не Согласие85 Или Кнопка <> ЭлементыФормы.Шаг85 Или Этап85 < 0 Или Этап85 > 2 Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Нет согласия или неизвестный шаг";
    КонецЕсли;
    Попытка
        Сейчас = УчебныеТарифы85.Источник85();
        УчебныеТарифы85.ПроверитьИсходные85(До85, Сейчас);
        Если Этап85 = 0 Тогда
            СписокФорма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 = 1;
            Протокол85 = "Открыт набор только A_COPY на11.10.2026. Следующие шаги сохраняют количество2→3→2, исходные цены не меняются.";
        Иначе
            Если Сейчас.Копия = Неопределено Тогда
                ВызватьИсключение "Своя копия исчезла";
            КонецЕсли;
            ОжидаемоеКоличество = ?(Этап85 = 1, 2, 3);
            Если Сейчас.Копия.Количество85 <> ОжидаемоеКоличество Или Сейчас.Копия.Цена85 <> 300 Или СвойНабор85.Количество() <> 1 Тогда
                ВызватьИсключение "Состояние перед записью не подтверждено";
            КонецЕсли;
            Строка = СвойНабор85[0];
            УчебныеТарифы85.ПроверитьСтроку85(Строка, Сейчас.Пользователь);
            Если Строка.Количество85 <> ОжидаемоеКоличество Или Строка.Цена85 <> 300 Тогда
                ВызватьИсключение "Буфер набора отличается от сохранённой копии";
            КонецЕсли;
            НовоеКоличество = ?(Этап85 = 1, 3, 2);
            Строка.Количество85 = НовоеКоличество;
            Строка.Сумма85 = НовоеКоличество * Строка.Цена85;
            Если Не НаборФорма85.ЗаписатьВФорме() Тогда
                ВызватьИсключение "Запись набора отменена; слепое восстановление не выполняется";
            КонецЕсли;
            После = УчебныеТарифы85.Источник85();
            УчебныеТарифы85.ПроверитьИсходные85(До85, После);
            Если После.Копия.Количество85 <> НовоеКоличество Или После.Копия.Сумма85 <> НовоеКоличество * 300 Или После.ИтогЦен <> 1050 + НовоеКоличество * 300 Тогда
                ВызватьИсключение "Свежая база не подтвердила результат формы набора";
            КонецЕсли;
            Этап85 = Этап85 + 1;
            Протокол85 = "Фактическая сумма всех цен: " + Формат(После.ИтогЦен, "ЧГ=0;ЧДЦ=0");
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Полный MAIN: журнал

Общие формы → ПросмотрЖурнала85 → Модуль

Обычный толстый клиент, свой controller.

Перем До85, Журнал85, Остановка85, Этап85;

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

Процедура Шаг85(Кнопка)
    Если Остановка85 Или Не Согласие85 Или Кнопка <> ЭлементыФормы.Шаг85 Или (Этап85 <> 0 И Этап85 <> 1) Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Неизвестный шаг или нет согласия";
    КонецЕсли;
    Попытка
        Сейчас = УчебныеТарифы85.Источник85();
        УчебныеТарифы85.ПроверитьИсходные85(До85, Сейчас);
        Если Этап85 = 0 Тогда
            Менеджеры = ЖурналыДокументов;
            Если ТипЗнч(Менеджеры) <> Тип("ЖурналыДокументовМенеджер") Тогда
                ВызватьИсключение "Не настоящий менеджер собственных журналов";
            КонецЕсли;
            Журнал85 = Менеджеры.Корзина85.ПолучитьФорму("ЖурналКорзины85", ЭтаФорма, Новый УникальныйИдентификатор);
            Если Журнал85 = Неопределено Тогда
                ВызватьИсключение "Свой журнал не получен";
            КонецЕсли;
            Если ТипЗнч(Журнал85) <> Тип("Форма") Или Журнал85.ВладелецФормы <> ЭтаФорма Тогда
                ВызватьИсключение "Не собственная форма журнала";
            КонецЕсли;
            Журнал85.ПараметрТекущаяСтрока = Сейчас.Документы[0].Ссылка;
            Журнал85.Открыть();
            Этап85 = 1;
            Протокол85 = "Дождитесь отображения трёх своих документов и текущей строки A, затем Шаг85. Параметр позиции не заменяет доставку данных.";
        Иначе
            Поле = Журнал85.ЭлементыФормы.Документы85;
            Колонка = Поле.Колонки.Найти("Номер");
            Если Колонка = Неопределено Или Поле.Данные <> "Список85" Или Поле.Значение <> Журнал85.Список85
                Или ТипЗнч(Журнал85.Список85) <> Тип("ЖурналДокументовСписок.Корзина85") Или Поле.ТекущаяСтрока <> Сейчас.Документы[0].Ссылка Тогда
                ВызватьИсключение "Не собственный журнал с фактически доставленной текущей строкой";
            КонецЕсли;
            Если ТипЗнч(Колонка) <> Тип("КолонкаТабличногоПоля") Или Не Колонка.ОтображатьСтандартнуюКартинку Тогда
                ВызватьИсключение "Не подготовленная политика колонки журнала";
            КонецЕсли;
            СуммаGUI = 0;
            Для Каждого Документ Из Сейчас.Документы Цикл
                Ячейки = Поле.ДанныеСтроки(Документ.Ссылка);
                Если Ячейки = Неопределено Тогда
                    ВызватьИсключение "GUI ещё не отдал свою строку; запрос не подставляется";
                КонецЕсли;
                Если Ячейки.Ссылка <> Документ.Ссылка Или Ячейки.Номер <> Документ.Номер Или Ячейки.Дата <> Документ.Дата
                    Или Ячейки.Проведен <> Документ.Проведен Или Ячейки.ПометкаУдаления <> Документ.ПометкаУдаления
                    Или Ячейки.Код85 <> Документ.Код85 Или Ячейки.Маркер85 <> Документ.Маркер85 Или Ячейки.Пользователь85 <> Документ.Пользователь85
                    Или Ячейки.Количество85 <> Документ.Количество85 Или Ячейки.Цена85 <> Документ.Цена85 Или Ячейки.Сумма85 <> Документ.Сумма85 Тогда
                    ВызватьИсключение "Настоящие ячейки собственного журнала отличаются от базы";
                КонецЕсли;
                СуммаGUI = СуммаGUI + Ячейки.Сумма85;
            КонецЦикла;
            Если СуммаGUI <> 1050 Или СуммаGUI <> Сейчас.ИтогДокументов Тогда
                ВызватьИсключение "Полная GUI-корзина не подтвердилась";
            КонецЕсли;
            Колонка.ОтображатьСтандартнуюКартинку = Ложь;
            Если Колонка.ОтображатьСтандартнуюКартинку Тогда
                ВызватьИсключение "Политика стандартных значков не изменилась";
            КонецЕсли;
            УчебныеТарифы85.ПроверитьИсходные85(До85, УчебныеТарифы85.Источник85());
            Колонка.ОтображатьСтандартнуюКартинку = Истина;
            Если Не Колонка.ОтображатьСтандартнуюКартинку Тогда
                ВызватьИсключение "Восстановление своей политики не подтвердилось";
            КонецЕсли;
            Этап85 = 2;
            Протокол85 = "В трёх настоящих GUI-строках сумма " + Формат(СуммаGUI, "ЧГ=0;ЧДЦ=0") + ". Проверены данные и политика, не пиксели стандартных картинок.";
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Полный MAIN: управляемая запись

ЦенаКорзины85 → Формы → УправляемаяЗапись85 → Модуль

Управляемый толстый клиент/сервер по директивам, actual own main Запись.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Попытка
        Сейчас = УчебныеТарифы85.Источник85();
        Если Сейчас.Копия = Неопределено Или Сейчас.Документы.Количество() <> 3 Тогда
            ВызватьИсключение "Сначала закончите обычные упражнения своего стенда";
        КонецЕсли;
        Если Сейчас.Копия.Количество85 <> 2 Или Сейчас.Копия.Цена85 <> 300 Или Сейчас.ИтогЦен <> 1650 Тогда
            ВызватьИсключение "Не исходное состояние будущей цены";
        КонецЕсли;
        Ключ = Параметры.Ключ;
        Если ТипЗнч(Ключ) <> Тип("РегистрСведенийКлючЗаписи.ЦенаКорзины85") Или Ключ.Пустой()
            Или Ключ.Период <> Сейчас.Копия.Период Или Ключ.Код85 <> Сейчас.Копия.Код85 Тогда
            ВызватьИсключение "Не свежий ключ своей сохранённой записи";
        КонецЕсли;
        Пользователь85 = Сейчас.Пользователь;
        ДокументA85 = Сейчас.Документы[0].Ссылка;
        ДокументB85 = Сейчас.Документы[1].Ссылка;
        ДокументC85 = Сейчас.Документы[2].Ссылка;
        ВерсияA85 = Сейчас.Документы[0].Версия85;
        ВерсияB85 = Сейчас.Документы[1].Версия85;
        ВерсияC85 = Сейчас.Документы[2].Версия85;
        ПроверитьДанные85(Запись, Пользователь85, Сейчас.Копия);
        Этап85 = 0;
        Согласие85 = Ложь;
        Остановка85 = Ложь;
    Исключение
        Остановка85 = Истина;
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаСервере
Функция ПроверитьНаСервере85(Цена)
    Если Остановка85 Тогда
        ВызватьИсключение "Свой экземпляр остановлен";
    КонецЕсли;
    Сейчас = УчебныеТарифы85.Источник85();
    Если Сейчас.Копия = Неопределено Или Сейчас.Документы.Количество() <> 3 Тогда
        ВызватьИсключение "Потеряны свои записи";
    КонецЕсли;
    Если Сейчас.Пользователь <> Пользователь85 Или Сейчас.Документы[0].Ссылка <> ДокументA85
        Или Сейчас.Документы[1].Ссылка <> ДокументB85 Или Сейчас.Документы[2].Ссылка <> ДокументC85
        Или Сейчас.Документы[0].Версия85 <> ВерсияA85 Или Сейчас.Документы[1].Версия85 <> ВерсияB85
        Или Сейчас.Документы[2].Версия85 <> ВерсияC85 Или Сейчас.Копия.Количество85 <> 2 Или Сейчас.Копия.Цена85 <> Цена
        Или Сейчас.Копия.Сумма85 <> 2 * Цена Или Сейчас.ИтогЦен <> 1050 + 2 * Цена Тогда
        ВызватьИсключение "Не своё ожидаемое состояние перед следующим шагом";
    КонецЕсли;
    Возврат Сейчас.Копия;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Процедура ПроверитьДанные85(Данные, Пользователь, Ожидаемое)
    Если ТипЗнч(Данные) <> Тип("ДанныеФормыСтруктура") Или Данные.Период <> Ожидаемое.Период Или Данные.Код85 <> Ожидаемое.Код85
        Или Данные.Количество85 <> Ожидаемое.Количество85 Или Данные.Цена85 <> Ожидаемое.Цена85 Или Данные.Сумма85 <> Ожидаемое.Сумма85
        Или Данные.Маркер85 <> "f1bd8718-0e22-4a55-9b3c-e6b6d3aa0585" Или Данные.Пользователь85 <> Пользователь Тогда
        ВызватьИсключение "Данные основной формы не совпали со своей полной записью";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура Шаг85(Команда)
    Если Остановка85 Или Не Согласие85 Или Команда.Имя <> "Шаг85" Или Этап85 < 0 Или Этап85 > 3 Тогда
        Остановка85 = Истина;
        ВызватьИсключение "Неизвестный шаг или нет согласия";
    КонецЕсли;
    Попытка
        Если Этап85 = 0 Или Этап85 = 2 Тогда
            Сохранённое = ПроверитьНаСервере85(?(Этап85 = 0, 300, 350));
            ПроверитьДанные85(Запись, Пользователь85, Сохранённое);
            Запись.Цена85 = ?(Этап85 = 0, 350, 300);
            Запись.Сумма85 = Запись.Количество85 * Запись.Цена85;
            Если Не ЭтаФорма.Записать(Новый Структура("Маркер85,Цель85", Запись.Маркер85, "ИзменениеЦены85")) Тогда
                ВызватьИсключение "Запись отменена; повтор и слепой откат запрещены";
            КонецЕсли;
            Сохранённое = ПроверитьНаСервере85(?(Этап85 = 0, 350, 300));
            ПроверитьДанные85(Запись, Пользователь85, Сохранённое);
            Этап85 = Этап85 + 1;
        ИначеЕсли Этап85 = 1 Тогда
            Сохранённое = ПроверитьНаСервере85(350);
            ПроверитьДанные85(Запись, Пользователь85, Сохранённое);
            Запись.Цена85 = 400;
            Запись.Сумма85 = 800;
            Если Запись.Период <> Дата(2026, 10, 11) Или Запись.Код85 <> "A_COPY" Или Запись.Количество85 <> 2
                Или Запись.Цена85 <> 400 Или Запись.Сумма85 <> 800 Тогда
                ВызватьИсключение "Не известный собственный несохранённый буфер";
            КонецЕсли;
            ЭтаФорма.Прочитать();
            Сохранённое = ПроверитьНаСервере85(350);
            ПроверитьДанные85(Запись, Пользователь85, Сохранённое);
            Этап85 = 2;
        Иначе
            Сохранённое = ПроверитьНаСервере85(300);
            ПроверитьДанные85(Запись, Пользователь85, Сохранённое);
            Ссылка = ЭтаФорма.ПолучитьНавигационнуюСсылкуЗаписи();
            СвежаяСсылка = СвояНавигационнаяСсылка85();
            Если ТипЗнч(Ссылка) <> Тип("Строка") Или Ссылка = "" Или Ссылка <> СвежаяСсылка Тогда
                ВызватьИсключение "Не навигационная ссылка своего текущего ключа";
            КонецЕсли;
            Этап85 = 4;
            Протокол85 = "Фактическая стоимость будущего тарифа " + Формат(Сохранённое.Сумма85, "ЧГ=0;ЧДЦ=0") + "; ссылка " + Ссылка + ". Внешние параметры не создавались, переход не выполнялся.";
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаСервере
Функция СвояНавигационнаяСсылка85()
    ПроверитьНаСервере85(300);
    СвежийКлюч = УчебныеТарифы85.СвойКлюч85();
    Возврат ПолучитьНавигационнуюСсылку(СвежийКлюч);
КонецФункции

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    Попытка
        Если Остановка85 Или Не Согласие85 Или (Этап85 <> 0 И Этап85 <> 2) Или Запись.Период <> Дата(2026, 10, 11) Или Запись.Код85 <> "A_COPY"
            Или ПараметрыЗаписи.Маркер85 <> Запись.Маркер85 Или ПараметрыЗаписи.Цель85 <> "ИзменениеЦены85" Тогда
            ВызватьИсключение "Не своя управляемая запись";
        КонецЕсли;
    Исключение
        Остановка85 = Истина;
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    Попытка
        Если Остановка85 Или Не Согласие85 Или (Этап85 <> 0 И Этап85 <> 2)
            Или ПараметрыЗаписи.Маркер85 <> ТекущийОбъект.Маркер85 Или ПараметрыЗаписи.Цель85 <> "ИзменениеЦены85"
            Или ТекущийОбъект.Период <> Дата(2026, 10, 11) Или ТекущийОбъект.Код85 <> "A_COPY"
            Или ТекущийОбъект.Количество85 <> 2 Или ТекущийОбъект.Цена85 <> ?(Этап85 = 0, 350, 300) Тогда
            ВызватьИсключение "Не свой объект/параметры/ожидаемая новая цена";
        КонецЕсли;
        ПроверитьНаСервере85(?(Этап85 = 0, 300, 350));
        УчебныеТарифы85.ПроверитьСтроку85(ТекущийОбъект, Пользователь85);
    Исключение
        Остановка85 = Истина;
        Отказ = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Видимая полная ручная спецификация собственного стенда

Конфигуратор собственной новой пустой ИБ

Копируемый manual JSON, не выполненная конфигурация/CF.

{
  "configuration": "КорзинаТарифов85",
  "CompatibilityMode": "НеИспользовать",
  "editorRunMode": "Сервис → Параметры → Общие → Редактирование конфигурации для режима запуска = Управляемое приложение и обычное приложение; это настройка редактора, не metadata property",
  "DefaultRunMode": "первый запуск ОбычноеПриложение; после ordinary опыта только в этой CF изменить на УправляемоеПриложение для второго толстого клиента",
  "user": "один Тариф85Ученик; actual UUID берётся native CurrentUser, не фиксируется выдуманной константой",
  "commonModule": {"name": "УчебныеТарифы85", "Server": true, "ServerCall": true, "ClientOrdinaryApplication": true, "ClientManagedApplication": false, "ExternalConnection": false, "Privileged": false, "Global": false, "ReturnValuesReuse": "НеИспользовать"},
  "fields": {"Код85": "Строка10", "Маркер85": "Строка36", "Пользователь85": "Строка36: текст actual user UUID", "Количество85": "Число10,0", "Цена85": "Число15,2", "Сумма85": "Число15,2"},
  "document": {"name": "СтрокаКорзины85", "Posting": "Запретить", "Number": "Строка9, автонумерация/контроль уникальности; читать actual номер, не угадывать", "attributes": "все fields как реквизиты", "forms": [], "tableParts": [], "registers": [], "module": "DOCUMENT_MODULE, native ПередЗаписью3"},
  "informationRegister": {"name": "ЦенаКорзины85", "WriteMode": "Независимый", "Periodicity": "День", "dimensions": {"Код85": "Строка10"}, "resources": {"Количество85": "Число10,0", "Цена85": "Число15,2", "Сумма85": "Число15,2"}, "attributes": {"Маркер85": "Строка36", "Пользователь85": "Строка36"}, "recorders": [], "sharedAttributes": [], "dataHistory": false, "sliceTotals": "не включать/не менять", "module": "RECORDSET_MODULE, native ПередЗаписью(Отказ,Замещение)"},
  "infoForms": {"ИсходнаяЗапись85": {"kind": "обычная форма записи", "mainAttribute": "Запись85: РегистрСведенийМенеджерЗаписи.ЦенаКорзины85, основной", "fields": "Период и все fields, Данные=Запись85.<поле>, все ТолькоПросмотр=Истина", "events": {"ПередОткрытием": "ПередОткрытием", "ПередЗаписью": "ПередЗаписью"}, "standardCommands": "удалить запись/удаление/изменение"}, "КопияЗаписи85": {"kind": "обычная форма записи", "mainAttribute": "Запись85: РегистрСведенийМенеджерЗаписи.ЦенаКорзины85, основной", "fields": "как ИсходнаяЗапись85, все только просмотр", "events": {"ПередОткрытием": "ПередОткрытием", "ПередЗаписью": "ПередЗаписью"}, "standardCommands": "удалить запись/удаление, controller пишет WriteInForm"}, "СписокЦен85": {"kind": "обычная форма списка", "mainAttribute": "Список85: РегистрСведенийСписок.ЦенаКорзины85, основной", "controls": {"Цены85": "ТабличноеПоле, Данные=Список85, ТолькоПросмотр=Истина"}, "columns": ["Период", "Код85", "Маркер85", "Пользователь85", "Количество85", "Цена85", "Сумма85"], "columnData": "каждое имя поля точно, без alias", "Сумма85.ОтображатьСтандартнуюКартинку": true, "events": {"ПередОткрытием": "ПередОткрытием"}, "standardCommands": "удалить запись/добавление/удаление"}, "НаборЦен85": {"kind": "обычная форма набора", "mainAttribute": "Набор85: РегистрСведенийНаборЗаписей.ЦенаКорзины85, основной", "controls": {"Цены85": "ТабличноеПоле, Данные=Набор85, ТолькоПросмотр=Истина"}, "columns": "те же7 полей, каждое Данные=точное имя", "events": {"ПередОткрытием": "ПередОткрытием", "ПередЗаписью": "ПередЗаписью"}, "standardCommands": "удалить запись/добавление/удаление; controller меняет ровно свой элемент"}, "УправляемаяЗапись85": {"kind": "управляемая форма записи", "mainAttribute": "Запись: РегистрСведенийМенеджерЗаписи.ЦенаКорзины85, основной, platform DataFormStructure", "attributes": {"Согласие85": "Булево defaultFalse", "Остановка85": "Булево", "Этап85": "Число2,0", "Пользователь85": "Строка36", "ДокументA85": "ДокументСсылка.СтрокаКорзины85", "ДокументB85": "ДокументСсылка.СтрокаКорзины85", "ДокументC85": "ДокументСсылка.СтрокаКорзины85", "ВерсияA85": "Строка неограниченная", "ВерсияB85": "Строка неограниченная", "ВерсияC85": "Строка неограниченная", "Протокол85": "Строка неограниченная"}, "controls": "Период/все fields как Запись.<поле>, только просмотр; Согласие85 флажок; Протокол85 просмотр; служебные attrs не выводить", "commands": {"Шаг85": "Действие=Шаг85"}, "events": {"ПриСозданииНаСервере": "ПриСозданииНаСервере", "ПередЗаписью": "ПередЗаписью", "ПередЗаписьюНаСервере": "ПередЗаписьюНаСервере"}, "standardCommands": "удалить запись/удаление"}},
  "journal": {"name": "Корзина85", "registeredDocuments": ["СтрокаКорзины85"], "graphs": "Код85/Маркер85/Пользователь85/Количество85/Цена85/Сумма85: каждый только одноимённый реквизит СтрокаКорзины85", "form": {"name": "ЖурналКорзины85", "kind": "обычная форма журнала", "mainAttribute": "Список85: ЖурналДокументовСписок.Корзина85, основной", "controls": {"Документы85": "ТабличноеПоле, Данные=Список85, ТолькоПросмотр=Истина"}, "columns": ["Ссылка", "Номер", "Дата", "Проведен", "ПометкаУдаления", "Код85", "Маркер85", "Пользователь85", "Количество85", "Цена85", "Сумма85"], "eachColumnData": "имя поля точно; встроенные5 поля +подготовленные6 граф", "Номер.ОтображатьСтандартнуюКартинку": true, "events": {"ПередОткрытием": "ПередОткрытием"}, "standardCommands": "удалить запись/добавление/удаление/проведение"}},
  "ordinaryCommonForms": {"ПультЦен85": {"attributes": "Согласие85 Булево defaultFalse; Протокол85 Строка неограниченная просмотр", "buttons": ["Подготовить85", "Запись85", "Набор85", "Журнал85"], "eachClick": "Действие85", "events": "ПередОткрытием=ПередОткрытием"}, "КопированиеТарифа85": "ORDINARY_RECORD", "СписокНабор85": "LIST_SET", "ПросмотрЖурнала85": "JOURNAL", "sharedControllerMetadata": {"mainAttribute": "нет", "attributes": "Согласие85 Булево defaultFalse; Протокол85 Строка неограниченная просмотр", "controls": "флажок Данные=Согласие85; поле протокола Данные=Протокол85; кнопка Шаг85, Нажатие=Шаг85", "events": "ПередОткрытием=ПередОткрытием", "exportedOwnerMethods": "КопированиеТарифа85 и СписокНабор85: ПроверитьДочернююЗапись85(Дочерняя), ОстановитьДочернююЗапись85(Дочерняя); это собственные процедуры Экспорт из полного MAIN, не native события"}},
  "managedCommonForm": {"name": "ПультЦенУправляемый85", "attributes": "Согласие85, Остановка85, Открыто85: Булево; флажок Согласие85 только он редактируется", "command": "Открыть85.Действие=Открыть85", "events": "ПриСозданииНаСервере=ПриСозданииНаСервере", "module": "MANAGED_HUB"},
  "fixture": {"originalCodes": ["A", "B", "C"], "quantity": [2, 3, 5], "price": [300, 100, 30], "amount": [600, 300, 150], "originalInfoDate": "2026-10-10T00:00:00", "documentDates": ["2026-10-10T12:00:00", "2026-10-10T12:01:00", "2026-10-10T12:02:00"], "copyCode": "A_COPY", "copyDate": "2026-10-11T00:00:00", "runtimeVerified": false}
}

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

  1. Полностью создайте свой пустой File CF по visible JSON и вставьте все модули. Сначала подготовка и ordinary копия, затем набор/журнал, отдельный managed запуск.

  2. Проверьте exact native factory, compiled основной реквизит/данные поля/владельца, согласие и известную фазу перед действием.

  3. Считайте реальные native данные после каждого сохранения. Source all rows остаётся полным; GUI читается отдельным RowData, без подстановки query row.

  4. После False/Unknown/ошибки остановитесь: не повторять операции и не восстанавливать неподтверждённое состояние.

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

  1. Документы A/B/C с actual refs/номерами/версиями и исходные цены1050 сохраняются; никакого проведения.

  2. Независимый record manager и его формы не подменены subordinate properties/constructor extension.

  3. Managed native client BeforeWrite2 не выполняет server RPC; server BeforeWrite3 принимает реальный RecordManager.

  4. Native key пересоздаётся из current own fields; не считается устойчивой ссылкой через overwrite.

  5. Каждая карточка содержит все supporting modules и полную visible JSON metadata, support targets остаются authored[].

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

Ожидаемый ручной результат: Три настоящие GUI-строки собственного журнала и полный DB source отдельно подтверждают1050; позиция/политика значков проверены, пиксели не измерены.

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

  1. Только authored/static/native проверка; actual1С/CF/DB/UI/network0.

  2. Обычная Форма и ФормаКлиентскогоПриложения имеют разные реальные расширения/события. API registry-short-owner не runtime type alias.

  3. JournalSelection8 исключён: его type и native manager.Select имеют противоречивые declared returns; здесь Select не вызывается.

  4. RecordManager только Независимый. Его subordinate Активность/Регистратор/НомерСтроки не используются; информационные totals не меняются.

  5. CopyingObjectParameter задаёт настоящий источник, но наши поля копирует собственный код, а не обещание platform autofill.

  6. Флаги значков/readbacks не доказывают pixels/security/RLS. Undefined GUI или неизвестное состояние не лечатся query substitution.

  7. Native record-manager replacement может вызвать пустой old-record set и new-record set; guard разрешает их только для своего exact equality key.

  8. Полные текущие scalar readbacks не являются историей всех изменений/байтов, общей атомарностью или блокировкой чужого сервера.

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

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

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

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

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