Смета в памяти: выбрать статус и проверить300→150 в таблице, дереве и numeric макете

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

Создадим три статуса сметы в собственной новой учебной конфигурации. Суммы100/150/50 хранятся только в памяти: полная сумма300, после выбора Оплачено —150. Научимся выбирать статус, сравнивать плоскую таблицу и дерево, проверять итог, сбрасывать отбор и отменять выбор без записей в базу.

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

Платформа8.5.1.1343 Windows, толстый клиент, обычное приложение, отдельная файловая учебная база. Код и макет описаны полностью; запуск в1С и компиляция конфигурации здесь не выполнялись.

Подготовка

  1. Задача: научиться отличать metadata-перечисление от таблицы бизнес-данных. Статусы фиксированы в конфигурации, а суммы существуют только в памяти. Мы не создаем и не записываем документы, справочники или регистры.

  2. Вручную создайте НОВУЮ пустую File-базу только C:\1c-labs\OwnEnumerationQuote85_5ef123f4-8b12-4e49-bc26-6d1c8a745d86\IB. UUID здесь — имя своего каталога стенда, НЕ UUID информационной базы. Не копируйте рабочую базу и не используйте путь пользователя к УТ/КА/УНФ/БП. Здесь мы не создаем каталог, базу, CF, пользователей или окна: это инструкция для будущего ручного запуска.

  3. Платформа8.5.1.1343 Windows, толстый клиент, ОбычноеПриложение. Свойства конфигурации: Имя УчебнаяСметаСтатусов85, РежимСовместимости НеИспользовать, режимы запуска УправляемоеПриложениеИОбычноеПриложение, основной режим запуска ОбычноеПриложение. Эта отдельная настройка режимов нужна, чтобы в свойствах общего модуля были доступны флаги клиента обычного и управляемого приложения; ниже включаем только обычный клиент. Единственный пользователь Смета85Ученик с собственной полной ролью, включая право Администрирование для ПолучитьПользователей. Аутентифицируйтесь этим пользователем. Не устанавливайте расширения БД и не подключайте расширения сеанса; автоматический guard проверяет только источникБазаДанных, отсутствие session extensions — отдельное ручное prerequisite.

  4. Перечисления→Добавить→СтатусыСметы85. В этом порядке добавьте Черновик85 (синоним Черновик), Оплачено85 (Оплачено), Отгружено85 (Отгружено). СпособВыбора=ОбоимиСпособами. Значения перечисления создаются ТОЛЬКО в metadata-конфигураторе, а не командой записи из 1С:Предприятия. В новой конфигурации не должно быть других перечислений, документов, справочников, обработок, отчетов и четырех семейств регистров.

  5. ОбщиеМодули→СметаСтатусов85: КлиентОбычноеПриложениеДа, КлиентУправляемоеПриложениеНет, СерверНет, ВнешнееСоединениеНет, ВызовСервераНет, ГлобальныйНет, ПривилегированныйНет. COMMON_MODULE целиком вставьте в его Модуль. Это будущий клиентский in-memory код, не общий server helper.

  6. ОбщиеФормы→Смета85→обычная форма, НЕ управляемая. HUB_MODULE целиком в Модуль. Реквизиты: Статус85 ПеречислениеСсылка.СтатусыСметы85; Таблица85 ТаблицаЗначений; Дерево85 ДеревоЗначений; Вывод85 ТабличныйДокумент; Состояние85 Строка2000. Исходная85/ПринятыйСтатус85/ОжидаемыйВыбор85/КлючВыбора85/Остановка85 — private module variables из кода, не реквизиты формы.

  7. Смета85: ПолеВвода Статус85 Данные=Статус85, тип только собственная EnumRef. ПриИзменении→СтатусПриИзменении85(Элемент), ровно1formal по ordinary event104. ДоступныеЗначения задаются кодом только Черновик/Оплачено. Удалите стандартное изменение данных вне поля выбора; Состояние85 readonly. Не устанавливайте input/table control владельцем подчиненной формы: native extension properties тогда недоступны; owner всегда ЭтаФорма.

  8. Смета85: ТабличноеПоле Таблица85 Данные=Таблица85. Колонки Код85/Статус85/Сумма85: их Имя и Данные совпадают с именем. Сумма85 должна иметь numeric тип из actual table. Картинка85 и Маркер85 — скрытые колонки данных, не строки картинки и не непрочитанный attachment. Native ДанныеКартинки у колонки Статус85 будет Картинка85, итоговый подвал у numeric колонки Сумма85 включается кодом. Удалите команды добавления/изменения/удаления и настройку колонок.

  9. Смета85: ТабличноеПоле Дерево85 Данные=Дерево85. Видимые колонки Код85/Статус85/Сумма85 с соответствующими Имя/Данные, hidden data Картинка85/Маркер85. Дерево показывает группу статуса и вложенную собственную строку; это разные уровни, их суммы нельзя складывать вместе. ИзменятьПорядокСтрокFalse, readonly и запрет изменения состава задаются кодом. Раскройте собственные группы штатным плюс/стрелкой, чтобы увидеть вложенные строки; не выдаем это за проверенный renderer.

  10. Смета85: ПолеТабличногоДокумента Вывод85 Данные=Вывод85, ТолькоПросмотрДа. Кнопки Сбросить85/Вид85/СписокСтатусов85/Выбрать85/Памятка85. Для каждой Нажатие свяжите с одноименной процедурой(Элемент), ровно1actual Кнопка по ordinary event104. Форма ПриОткрытии→ПриОткрытии(), ОбработкаВыбора→ОбработкаВыбора(ЗначениеВыбора,Источник), ровно2безElement. Не вызывайте event-handlers вручную из кода.

  11. У СтатусыСметы85 через ФОРМЫ→Добавить мастер ordinary формы создайте Список85 типа формы списка и Выбор85 типа формы выбора. В каждой системе поручается создать main requisite типа ПеречислениеСписок.СтатусыСметы85; назовите его Список85 и установите ОсновнойРеквизитДа. Не создавайте Новый ПеречислениеСписок — native конструктора нет. ОсновнаяФормаСписка=Список85, ОсновнаяФормаДляВыбора=Выбор85. В каждой LIST_MODULE целиком в Модуль; модули независимы, не зовут друг друга.

  12. В обеих enum формах: ТабличноеПоле Статусы85 Данные=Список85; ровно одна visible колонка ИмяСсылка/ДанныеСсылка. Это actual EnumList control: ТекущаяСтрока имеет native EnumRef, а не Структура и не row index. readonly поле Состояние85 Строка2000. Уберите стандартное изменение enum значений, команды записи и интерактивную настройку отбора. Отбор и НастройкаОтбора являются RO контейнерами; childСсылка меняется допустимыми native методами.

  13. Обе enum формы: ПередОткрытием→ПередОткрытием(Отказ,СтандартнаяОбработка)2, ПриЗакрытии→ПриЗакрытии()0; у Статусы85 Выбор→СтатусыВыбор85(Элемент,ВыбраннаяСтрока,Колонка,СтандартнаяОбработка)4. NativeSelection35 имеет3formals, ordinaryevent104 добавляет actual первыйcontrol. СтандартнаяОбработка=False первой строкой исключает скрытый native выбор. ОповеститьОВыборе вызывается ТОЛЬКО в режиме собственной choice формы. NativeClose/X не посылает выбор; ПриЗакрытии вызывает обычную экспортную business процедуру отмены владельца, не event handler.

  14. СтатусыСметы85→Формы→обычная произвольная Памятка85 (НЕ управляемая). MEMO_MODULE целиком в Модуль. Реквизит Вывод85 ТабличныйДокумент, одно ПолеТабличногоДокумента Вывод85 Данные=Вывод85/ТолькоПросмотрДа. ПередОткрытием2 по модулю. Памятка получает именно текущий проверенный numeric документ своей сметы из actual enum manager GetForm3, не стороннюю форму и не новый фальшивый объект.

  15. СтатусыСметы85→Макеты→Итоги85→ТабличныйДокумент. Ровно3строки×2колонки, без объединений и ячеек внеR1C1:R3C2. Полный copyable six-cell asset CELLS ниже описывает КАЖДУЮ ячейку. Через штатный редактор внесите labels и numeric параметры: Всего85/Количество85/Отбор85, ЗаполнениеПараметр, numericЗначение0, СодержитЗначениеДа, ТипЗначенияЧисло12,0 неотрицательное, ЗащитаДа ВСЕХ6cells. JSON asset — спецификация ручной подготовки, НЕ формат импорта CF. Нельзя подменить numeric0 текстом0 или менять ContainsValue runtime, чтобы скрыть ошибку макета.

  16. В модуль обычного приложения своей CF вставьте APPLICATION_MODULE ПриНачалеРаботыСистемы()0. Обновите конфигурацию своей учебной БД вручную и запустите именно ее в толстом обычном клиенте своим единственным пользователем. Штатный собственный app-start opens ОбщаяФорма.Смета85; не нужно меню или подсистема рабочей конфигурации.

  17. Ручной тест1: при старте две memory views содержат3строки/3группы со своим дочерним листом, исходные100/150/50; numeric report readback поR1C2/R2C2/R3C2 равно300/3/300. Вкладка/пиксели/цвет картинки/подвал относятся к будущей manual UI проверке. Сумма дерева по группам300, по деталям300, НЕ600.

  18. Ручной тест2: БыстрыйВыбор показывает только Черновик/Оплачено. Выберите Оплачено: actual flat1row150, tree1group+1leaf150, numeric readback300/1/150. Черновик дает300/1/100. Сбросить85 возвращает300/3/300. Вид85 переключает дерево/иерархический список без смены3или1actualrows/сумм. Памятка85 показывает те же actual numeric клетки в своем readonly поле.

  19. Ручной тест3: СписокСтатусов85 opens own EnumList с childFilterСсылка InList двух refs и initial positionОплачено. Факт actualcurrent row после показа проверяется выбором собственной enum строки, но renderer/пиксели здесь не запускались. Выбрать85 opens own native choice; выберитеОплачено actual double-click/Enter, не прямой вызов handler. Платформа вызовет Selection4→NotifyChoice1→ownerChoiceProcessing2→новый candidate result.

  20. Ручной тест4: открыть Выбрать85 и закрытьX без выбора. Native Close0 должен очистить только ожидаемый choice handle; предыдущие flat/tree/numeric клетки сохраняются. Foreignsource/foreignref/Отгружено/array/unknownkey/измененный источник/нечисловой макет — отказ. После исключения stickystop не позволяет продолжать текущую форму; ее надо закрыть и исправить подготовку. Последовательные присваивания не являются транзакцией и не обещают rollback/атомарность UI.

Перем Исходная85;
Перем ПринятыйСтатус85;
Перем ОжидаемыйВыбор85;
Перем КлючВыбора85;
Перем Остановка85;

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

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

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

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

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

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

Процедура Сбросить85(Элемент)
    ПроверитьКнопку85(Элемент, "Сбросить85");
    ПрименитьСтатус85(Перечисления.СтатусыСметы85.ПустаяСсылка());
КонецПроцедуры

Процедура Вид85(Элемент)
    ПроверитьКнопку85(Элемент, "Вид85");
    Попытка
        НастроитьПредставление85(Не ЭлементыФормы.Дерево85.Дерево);
        ПроверитьРаботу85();
    Исключение
        Остановка85 = Истина;
        Состояние85 = "СТОП: не удалось проверить переключение дерева";
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

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

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

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

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

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

ОбщиеМодули → СметаСтатусов85 → Модуль

Толстый клиент, обычное приложение; только собственная новая File CF

Процедура ПроверитьСтенд85() Экспорт
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnEnumerationQuote85_5ef123f4-8b12-4e49-bc26-6d1c8a745d86\IB"";" Тогда
        ВызватьИсключение "Откройте только собственную учебную File-базу сметы";
    КонецЕсли;
    Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или Метаданные.Перечисления.Количество() <> 1 Или Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Обработки.Количество() <> 0 Или Метаданные.Отчеты.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ОбщиеФормы.Количество() <> 1 Или Метаданные.ОбщиеФормы.Найти("Смета85") = Неопределено Или Метаданные.ОбщиеМодули.Количество() <> 1 Или Метаданные.ОбщиеМодули.Найти("СметаСтатусов85") = Неопределено Тогда
        ВызватьИсключение "Метаданные не соответствуют новой пустой учебной конфигурации";
    КонецЕсли;
    СвоеПеречисление = Метаданные.Перечисления.Найти("СтатусыСметы85");
    Если СвоеПеречисление = Неопределено Или СвоеПеречисление.СпособВыбора <> Метаданные.СвойстваОбъектов.СпособВыбора.ОбоимиСпособами
        Или СвоеПеречисление.ЗначенияПеречисления.Количество() <> 3 Или СвоеПеречисление.Формы.Количество() <> 3
        Или СвоеПеречисление.Формы.Найти("Список85") = Неопределено Или СвоеПеречисление.Формы.Найти("Выбор85") = Неопределено
        Или СвоеПеречисление.Формы.Найти("Памятка85") = Неопределено Или СвоеПеречисление.Макеты.Количество() <> 1
        Или СвоеПеречисление.Макеты.Найти("Итоги85") = Неопределено
        Или СвоеПеречисление.Макеты.Найти("Итоги85").ТипМакета <> Метаданные.СвойстваОбъектов.ТипМакета.ТабличныйДокумент Тогда
        ВызватьИсключение "Подготовьте три собственных статуса, три формы и один compiled макет";
    КонецЕсли;
    Имена = Новый Массив;
    Имена.Добавить("Черновик85");
    Имена.Добавить("Оплачено85");
    Имена.Добавить("Отгружено85");
    Для Номер = 0 По 2 Цикл
        Если СвоеПеречисление.ЗначенияПеречисления.Получить(Номер).Имя <> Имена[Номер] Тогда
            ВызватьИсключение "Имена или порядок собственных metadata-значений изменены";
        КонецЕсли;
    КонецЦикла;
    Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0 Тогда
        ВызватьИсключение "Не устанавливайте расширения в собственный стенд";
    КонецЕсли;
    Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если Пользователь = Неопределено Или Пользователь.Имя <> "Смета85Ученик" Или Пользователи.Количество() <> 1
        Или Пользователи[0].УникальныйИдентификатор <> Пользователь.УникальныйИдентификатор Тогда
        ВызватьИсключение "Нужен единственный собственный учебный пользователь с Администрированием";
    КонецЕсли;
КонецПроцедуры

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

Функция ДоступныеСтатусы85() Экспорт
    Значения = Новый СписокЗначений;
    Значения.Добавить(Перечисления.СтатусыСметы85.Черновик85);
    Значения.Добавить(Перечисления.СтатусыСметы85.Оплачено85);
    Возврат Значения;
КонецФункции

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

Функция ИсходнаяСмета85() Экспорт
    ПроверитьСтенд85();
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Код85", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(1)));
    Таблица.Колонки.Добавить("Статус85", Новый ОписаниеТипов("ПеречислениеСсылка.СтатусыСметы85"));
    Таблица.Колонки.Добавить("Сумма85", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(12, 0, ДопустимыйЗнак.Неотрицательный)));
    Таблица.Колонки.Добавить("Картинка85", Новый ОписаниеТипов("Картинка"));
    Таблица.Колонки.Добавить("Маркер85", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(36)));
    Для Номер = 0 По 2 Цикл
        СтрокаСметы = Таблица.Добавить();
        СтрокаСметы.Код85 = Сред("ABC", Номер + 1, 1);
        СтрокаСметы.Статус85 = Перечисления.СтатусыСметы85.Получить(Номер);
        СтрокаСметы.Сумма85 = ?(Номер = 0, 100, ?(Номер = 1, 150, 50));
        СтрокаСметы.Картинка85 = БиблиотекаКартинок.Перечисление;
        СтрокаСметы.Маркер85 = "5ef123f4-8b12-4e49-bc26-6d1c8a745d86";
    КонецЦикла;
    ПроверитьИсходную85(Таблица);
    Возврат Таблица;
КонецФункции

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

Процедура ПроверитьИсходную85(Таблица) Экспорт
    Если ТипЗнч(Таблица) <> Тип("ТаблицаЗначений") Или Таблица.Количество() <> 3 Тогда
        ВызватьИсключение "Исходная смета должна содержать ровно три собственные строки";
    КонецЕсли;
    ПроверитьКолонки85(Таблица.Колонки);
    Для Номер = 0 По 2 Цикл
        СтрокаСметы = Таблица.Получить(Номер);
        Если СтрокаСметы.Код85 <> Сред("ABC", Номер + 1, 1) Или ТипЗнч(СтрокаСметы.Статус85) <> Тип("ПеречислениеСсылка.СтатусыСметы85")
            Или СтрокаСметы.Статус85 <> Перечисления.СтатусыСметы85.Получить(Номер)
            Или ТипЗнч(СтрокаСметы.Сумма85) <> Тип("Число") Или СтрокаСметы.Сумма85 <> ?(Номер = 0, 100, ?(Номер = 1, 150, 50))
            Или ТипЗнч(СтрокаСметы.Картинка85) <> Тип("Картинка") Или СтрокаСметы.Картинка85 <> БиблиотекаКартинок.Перечисление
            Или СтрокаСметы.Маркер85 <> "5ef123f4-8b12-4e49-bc26-6d1c8a745d86" Тогда
            ВызватьИсключение "Исходная строка, статус, сумма, картинка или маркер изменены";
        КонецЕсли;
    КонецЦикла;
    Если Таблица.Итог("Сумма85") <> 300 Тогда
        ВызватьИсключение "Полная исходная сумма должна быть 300";
    КонецЕсли;
КонецПроцедуры

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

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

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

Функция Итоги85(Макет, Числа) Экспорт
    Если ТипЗнч(Макет) <> Тип("ТабличныйДокумент") Или Макет.ВысотаТаблицы <> 3 Или Макет.ШиринаТаблицы <> 2 Тогда
        ВызватьИсключение "Подготовьте собственный compiled макет 3x2";
    КонецЕсли;
    Имена = Новый Массив;
    Имена.Добавить("Всего85"); Имена.Добавить("Количество85"); Имена.Добавить("Отбор85");
    Подписи = Новый Массив;
    Подписи.Добавить("Полная исходная сумма"); Подписи.Добавить("Видимых строк"); Подписи.Добавить("Сумма выбранного статуса");
    Для Номер = 1 По 3 Цикл
        Подпись = Макет.Область(Номер, 1, Номер, 1);
        Ячейка = Макет.Область(Номер, 2, Номер, 2);
        Если Подпись.Текст <> Подписи[Номер - 1] Или Не Подпись.Защита
            Или Ячейка.Заполнение <> ТипЗаполненияОбластиТабличногоДокумента.Параметр Или Ячейка.Параметр <> Имена[Номер - 1]
            Или Не Ячейка.Защита Или Не Ячейка.СодержитЗначение Или ТипЗнч(Ячейка.Значение) <> Тип("Число") Или Ячейка.Значение <> 0
            Или Ячейка.ТипЗначения.Типы().Количество() <> 1 Или Не Ячейка.ТипЗначения.СодержитТип(Тип("Число")) Тогда
            ВызватьИсключение "Compiled ячейка должна быть собственным защищенным numeric параметром, не строкой 0";
        КонецЕсли;
    КонецЦикла;
    Область = Макет.ПолучитьОбласть("R1C1:R3C2");
    Область.Параметры.Заполнить(Числа);
    Документ = Новый ТабличныйДокумент;
    Документ.Вывести(Область);
    Документ.ТолькоПросмотр = Истина;
    ПроверитьИтоги85(Документ, Числа);
    Возврат Документ;
КонецФункции

Процедура ПроверитьИтоги85(Документ, Числа) Экспорт
    Если ТипЗнч(Документ) <> Тип("ТабличныйДокумент") Или Документ.ВысотаТаблицы <> 3 Или Документ.ШиринаТаблицы <> 2 Или Не Документ.ТолькоПросмотр Тогда
        ВызватьИсключение "Фактический результат должен быть readonly документом 3x2";
    КонецЕсли;
    Значения = Новый Массив;
    Значения.Добавить(Числа.Всего85); Значения.Добавить(Числа.Количество85); Значения.Добавить(Числа.Отбор85);
    Для Номер = 1 По 3 Цикл
        Ячейка = Документ.Область(Номер, 2, Номер, 2);
        Если Не Документ.Область(Номер, 1, Номер, 1).Защита Или Не Ячейка.Защита Или Не Ячейка.СодержитЗначение
            Или Ячейка.ТипЗначения.Типы().Количество() <> 1 Или Не Ячейка.ТипЗначения.СодержитТип(Тип("Число"))
            Или ТипЗнч(Ячейка.Значение) <> Тип("Число") Или Ячейка.Значение <> Значения[Номер - 1] Тогда
            ВызватьИсключение "Фактическая numeric ячейка результата не равна рассчитанной сумме или количеству";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры
Полная собственная форма сметы

ОбщиеФормы → Смета85 → Модуль обычной формы

Толстый клиент, обычное приложение; только собственная новая File CF

Перем Исходная85;
Перем ПринятыйСтатус85;
Перем ОжидаемыйВыбор85;
Перем КлючВыбора85;
Перем Остановка85;

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

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

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

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

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

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

Процедура Сбросить85(Элемент)
    ПроверитьКнопку85(Элемент, "Сбросить85");
    ПрименитьСтатус85(Перечисления.СтатусыСметы85.ПустаяСсылка());
КонецПроцедуры

Процедура Вид85(Элемент)
    ПроверитьКнопку85(Элемент, "Вид85");
    Попытка
        НастроитьПредставление85(Не ЭлементыФормы.Дерево85.Дерево);
        ПроверитьРаботу85();
    Исключение
        Остановка85 = Истина;
        Состояние85 = "СТОП: не удалось проверить переключение дерева";
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

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

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

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

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

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

Перечисления → СтатусыСметы85 → Формы → Список85 → Модуль

Толстый клиент, обычное приложение; только собственная новая File CF

Перем Готово85;
Перем Выбор85;
Перем СвойКлюч85;

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

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

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

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

Процедура ПриЗакрытии()
    Если Готово85 = Истина И Выбор85 И ТипЗнч(ВладелецФормы) = Тип("Форма") И ВладелецФормы.Открыта() Тогда
        ВладелецФормы.ОтменитьВыбор85(ЭтаФорма);
    КонецЕсли;
КонецПроцедуры
Полная собственная ordinary enum choice форма

Перечисления → СтатусыСметы85 → Формы → Выбор85 → Модуль

Толстый клиент, обычное приложение; только собственная новая File CF

Перем Готово85;
Перем Выбор85;
Перем СвойКлюч85;

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

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

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

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

Процедура ПриЗакрытии()
    Если Готово85 = Истина И Выбор85 И ТипЗнч(ВладелецФормы) = Тип("Форма") И ВладелецФормы.Открыта() Тогда
        ВладелецФормы.ОтменитьВыбор85(ЭтаФорма);
    КонецЕсли;
КонецПроцедуры
Полная собственная ordinary enum памятка

Перечисления → СтатусыСметы85 → Формы → Памятка85 → Модуль

Толстый клиент, обычное приложение; только собственная новая File CF

Перем Готово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.ТолькоПросмотр Тогда
        ВызватьИсключение "Памятка не отображает собственный readonly numeric документ";
    КонецЕсли;
    СметаСтатусов85.ПроверитьИтоги85(ЭлементыФормы.Вывод85.Значение, СвоиЧисла85);
    Готово85 = Истина;
КонецПроцедуры

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

Конфигурация → Открыть модуль обычного приложения

Толстый клиент, обычное приложение; только собственная новая File CF

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

Перечисления → СтатусыСметы85 → Макеты → Итоги85 → штатный табличный редактор

Собственный макет3x2. JSON описывает ручную подготовку ячеек, НЕ является форматом импорта1С и НЕ исполняется какBSL

[
  {
    "cell": "R1C1",
    "text": "Полная исходная сумма",
    "protection": true
  },
  {
    "cell": "R2C1",
    "text": "Видимых строк",
    "protection": true
  },
  {
    "cell": "R3C1",
    "text": "Сумма выбранного статуса",
    "protection": true
  },
  {
    "cell": "R1C2",
    "fill": "Параметр",
    "parameter": "Всего85",
    "containsValue": true,
    "valueType": "Число12,0 неотрицательное",
    "value": 0,
    "protection": true,
    "format": "ЧГ=0;ЧДЦ=0"
  },
  {
    "cell": "R2C2",
    "fill": "Параметр",
    "parameter": "Количество85",
    "containsValue": true,
    "valueType": "Число12,0 неотрицательное",
    "value": 0,
    "protection": true,
    "format": "ЧГ=0;ЧДЦ=0"
  },
  {
    "cell": "R3C2",
    "fill": "Параметр",
    "parameter": "Отбор85",
    "containsValue": true,
    "valueType": "Число12,0 неотрицательное",
    "value": 0,
    "protection": true,
    "format": "ЧГ=0;ЧДЦ=0"
  }
]

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

  1. Enum refs приходят от своей metadata-фабрики Перечисления.СтатусыСметы85. Их нельзя создать записью строки в БД или NewEnumList.

  2. Native EnumList создается основным реквизитом своей enum list/choice формы. GetListForm/GetChoiceForm получают настоящий системный объект формы; затем проверяются actual owner, ключ, typed main requisite и контрольное поле.

  3. 100/150/50 — суммы трех собственных строк в памяти. EmptyRef означает Все, а выбор actual Оплачено отбирает только150. Исходная таблица читается до и после каждого формирования и не меняется.

  4. Сначала создаются и полностью проверяются новые flat/tree/TabDoc candidates. После присваиваний перечитываются actual form attributes/control values и native numeric cells. При ошибке возможна частичная UI замена, sticky stop запрещает повторную работу.

  5. Список enum фильтруется native childСсылка InList двух actual refs; Set(value,use) имеет только2slots и сбрасываетComparison вEqual, потомуInList устанавливается затем явно и перечитывается.

  6. Input quick dropdown и немодальный собственный ChoiceForm — два реальных маршрута. Платформа вызывает control/form events; код сам event handlers не вызывает. Форма-источник проверяется поactual instance+native FormOwner+ключ, а не только имени.

  7. Cancel/Close не выбирает значение и не пересчитывает смету. Экспортный business метод отмены только сверяет сохраненный результат и очищает ожидаемый handle. Reset явно принимает собственный EmptyRef и формирует300 заново.

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

  1. В начале и после Reset numeric output300/3/300; собственное Оплачено300/1/150; Черновик300/1/100.

  2. Сумма roots300 и сумма leafs300 — альтернативные уровни, не общий итог600. Изображение и footer фактически не рендерились.

  3. Foreign refs/source, array result, измененные rows/schema/owner/filters, incorrect numeric layout вызывают отказ. Здесь выполнены только source/static tests, manual runtime protocol впереди.

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

Будущий ручной результат: полная смета300/3/300, выборОплачено300/1/150, reset300/3/300; cancel сохраняет предыдущие actual numeric cells. Actual1C/CFcompiler/DB/UI/network/OS0, RuntimeVerifiedFalse, backups0.

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

  1. Три формы GetForm/GetListForm/GetChoiceForm доступны только толстому клиенту. Это не Taxi managed/mobile/web пример, не server business helper и не переносимая UI автоматизация.

  2. Форма.ВладелецФормы — точное ordinary native свойство FormOwner366; свойства Владелец у Форма здесь нет. Входные контролы не используются владельцем, поскольку их ordinary extension properties при таком owner недоступны.

  3. БыстрыйВыбор действует только при metadataСпособВыбораОбоимиСпособами. ДоступныеЗначения/недоступность настройки отбора — UI политика, не права доступа и не доказательство безопасности.

  4. Native EnumList.Отбор содержит толькоСсылка и допускает лишьРавно/НеРавно/ВСписке/НеВСписке. Чужой comparison делает список пустым. RO containers не заменяются.

  5. Native type page Value tree table box extension ошибочно пишет ПолеВвода в prose. Мы не выводим из этой строки factory: используем actual native ТабличноеПоле, привязанное к собственному ДеревоЗначений, и exact Tree1770/ChangeRowOrder2434/columnPicture1426 contracts. Если actual extension недоступно, явный отказ; runtime не проверен.

  6. NewRowShowCheck и managed FormItems не включены: перечисление не редактируется вводом новых бизнес-строк, а ordinary Controls не является managed FormItems. Здесь ровно23целевыхAPI безpadding.

  7. Readonly TabDoc требует Защита всех6compiledcells. Не переустанавливаем СодержитЗначение, не превращаем текст0 вчисло и не выдаем5staticcheckers за nativecompiler/runtime/renderproof.

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

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

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

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

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