Штатные фабрики: открыть именно свой список и свой прочитанный набор

Учебные задачи

Один полный самостоятельный маршрут собственной новой FileCF: реальные данные/штатные формы, различие отбора списка и строк и отдельное согласие на точную поправку.

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

Полный основной модуль: ОбщаяФорма.МаршрутПрихода85, обычная форма.

Подготовка

  1. Вручную создайте НОВУЮ файловую ИБ по точному пути C:\1C85_OwnAccumulationInvoice\9d8a6e13-4790-4bc1-a048-84c78ae597e5\Base. Это отдельный UUID-каталог собственного опыта, не UUID рабочей ИБ. Не копируйте УТ/КА/УНФ/БП и не используйте клиент-серверную ИБ. Здесь ИБ/каталог не создавались, 1С не запускалась.

  2. Конфигурация Уч85ПриходыСчета: в Конфигураторе выберите Сервис → Параметры → Общие → Редактирование конфигурации для режима запуска = «Управляемое приложение и обычное приложение»; свойство конфигурации ОсновнойРежимЗапуска = ОбычноеПриложение, режим совместимости Не использовать, платформа8.5.1.1343. Единственная роль УчебныйАдминистратор85: Администрирование для native списка пользователей; чтение/добавление/изменение своих документов и своего регистра, использование собственных обычных форм. Единственный пользователь Уч85Приход_9d8a6e13 получает эту роль. Нет BSP, расширений, разделителей, внешних источников и других прикладных объектов.

  3. Создайте Документ.Приход85: проведение РАЗРЕШИТЬ; три реквизита Метка85:Строка36, Пользователь85:Строка36, КодДокумента85:Строка1; табличных частей нет. Приход85 — единственный разрешенный тип регистратора РегистрНакопления.ПриходыСчета85, он выбран в составе движений документа. Модуль документа пуст: автоматических движений, обработок проведения и подписок нет. Вручную проводятся только два своих документа, движения вводятся отдельно штатной формой регистра ДО установки fail-closed обработчика.

  4. Создайте РегистрНакопления.ПриходыСчета85, вид регистра Остатки: одно измерение Код85:Строка10; ресурсы Количество85:Число9,0 неотрицательное и Сумма85:Число12,2 неотрицательное; реквизит Цена85:Число12,2 неотрицательное. Не добавляйте иных реквизитов, измерений, ресурсов и регистраторов. ВидДвижения читается только потому, что выбран регистр остатков; не переносите этот код в регистр оборотов.

  5. INITIAL FIXTURE делается вручную ДО вставки Set-модуля и событий собственных форм. Сначала в своем единственном FileCF получите UUID своего реального пользователя штатным синтаксис-помощником/конфигуратором и введите его строку в Пользователь85 обоих документов; не выдумывайте UUID. Документ A: дата10.10.2026 09:00:00, КодДокумента85=A; документ B: дата10.10.2026 10:00:00, код B. Метка обоих=9d8a6e13-4790-4bc1-a048-84c78ae597e5. Запишите и проведите оба документа, пометка удаления Ложь; номера реальные штатные непустые, не предписываются фиктивные номера.

  6. Пока fail-closed модули еще НЕ установлены, в штатной форме собственного регистра создайте по фактическому регистратору A ровно2 записи: номер1 кодA количество2 цена250 сумма500; номер2 кодAA количество1 цена250 сумма250. По фактическому регистратору B ровно1 запись: номер1 кодB количество3 цена250 сумма750. АктивностьИстина, ВидДвиженияПриход, Период ровноДата соответствующего документа. НомерСтроки readonly: не присваивайте его кодом; фактические номера проверяются после штатной записи. Проверяйте весь регистр1500 и только эти3 записи. Любая другая строка/неверный номер означает остановку, не автоматическое удаление/перепроведение.

  7. Теперь в Конфигураторе создайте ОбщийМодуль.УчПриходыСчета85: ГлобальныйНет, СерверДа, КлиентОбычноеПриложениеДа, ВнешнееСоединениеДа, КлиентУправляемоеПриложениеНет, ВызовСервераНет, ПривилегированныйНет, повторное использование возвращаемых значений Не использовать. Вставьте полный COMMON supporting module. Он содержит только чистые проверки/чтение и не хранит общую авторизацию в Перем.

  8. Создайте ОбщаяФорма.МаршрутПрихода85, вид Обычная: реквизит Состояние85:Строка500 только для просмотра; две обычные кнопки Список85/Набор85 с Нажатие→одноименнаяПроцедура(Кнопка), ровно1 параметр. ПриОткрытии→ПриОткрытии()0. Основной модуль Hub из первой карточки; родителем создаваемых форм является именно эта обычная форма, не control.

  9. В РегистрНакопления.ПриходыСчета85 мастером создайте обычную форму СПИСКА СписокСчета85. Основной реквизит Список:РегистрНакопленияСписок.ПриходыСчета85; ТабличноеПоле Строки85 с Данные=Список. Состояние85:Строка500 только для просмотра, кнопка ТочныйКод85 (native Нажатие1), ПриОткрытии0. Свой список получает ровно9 штатных/подготовленных колонок кодом. Вставьте LIST main module; параметры регистратора и ключа задает настоящий Hub ДО Открыть.

  10. Мастером создайте обычную форму НАБОРА НаборСчета85. Основной реквизит Набор:РегистрНакопленияНаборЗаписей.ПриходыСчета85; ТабличноеПоле Строки85, Данные=Набор. Состояние85:Строка500 только для просмотра; кнопки СледующийОтбор85/СвояПробнаяСтрока85/СохранитьПоправку85, каждая native Нажатие1. ПриОткрытии0, настоящее событие формы ПередЗаписью→ПередЗаписью(Отказ)1. Вставьте SET_FORM main module. Таблица только для просмотра: текущую существующую запись меняет исключительно подтвержденная собственная команда.

  11. В МОДУЛЬ НАБОРА ЗАПИСЕЙ собственного регистра вставьте полный SET_MODULE из четвертой карточки; native событие ПередЗаписью(Отказ,Замещение)2. ЭтотОбъект существует именно здесь. После установки вся неподтвержденная запись, включая штатные кнопки/ввод fixture повторно, отказывает. События нельзя вызывать вручную; форму и объект вызывает сама native WriteInForm.

  12. В модуль обычного приложения вставьте полный APPLICATION supporting module. Обновите свою новую конфигурацию и начните отдельный запуск толстого обычного клиента этой FileCF. Формы не вызывают неизвестные соседние уроки: все4 MAIN и полный COMMON/APP присутствуют в supporting modules каждой карточки. После успешной поправки начальный1500 уже не существует: новый просмотр этого одноразового маршрута намеренно откажет, автоматического восстановления fixture нет.

Перем Источник85;

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

Процедура Список85(Кнопка)
    Если Кнопка <> ЭлементыФормы.Список85 Или Кнопка.Имя <> "Список85" Тогда
        ВызватьИсключение "Нужна настоящая собственная кнопка списка.";
    КонецЕсли;
    УчПриходыСчета85.СравнитьИсточник85(Источник85, УчПриходыСчета85.Источник85());
    Менеджеры85 = РегистрыНакопления;
    Если ТипЗнч(Менеджеры85) <> Тип("РегистрыНакопленияМенеджер") Тогда
        ВызватьИсключение "Не получена штатная фабрика менеджеров.";
    КонецЕсли;
    Менеджер85 = Менеджеры85["ПриходыСчета85"];
    Ключ85 = УчПриходыСчета85.КлючAA85(Источник85);
    Форма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.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен реальный собственный пустой native набор.";
    КонецЕсли;
    СвойНабор85.Отбор.Регистратор.Установить(Источник85.Документы[0].Ссылка, Истина);
    СвойНабор85.Прочитать();
    УчПриходыСчета85.ПроверитьНабор85(СвойНабор85, Источник85, Ложь);
    Форма85 = СвойНабор85.ПолучитьФорму("НаборСчета85", ЭтаФорма, Новый УникальныйИдентификатор);
    Если Форма85 = Неопределено Тогда
        ВызватьИсключение "Штатная фабрика отказала в создании формы конкретного набора.";
    КонецЕсли;
    Если Форма85.ВладелецФормы <> ЭтаФорма Или Форма85.Набор <> СвойНабор85 Тогда
        ВызватьИсключение "Форма принадлежит не собственному владельцу/экземпляру набора.";
    КонецЕсли;
    Форма85.ПодтвердитьИсточник85(Источник85);
    Форма85.Открыть();
КонецПроцедуры
Чистый общий модуль проверок/чтения

Общие модули → УчПриходыСчета85; СерверДа/КлиентОбычноеПриложениеДа/ВнешнееСоединениеДа, не глобальный, не privileged, без shared Перем.

Функция Паспорт85() Экспорт
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1C85_OwnAccumulationInvoice\9d8a6e13-4790-4bc1-a048-84c78ae597e5\Base"";" Или Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или Метаданные.Документы.Количество() <> 1 Или Метаданные.РегистрыНакопления.Количество() <> 1 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.Справочники.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Тогда
        ВызватьИсключение "Допустим только точный новый собственный FileCF без совместимости.";
    КонецЕсли;
    ДокМД85 = Метаданные.Документы.Найти("Приход85");
    РегМД85 = Метаданные.РегистрыНакопления.Найти("ПриходыСчета85");
    Если ДокМД85 = Неопределено Или РегМД85 = Неопределено Тогда
        ВызватьИсключение "Не подготовлены единственные собственные прикладные объекты.";
    КонецЕсли;
    Если ДокМД85.Проведение <> Метаданные.СвойстваОбъектов.Проведение.Разрешить
        Или ДокМД85.Движения.Количество() <> 1 Или Не ДокМД85.Движения.Содержит(РегМД85)
        Или РегМД85.ВидРегистра <> Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки
        Или РегМД85.Измерения.Количество() <> 1
        Или РегМД85.Ресурсы.Количество() <> 2
        Или РегМД85.Реквизиты.Количество() <> 1 Тогда
        ВызватьИсключение "Проведение, собственное движение или полный состав регистра изменены.";
    КонецЕсли;
    РегистраторМД85 = Неопределено;
    Для Каждого Стандартный85 Из РегМД85.СтандартныеРеквизиты Цикл
        Если Стандартный85.Имя = "Регистратор" Тогда
            Если РегистраторМД85 <> Неопределено Тогда
                ВызватьИсключение "Неоднозначный стандартный реквизит регистратора.";
            КонецЕсли;
            РегистраторМД85 = Стандартный85;
        КонецЕсли;
    КонецЦикла;
    Если РегистраторМД85 = Неопределено Тогда
        ВызватьИсключение "Не найден стандартный тип регистратора.";
    КонецЕсли;
    Если РегистраторМД85.Тип.Типы().Количество() <> 1
        Или Не РегистраторМД85.Тип.СодержитТип(Тип("ДокументСсылка.Приход85")) Тогда
        ВызватьИсключение "Разрешен только собственный тип регистратора Приход85.";
    КонецЕсли;
    Для Каждого Имя85 Из СтрРазделить("Код85,Количество85,Сумма85,Цена85", ",") Цикл
        Описание85 = ?(Имя85 = "Код85", РегМД85.Измерения.Найти(Имя85), ?(Имя85 = "Цена85", РегМД85.Реквизиты.Найти(Имя85), РегМД85.Ресурсы.Найти(Имя85)));
        Если Описание85 = Неопределено Тогда
            ВызватьИсключение "Нет обязательного собственного поля " + Имя85;
        КонецЕсли;
        Если Имя85 = "Код85" Тогда
            ОжидаемыйТип85 = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(10));
        Иначе
            ОжидаемыйТип85 = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(?(Имя85 = "Количество85", 9, 12), ?(Имя85 = "Количество85", 0, 2), ДопустимыйЗнак.Неотрицательный));
        КонецЕсли;
        Если XML85(Описание85.Тип) <> XML85(ОжидаемыйТип85) Тогда
            ВызватьИсключение "Не совпал полный тип собственного поля " + Имя85;
        КонецЕсли;
    КонецЦикла;
    Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0 Тогда
        ВызватьИсключение "Стенд не должен содержать расширений.";
    КонецЕсли;
    Пользователь85 = ПользователиИнформационнойБазы.ТекущийПользователь();
    Пользователи85 = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если Пользователь85 = Неопределено Или Пользователи85.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен единственный свой администратор, не гостевой сеанс.";
    КонецЕсли;
    Если Пользователь85.Имя <> "Уч85Приход_9d8a6e13"
        Или Пользователи85[0].УникальныйИдентификатор <> Пользователь85.УникальныйИдентификатор
        Или Метаданные.Роли.Количество() <> 1
        Или Не Пользователь85.Роли.Содержит(Метаданные.Роли.УчебныйАдминистратор85) Тогда
        ВызватьИсключение "Подготовьте точного собственного пользователя и его единственную роль.";
    КонецЕсли;
    Возврат Новый Структура("Метка,Пользователь", "9d8a6e13-4790-4bc1-a048-84c78ae597e5", Строка(Пользователь85.УникальныйИдентификатор));
КонецФункции

Функция XML85(Значение85) Экспорт
    Писатель85 = Новый ЗаписьXML;
    Писатель85.УстановитьСтроку();
    Попытка
        СериализаторXDTO.ЗаписатьXML(Писатель85, Значение85);
    Исключение
        Писатель85.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Возврат Писатель85.Закрыть();
КонецФункции

Функция Источник85(Исправлен85 = Ложь) Экспорт
    Паспорт85 = Паспорт85();
    Запрос85 = Новый Запрос("ВЫБРАТЬ Д.Ссылка, Д.Дата, Д.Номер, Д.Проведен, Д.ПометкаУдаления, Д.Метка85, Д.Пользователь85, Д.КодДокумента85 ИЗ Документ.Приход85 КАК Д УПОРЯДОЧИТЬ ПО Д.КодДокумента85");
    Документы85 = Запрос85.Выполнить().Выгрузить();
    Если Документы85.Количество() <> 2 Тогда
        ВызватьИсключение "Допустимы ровно два собственных документа, проверяется весь источник.";
    КонецЕсли;
    Для Индекс85 = 0 По 1 Цикл
        Док85 = Документы85[Индекс85];
        Если ТипЗнч(Док85.Ссылка) <> Тип("ДокументСсылка.Приход85") Или Док85.Ссылка.Пустая()
            Или Док85.Метка85 <> Паспорт85.Метка Или Док85.Пользователь85 <> Паспорт85.Пользователь
            Или Док85.КодДокумента85 <> ?(Индекс85 = 0, "A", "B")
            Или Док85.Дата <> Дата(2026, 10, 10, 9 + Индекс85, 0, 0)
            Или ПустаяСтрока(Док85.Номер) Или Док85.ПометкаУдаления Или Не Док85.Проведен Тогда
            ВызватьИсключение "Не совпал полный паспорт своего реального документа.";
        КонецЕсли;
    КонецЦикла;
    Если Документы85[0].Ссылка = Документы85[1].Ссылка Тогда
        ВызватьИсключение "Регистраторы обязаны быть различными реальными ссылками.";
    КонецЕсли;
    Запрос85 = Новый Запрос("ВЫБРАТЬ Р.Регистратор, Р.НомерСтроки, Р.Период, Р.Активность, Р.ВидДвижения, Р.Код85, Р.Количество85, Р.Сумма85, Р.Цена85 ИЗ РегистрНакопления.ПриходыСчета85 КАК Р УПОРЯДОЧИТЬ ПО Р.Код85");
    Строки85 = Запрос85.Выполнить().Выгрузить();
    Если Строки85.Количество() <> 3 Или Строки85.Колонки.Количество() <> 9 Тогда
        ВызватьИсключение "Проверяется весь регистр: ровно три строки и девять полей без чужих записей.";
    КонецЕсли;
    Для Индекс85 = 0 По 2 Цикл
        Строка85 = Строки85[Индекс85];
        Регистратор85 = Документы85[?(Индекс85 = 2, 1, 0)].Ссылка;
        Количество85 = ?(Индекс85 = 0, ?(Исправлен85, 1, 2), ?(Индекс85 = 1, 1, 3));
        Код85 = ?(Индекс85 = 0, "A", ?(Индекс85 = 1, "AA", "B"));
        Если ТипЗнч(Строка85.Регистратор) <> Тип("ДокументСсылка.Приход85")
            Или Строка85.Регистратор <> Регистратор85
            Или Строка85.НомерСтроки <> ?(Индекс85 = 2, 1, Индекс85 + 1)
            Или Строка85.Период <> Документы85[?(Индекс85 = 2, 1, 0)].Дата
            Или Строка85.Код85 <> Код85 Или Не Строка85.Активность
            Или Строка85.ВидДвижения <> ВидДвиженияНакопления.Приход
            Или Строка85.Количество85 <> Количество85 Или Строка85.Цена85 <> 250
            Или Строка85.Сумма85 <> Количество85 * Строка85.Цена85 Тогда
            ВызватьИсключение "Изменились собственный реальный ключ, период, активность, вид движения или сумма.";
        КонецЕсли;
    КонецЦикла;
    Если Строки85.Итог("Количество85") <> ?(Исправлен85, 5, 6)
        Или Строки85.Итог("Сумма85") <> ?(Исправлен85, 1250, 1500) Тогда
        ВызватьИсключение "Независимый итог всего прочитанного регистра не совпал.";
    КонецЕсли;
    Возврат Новый Структура("Паспорт,Документы,Строки", Паспорт85, Документы85, Строки85);
КонецФункции

Процедура ПроверитьНабор85(Набор85, Источник85, Исправлен85) Экспорт
    Если ТипЗнч(Набор85) <> Тип("РегистрНакопленияНаборЗаписей.ПриходыСчета85")
        Или Набор85.Метаданные() <> Метаданные.РегистрыНакопления.ПриходыСчета85
        Или Набор85.Количество() <> 2 Или Набор85.Отбор.Количество() <> 1
        Или Не Набор85.Отбор.Регистратор.Использование
        Или Набор85.Отбор.Регистратор.ВидСравнения <> ВидСравнения.Равно
        Или Набор85.Отбор.Регистратор.Значение <> Источник85.Документы[0].Ссылка Тогда
        ВызватьИсключение "Нужен полный двухстрочный набор только собственного регистратора A.";
    КонецЕсли;
    Для Индекс85 = 0 По 1 Цикл
        Запись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 = 0, ?(Исправлен85, 1, 2), 1);
        Если Запись85.Количество85 <> Количество85 Или Запись85.Сумма85 <> Количество85 * Запись85.Цена85 Тогда
            ВызватьИсключение "Кандидат не совпал с точной собственной поправкой A.";
        КонецЕсли;
    КонецЦикла;
    Если Набор85.Итог("Количество85") <> ?(Исправлен85, 2, 3)
        Или Набор85.Итог("Сумма85") <> ?(Исправлен85, 500, 750) Тогда
        ВызватьИсключение "Полный итог реального набора A не совпал.";
    КонецЕсли;
КонецПроцедуры

Функция КлючAA85(Источник85) Экспорт
    Строка85 = Источник85.Строки[1];
    Если Строка85.Регистратор <> Источник85.Документы[0].Ссылка
        Или ТипЗнч(Строка85.Регистратор) <> Тип("ДокументСсылка.Приход85")
        Или ТипЗнч(Строка85.НомерСтроки) <> Тип("Число") Или Строка85.НомерСтроки <> 2
        Или Строка85.Код85 <> "AA" Тогда
        ВызватьИсключение "Ключ создается только после проверки реальных Регистратор/НомерСтроки.";
    КонецЕсли;
    ЗначенияКлюча85 = Новый Структура("Регистратор,НомерСтроки", Строка85.Регистратор, Строка85.НомерСтроки);
    Ключ85 = РегистрыНакопления.ПриходыСчета85.СоздатьКлючЗаписи(ЗначенияКлюча85);
    Если ТипЗнч(Ключ85) <> Тип("РегистрНакопленияКлючЗаписи.ПриходыСчета85")
        Или Ключ85.Регистратор <> Строка85.Регистратор Или Ключ85.НомерСтроки <> Строка85.НомерСтроки Тогда
        ВызватьИсключение "Фактический native ключ не совпал с двумя ключевыми полями.";
    КонецЕсли;
    Возврат Ключ85;
КонецФункции

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

Конфигурация → Модуль обычного приложения; native ПриНачалеРаботыСистемы0.

Процедура ПриНачалеРаботыСистемы()
    ПолучитьОбщуюФорму("МаршрутПрихода85", , Новый УникальныйИдентификатор).Открыть();
КонецПроцедуры
Список своего регистра: точный код500, реальное позиционирование и native картинки

РегистрНакопления.ПриходыСчета85.Форма.СписокСчета85, обычная форма списка

Перем Источник85, Готов85, НеизвестныйИсход85, Этап85;

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

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

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

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

Процедура ПроверитьРезультат85()
    Для Каждого Условие85 Из Список.Отбор Цикл
        Если Условие85.Использование И Условие85.Имя <> "Регистратор" И Условие85.Имя <> "Код85" Тогда
            ВызватьИсключение "Неизвестный активный отбор списка не удаляем.";
        КонецЕсли;
    КонецЦикла;
    Если Список.Отбор.Код85.Использование <> (Этап85 = 1)
        Или Этап85 = 1 И (Список.Отбор.Код85.ВидСравнения <> ВидСравнения.Равно Или Список.Отбор.Код85.Значение <> "A") Тогда
        ВызватьИсключение "Нужен именно точный отбор A, не строковое вхождение.";
    КонецЕсли;
    ФактСумма85 = 0;
    ФактЧисло85 = 0;
    Для Индекс85 = 0 По 1 Цикл
        Строка85 = Источник85.Строки[Индекс85];
        Ключ85 = РегистрыНакопления.ПриходыСчета85.СоздатьКлючЗаписи(Новый Структура("Регистратор,НомерСтроки", Строка85.Регистратор, Строка85.НомерСтроки));
        Если ЭлементыФормы.Строки85.ПроверитьСтроку(Ключ85) Тогда
            Данные85 = ЭлементыФормы.Строки85.ДанныеСтроки(Ключ85);
            Если Данные85 = Неопределено Тогда
                ВызватьИсключение "Нативное поле еще не вернуло данные собственной принятой строки.";
            КонецЕсли;
            Если Данные85.Регистратор <> Строка85.Регистратор Или Данные85.НомерСтроки <> Строка85.НомерСтроки
                Или Данные85.Период <> Строка85.Период Или Данные85.Активность <> Строка85.Активность
                Или Данные85.ВидДвижения <> Строка85.ВидДвижения Или Данные85.Код85 <> Строка85.Код85
                Или Данные85.Количество85 <> Строка85.Количество85 Или Данные85.Сумма85 <> Строка85.Сумма85
                Или Данные85.Цена85 <> Строка85.Цена85 Тогда
                ВызватьИсключение "Фактические данные поля не совпали с полной сохраненной строкой.";
            КонецЕсли;
            ФактЧисло85 = ФактЧисло85 + 1;
            ФактСумма85 = ФактСумма85 + Данные85.Сумма85;
        КонецЕсли;
    КонецЦикла;
    Если ФактЧисло85 <> ?(Этап85 = 1, 1, 2) Или ФактСумма85 <> ?(Этап85 = 1, 500, 750) Тогда
        ВызватьИсключение "Нативный список не подтвердил собственный числовой результат.";
    КонецЕсли;
    Состояние85 = "Нативно принятых строк=" + Строка(ФактЧисло85) + "; сумма=" + Строка(ФактСумма85) + "; сохраненный регистр=1500";
КонецПроцедуры
Набор своего прихода: вхождениеA/AA, безопасная pending проба и подтвержденная поправка

РегистрНакопления.ПриходыСчета85.Форма.НаборСчета85, обычная форма набора

Перем Источник85, Готов85, НеизвестныйИсход85, РазрешенаЗапись85, Этап85, Токен85;

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

Процедура ПриОткрытии()
    ПроверитьГотовность85();
    ПроверитьОтбор85(Ложь, 750, 2);
КонецПроцедуры

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

Процедура ПроверитьОтбор85(Включен85, ОжидаемаяСумма85, ОжидаемоеЧисло85)
    Таблица85 = ЭлементыФормы.Строки85;
    Если Таблица85.Данные <> "Набор" Или Таблица85.Значение <> Набор
        Или Таблица85.ИзменятьПорядокСтрок Или Таблица85.ИзменятьСоставСтрок
        Или Не Таблица85.ТолькоПросмотр Или Таблица85.ОбновлятьПриИзмененииОтбора
        Или Таблица85.ПроверкаОтображенияНовойСтроки <> ВариантПроверкиОтображенияНовойСтроки.СообщатьОНесоответствииОтбору
        Или Не Таблица85.Подвал Или Не Таблица85.Колонки.Сумма85.ОтображатьИтогиВПодвале
        Или Не Таблица85.Колонки.НомерСтроки.ОтображатьСтандартнуюКартинку Тогда
        ВызватьИсключение "Реальные собственные политики таблицы изменены.";
    КонецЕсли;
    Для Каждого Правило85 Из Таблица85.НастройкаОтбораСтрок Цикл
        Если Правило85.Доступность Тогда
            ВызватьИсключение "Не разрешена интерактивная подмена собственных row filters.";
        КонецЕсли;
    КонецЦикла;
    Для Каждого Условие85 Из Таблица85.ОтборСтрок Цикл
        Если Условие85.Использование И Условие85.Имя <> "Код85" Тогда
            ВызватьИсключение "Неизвестный активный row filter не удаляем.";
        КонецЕсли;
    КонецЦикла;
    Если Таблица85.ОтборСтрок.Код85.Использование <> Включен85 Тогда
        ВызватьИсключение "Не совпало реальное включение своего row filter.";
    КонецЕсли;
    ФактСумма85 = 0;
    ФактЧисло85 = 0;
    Для Каждого Запись85 Из Набор Цикл
        Если Таблица85.ПроверитьСтроку(Запись85) Тогда
            Данные85 = Таблица85.ДанныеСтроки(Запись85);
            Если ТипЗнч(Данные85) <> Тип("РегистрНакопленияЗапись.ПриходыСчета85") Тогда
                ВызватьИсключение "Native RowData не вернул настоящую запись своего набора.";
            КонецЕсли;
            Если Данные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 = ФактСумма85 + Данные85.Сумма85;
        КонецЕсли;
    КонецЦикла;
    Если ФактСумма85 <> ОжидаемаяСумма85 Или ФактЧисло85 <> ОжидаемоеЧисло85 Тогда
        ВызватьИсключение "Native CheckRow/RowData не подтвердили реальное вхождение и сумму.";
    КонецЕсли;
    Состояние85 = "Этап=" + Строка(Этап85) + "; native строк=" + Строка(ФактЧисло85) + "; сумма=" + Строка(ФактСумма85);
КонецПроцедуры

Процедура СледующийОтбор85(Кнопка)
    Если Кнопка <> ЭлементыФормы.СледующийОтбор85 Или Кнопка.Имя <> "СледующийОтбор85" Тогда
        ВызватьИсключение "Нужна настоящая кнопка своей таблицы.";
    КонецЕсли;
    ПроверитьГотовность85();
    Если Этап85 > 2 Тогда
        ВызватьИсключение "Три этапа отбора уже завершены.";
    КонецЕсли;
    НеизвестныйИсход85 = Истина;
    Попытка
        Снимок85 = УчПриходыСчета85.XML85(Набор.Выгрузить());
        ЭлементыФормы.Строки85.ОтборСтрок.Код85.Установить(?(Этап85 = 0, "A", "AA"), Этап85 <> 2);
        ЭлементыФормы.Строки85.ОбновитьСтроки();
        Этап85 = Этап85 + 1;
        ПроверитьОтбор85(Этап85 < 3, ?(Этап85 = 2, 250, 750), ?(Этап85 = 2, 1, 2));
        Если УчПриходыСчета85.XML85(Набор.Выгрузить()) <> Снимок85 Тогда
            ВызватьИсключение "Отбор представления изменил собственный полный набор.";
        КонецЕсли;
        УчПриходыСчета85.СравнитьИсточник85(Источник85, УчПриходыСчета85.Источник85());
        НеизвестныйИсход85 = Ложь;
    Исключение
        НеизвестныйИсход85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

Процедура СвояПробнаяСтрока85(Кнопка)
    Если Кнопка <> ЭлементыФормы.СвояПробнаяСтрока85 Или Кнопка.Имя <> "СвояПробнаяСтрока85" Тогда
        ВызватьИсключение "Нужна настоящая кнопка пробной строки.";
    КонецЕсли;
    ПроверитьГотовность85();
    Если Этап85 <> 3 Тогда
        ВызватьИсключение "Сначала завершите свой маршрут A/AA/без отбора.";
    КонецЕсли;
    НеизвестныйИсход85 = Истина;
    Попытка
        Снимок85 = УчПриходыСчета85.XML85(Набор.Выгрузить());
        ЭлементыФормы.Строки85.ОтборСтрок.Код85.Установить("AA", Истина);
        Проба85 = Набор.ДобавитьПриход();
        Проба85.Регистратор = Источник85.Документы[0].Ссылка;
        Проба85.Период = Источник85.Документы[0].Дата;
        Проба85.Активность = Истина;
        Проба85.Код85 = "B";
        Проба85.Количество85 = 1;
        Проба85.Цена85 = 100;
        Проба85.Сумма85 = Проба85.Количество85 * Проба85.Цена85;
        Если Набор.Количество() <> 3 Или ЭлементыФормы.Строки85.ПроверитьСтроку(Проба85) Тогда
            ВызватьИсключение "Своя pending строка B должна не соответствовать row filter AA.";
        КонецЕсли;
        Набор.Удалить(Проба85);
        Если УчПриходыСчета85.XML85(Набор.Выгрузить()) <> Снимок85 Тогда
            ВызватьИсключение "После удаления только собственной пробной строки полный набор не восстановился.";
        КонецЕсли;
        ЭлементыФормы.Строки85.ОтборСтрок.Код85.Использование = Ложь;
        ЭлементыФормы.Строки85.ОбновитьСтроки();
        УчПриходыСчета85.ПроверитьНабор85(Набор, Источник85, Ложь);
        ПроверитьОтбор85(Ложь, 750, 2);
        УчПриходыСчета85.СравнитьИсточник85(Источник85, УчПриходыСчета85.Источник85());
        Этап85 = 4;
        НеизвестныйИсход85 = Ложь;
    Исключение
        НеизвестныйИсход85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

Процедура СохранитьПоправку85(Кнопка)
    Если Кнопка <> ЭлементыФормы.СохранитьПоправку85 Или Кнопка.Имя <> "СохранитьПоправку85" Тогда
        ВызватьИсключение "Нужна настоящая собственная кнопка записи.";
    КонецЕсли;
    ПроверитьГотовность85();
    Если Этап85 <> 4 Тогда
        ВызватьИсключение "Сначала завершите все локальные проверки; повторная запись не разрешена.";
    КонецЕсли;
    Если Вопрос("ТОЛЬКО своя новая FileCF. Заменить ровно две записи своего документа A: A500→250, AA250 неизменно; общий итог1500→1250?", РежимДиалогаВопрос.ДаНет) <> КодВозвратаДиалога.Да Тогда
        УчПриходыСчета85.СравнитьИсточник85(Источник85, УчПриходыСчета85.Источник85());
        УчПриходыСчета85.ПроверитьНабор85(Набор, Источник85, Ложь);
        Возврат;
    КонецЕсли;
    ПроверитьГотовность85();
    НеизвестныйИсход85 = Истина;
    Токен85 = Строка(Новый УникальныйИдентификатор);
    Попытка
        Запись85 = Набор.Получить(0);
        Если Запись85.Код85 <> "A" Или Запись85.НомерСтроки <> 1 Тогда
            ВызватьИсключение "Нельзя изменять неизвестную строку.";
        КонецЕсли;
        Запись85.Количество85 = 1;
        Запись85.Сумма85 = Запись85.Количество85 * Запись85.Цена85;
        УчПриходыСчета85.ПроверитьНабор85(Набор, Источник85, Истина);
        Разрешение85 = Новый Структура("Метка,Пользователь,Регистратор,Токен,Подтверждено", Источник85.Паспорт.Метка, Источник85.Паспорт.Пользователь, Источник85.Документы[0].Ссылка, Токен85, Истина);
        Набор.ДополнительныеСвойства.Вставить("УчПриходРазрешение85", Разрешение85);
        РазрешенаЗапись85 = Истина;
        Если Не ЭтаФорма.ЗаписатьВФорме() Тогда
            ВызватьИсключение "Native WriteInForm вернул False; исход неизвестен, повтор и rollback запрещены.";
        КонецЕсли;
        РазрешенаЗапись85 = Ложь;
        Если Набор.ДополнительныеСвойства.Количество() <> 0 Тогда
            ВызватьИсключение "Нативный callback не подтвердил потребление собственных transient данных.";
        КонецЕсли;
        Свежий85 = УчПриходыСчета85.Источник85(Истина);
        Если УчПриходыСчета85.XML85(Свежий85.Документы) <> УчПриходыСчета85.XML85(Источник85.Документы) Тогда
            ВызватьИсключение "Запись регистра не должна менять собственные документы.";
        КонецЕсли;
        УчПриходыСчета85.ПроверитьНабор85(Набор, Свежий85, Истина);
        ПроверитьОтбор85(Ложь, 500, 2);
        Источник85 = Свежий85;
        Этап85 = 5;
        НеизвестныйИсход85 = Ложь;
        Состояние85 = "Полный fresh readback: свой A=500, свой B=750, общий итог1250; повтор записи запрещен.";
    Исключение
        РазрешенаЗапись85 = Ложь;
        НеизвестныйИсход85 = Истина;
        Если Набор.ДополнительныеСвойства.Свойство("УчПриходРазрешение85", Остаток85) Тогда
            Если ТипЗнч(Остаток85) = Тип("Структура") Тогда
                Если Остаток85.Свойство("Токен", ОстатокТокена85) И ОстатокТокена85 = Токен85 Тогда
                    Набор.ДополнительныеСвойства.Удалить("УчПриходРазрешение85");
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

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

РегистрНакопления.ПриходыСчета85 → Модуль набора записей

Процедура ПередЗаписью(Отказ, Замещение)
    Отказ = Истина;
#Если ТолстыйКлиентОбычноеПриложение Тогда
    СвойНабор85 = ЭтотОбъект;
    Если ТипЗнч(СвойНабор85) <> Тип("РегистрНакопленияНаборЗаписей.ПриходыСчета85")
        Или ТипЗнч(Замещение) <> Тип("Булево") Или Не Замещение
        Или ЭтотОбъект.ДополнительныеСвойства.Количество() <> 1 Тогда
        ВызватьИсключение "Допустим только свой обычный полный набор и явная замена с единственным разрешением.";
    КонецЕсли;
    Если Не СвойНабор85.ДополнительныеСвойства.Свойство("УчПриходРазрешение85", Разрешение85) Тогда
        ВызватьИсключение "Переданные своей формой данные отсутствуют: отказ, не предполагаем общее состояние клиента/сервера.";
    КонецЕсли;
    СвойНабор85.ДополнительныеСвойства.Удалить("УчПриходРазрешение85");
    Если ТипЗнч(Разрешение85) <> Тип("Структура") Или Разрешение85.Количество() <> 5 Тогда
        ВызватьИсключение "Разрешение обязано иметь ровно пять собственных полей.";
    КонецЕсли;
    Для Каждого Имя85 Из СтрРазделить("Метка,Пользователь,Регистратор,Токен,Подтверждено", ",") Цикл
        Если Не Разрешение85.Свойство(Имя85) Тогда
            ВызватьИсключение "Отсутствует обязательное поле собственного разрешения.";
        КонецЕсли;
    КонецЦикла;
    Источник85 = УчПриходыСчета85.Источник85();
    Если ТипЗнч(Разрешение85.Метка) <> Тип("Строка") Или Разрешение85.Метка <> Источник85.Паспорт.Метка
        Или ТипЗнч(Разрешение85.Пользователь) <> Тип("Строка") Или Разрешение85.Пользователь <> Источник85.Паспорт.Пользователь
        Или ТипЗнч(Разрешение85.Регистратор) <> Тип("ДокументСсылка.Приход85") Или Разрешение85.Регистратор <> Источник85.Документы[0].Ссылка
        Или ТипЗнч(Разрешение85.Токен) <> Тип("Строка") Или СтрДлина(Разрешение85.Токен) <> 36
        Или ТипЗнч(Разрешение85.Подтверждено) <> Тип("Булево") Или Не Разрешение85.Подтверждено Тогда
        ВызватьИсключение "Разрешение относится не к собственным пользователю/регистратору/нажатию.";
    КонецЕсли;
    Если НРег(Строка(Новый УникальныйИдентификатор(Разрешение85.Токен))) <> НРег(Разрешение85.Токен) Тогда
        ВызватьИсключение "Поврежден UUID собственного одноразового действия.";
    КонецЕсли;
    Разрешение85.Подтверждено = Ложь;
    УчПриходыСчета85.ПроверитьНабор85(СвойНабор85, Источник85, Истина);
    Отказ = Ложь;
#Иначе
    ВызватьИсключение "Этот учебный обработчик не разрешает запись из других контекстов.";
#КонецЕсли
КонецПроцедуры

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

  1. Подготовьте новый собственный стенд и исходные движения вручную ДО установки запрещающих событий.

  2. Установите все полные модули с точными владельцами и связями native callbacks; запустите только thick ordinary.

  3. Просмотрите и сравните свои реальные числа, затем при желании отдельно подтвердите единственную собственную поправку.

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

  1. Открытие проверяет2 реальных документа/3 записи/весь итог1500. Кнопка Список85 открывает только own list с actualDocA и проверенным native ключомAA; Набор85 получает форму конкретного прочитанного собственного набора750.

  2. Иное имя FileCF/версия/режим/пользователь/тип регистратора/чужая запись обязаны отказать ДО открытия формы. Undefined native form и чужой ВладелецФормы честно отказывают.

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

Метаданные, native фабрики и каждый полный readback принадлежат только этому конечному собственному опыту; пустые getter-обертки не используются.

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

  1. Только authoredsource и статические проверки. Actual1С/БД/UI/сеть/проведение/запись/файлы/хранилища0; подготовка и опыт — будущие личные ручные действия исключительно в указанной новой ИБ; backups0.

  2. Это толстый ОБЫЧНЫЙ клиент: ТабличноеПоле/КолонкаТабличногоПоля/Форма, не managed ТаблицаФормы. GetForm526 возвращает Form|Undefined и требует имя формы; формы создаются штатным мастером с точными основными реквизитами. Только реальные native объекты и metadata типы, не Новый РегистрНакопленияЗапись/Новый form-extension.

  3. В установленной HBK type description табличного поля ошибочно говорит сведений, а формы набора — расчета. Exact accumulation page paths, свойства, GetForm526, WriteInForm1344 и form/set event pages указывают регистр накопления. Эти две опечатки не исправляются в источнике справки и не используются для перенаправления владельца.

  4. ОтборСтрок и НастройкаОтбораСтрок — readonly контейнеры; меняются только документированные child fields. RowFilter проверяет вхождение: A принимает A иAA; Список.Отбор.Код85 использует Равно. Native CheckRow/RowData доказывают принятие/данные строки, не момент окончательной перерисовки каждого пикселя и не реальный визуальный итог подвала.

  5. NewRowShowCheck предупреждает после интерактивного завершения ввода новой строки. Своя pending проба создана кодом в памяти: native CheckRow проверяется, но появление штатного предупреждения здесь не объявляется runtime доказанным. Это политика интерфейса, не запрет записи. Пробная строка удаляется только штатным Delete(тотжеactualobject) на успешном локальном этапе; при ошибке нет blind cleanup/rollback.

  6. ОбновлятьПриИзмененииОтбора=False не заменяет проверку полного источника и не обещает универсально отсутствие перечитывания. RefreshRows обновляет отображение, не служит доказательством неизменности БД; отдельно сверяются full query source и full unloaded own memory set.

  7. RecordKey содержит только реальные Регистратор/НомерСтроки; код не использует ошибочный пример CreateRecordKey848 с измерениями. Такой ключ неустойчив после замещения записей; после Save новые исходные ключи не переиспользуются и форма списка может стать устаревшей.

  8. Форма передает конечное разрешение в AdditionalProperties именно собственного actual набора. Общие функции не полагаются на разделяемые client/server переменные. Доставка transient данных через возможное преобразование объекта не гарантируется: если callback их не получил, он отказывает. UUID действия не является криптографическим разрешением или security barrier от чужого кода.

  9. Препроцессор ТолстыйКлиентОбычноеПриложение истинен и в client, и в server части File/thick ordinary. Он не означает универсальное не-сервер. COMMON также доступен Сервер+КлиентОбычноеПриложение; другие server/client-server/external контексты без этого символа получают отказ в callback. Shared auth state не предполагается.

  10. WriteInFormFalse/exception/fresh readback mismatch дают sticky неизвестный исход: одноразовое согласие снимается и повтор/слепое восстановление запрещены. Readback не является proof отсутствия конкуренции; используйте один собственный сеанс без других пользователей/фоновых изменений. Успешная замена касается всего отфильтрованного двухстрочного набора A, не только видимой строки.

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

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

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

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

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