Содержит свойства и методы формы, которые применимы для формы обработки.
Полное описание, параметры и ограничения
Расширение формы клиентского приложения для обработки (Client application form extension for processings)
Расширение формы клиентского приложения для обработки (Client application form extension for processings)
Доступен, начиная с версии 8.3.19.
Методы:
ПолучитьНавигационнуюСсылкуОбработки (GetDataProcessorURL)
Описание:
Содержит свойства и методы формы, которые применимы для формы обработки.
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.
Использование в версии:
Доступен, начиная с версии 8.3.19.
Методическая информация
Практические примеры
Обработка и три настоящих представления: общийsource1000, Contains750/250 и дерево750+250
Создать реальный processingObject, native server-converted ValueTable/TP/tree, показать собственную навигационную ссылку и отличить UI-фильтр от полного источника. Изменение TP требует явной переустановки фильтра.
Где и как запускать
Полный managed module Обработка.Калькулятор85.Управляемая85; server-only conversions/native table client reads. FileCF/thick-managed Windows.
Подготовка
Ничего не запускайте в рабочей базе. Этот код только авторский учебный материал, без runtime-проверки. Вручную создайте НОВУЮ пустую файловую ИБ ровно C:\1c-labs\OwnProcessingObjectViews85_a9b660d1-619b-41f7-a2cd-082bdc4ba164\IB; это конкретная собственная File-ИБ, не UUID чужой базы. Конфигурация УчебныеПредставления85, платформа8.5.1.1343, РежимСовместимостиНеИспользовать. Редактор: Сервис → Параметры → Общие → Редактирование конфигурации для режима запуска = оба приложения. Это настройка редактора, не SupportedRunModes. ОсновнойРежимЗапускаОбычноеПриложение. Для managed опыта закройте свой ordinary клиент, только в ЭТОЙ учебной CF измените свойство конфигурации ОсновнойРежимЗапуска на УправляемоеПриложение, обновите только свою конфигурацию базы данных, закройте Конфигуратор и откройте эту собственную ИБ толстым Windows-клиентом, интерфейсТакси. Для возврата повторите эти же ручные шаги с ОсновнойРежимЗапускаОбычноеПриложение. Не переключайте рабочие конфигурации и не угадывайте параметры командной строки.
Ровно один ПланСчетов Коэффициенты85, одна обработка Калькулятор85, один общий модуль ПредставленияИсточник85 и одна роль Представления85. Других прикладных объектов, регистров, разделителей, расширений, подписок, заданий нет. ПланСчетов используется для изучения настоящей ОБЩЕЙ managed формы объекта: это не бухгалтерские проводки и не рекомендация хранить тарифы в рабочем плане счетов. Generic «Расширение объектов» НЕ подменять специальными расширениями справочника/ПВХ/документа или ordinary формой.
ПланСчетов: МаксКоличествоСубконто0, ни одного вида/признака субконто, без дополнительных табличных частей. ДлинаКода3, ДлинаНаименования40, контроль уникальностиДа. Два реквизита: Маркер85 только Строка36; Коэффициент85 только Число5,2. ДО установки запрета OBJECT вручную сохраните ровно два собственных верхних непредопределённых активных незабалансовых счета без родителя: F85/Полный/1 и H85/Половина/0.5. Маркер у обоих a9b660d1-619b-41f7-a2cd-082bdc4ba164; ПометкаУдаленияFalse. Порядок/ВерсияДанных читаются фактически, не задаются выдуманными значениями. Никаких иных счетов, движений и бухгалтерских регистров.
После ручной fixture полный OBJECT вставьте в ПланСчетов → Коэффициенты85 → Модуль объекта: native ПередЗаписью1 всегда ОтказTrue, без клиентских помощников и во всех его native контекстах. Это широкая дополнительная защита, а не доказательство отката. Пользователь только Представления85Ученик, роль Представления85: чтение/просмотр/добавление/изменение собственного плана, своей обработки и АктивныеПользователи для одного подключения. Без RLS, привилегированных модулей и админсервисов. Закройте Конфигуратор/предыдущий клиент, оставьте одно собственное подключение.
ОбщийМодуль ПредставленияИсточник85: ГлобальныйНет, СерверДа, ВызовСервераДа, КлиентОбычноеПриложениеНет, КлиентУправляемоеПриложениеНет, ВнешнееСоединениеНет, ПривилегированныйНет, повторное использованиеНеИспользовать. Полный COMMON вставьте целиком. Клиент получает от Пакет85 только Structure/Array с собственными ссылками и scalar полями; Смета85 возвращает native ТаблицаЗначений ТОЛЬКО серверному коду managed формы, клиент ее не вызывает и не переносит native objects/metadata/query/managers через RPC. ПроверитьСмету85 используется только внутри серверного кода managed формы. Ordinary primary/табличная часть проверяются ЛОКАЛЬНО; через CommonServerCall они не передаются.
Калькулятор85: Маркер85 Строка36, Коэффициент85 Число5,2; табличная часть Строки85, ровно Код85 Строка10, Количество85 Число5,0, Цена85 Число8,2, Сумма85 Число10,2. Это только несохранённый экземпляр обработки, не документ/регистр; функции Записать у обработки нет и не изобретается. Конструктором подготовьте две реальные формы Обычная85 и Управляемая85; основные формы указывайте явно в вызовах по имени, не переключайте чужую базу.
ПланСчетов → Коэффициенты85 → Формы → Счет85: реальная managed основная форма объекта. Основной реквизит Объект только ПланСчетовОбъект.Коэффициенты85; поля объекта только просмотр. Добавьте Согласие85 Булево с начальнымFalse и собственный флажок, Статус85 Строка1000 readonly; команда ПроверитьЗапрет85. Полный ACCOUNT: ПриСозданииНаСервере2, ПриОткрытии1, native ВыборЗначения1, ПередЗаписью2; действие своей команды1 → ПроверитьЗапрет85. Штатная команда Выбрать закрывает форму именно в native РежимВыбора; не вызывайте event вручную. Поля/основной реквизит создаёт реальный конструктор формы. Родитель — managed форма обработки, не её поле ввода.
Обработка → Калькулятор85 → Управляемая85: основной Объект только ОбработкаОбъект.Калькулятор85; Таблица85 только ТаблицаЗначений с колонками Код85 Строка10/Количество85 Число5,0/Цена85 Число8,2/Сумма85 Число10,2; Дерево85 только ДеревоЗначений с Код85 Строка10/Сумма85 Число10,2; Статус85 Строка1000 readonly. ТаблицаФормы Таблица85: ПутьКДаннымТаблица85; Строки85: ПутьКДаннымОбъект.Строки85; Дерево85: ПутьКДаннымДерево85. Все readonly для ручного редактирования, visibleTrue. Команды ВыбратьСчет85/ОтборА85/ОтборБ85/Все85/Перенести85/ПроверитьСтроки85 и их реальные кнопки. Вставьте PROCESSING целиком: ПриСозданииНаСервере2/ПриОткрытии1/ОбработкаВыбора2, каждое действие команды1 в одноимённую процедуру. Частные &НаКлиенте Перем не являются неизвестными динамическими реквизитами формы.
Обработка → Калькулятор85 → Обычная85: primary Калькулятор85 только ОбработкаОбъект.Калькулятор85, Статус85 Строка1000 readonly; кнопки Полный85/Половина85. Список сохраняемых значений пустой, Восстанавливать настройки автоматическиНет, без автоматического сохранения/пользовательского хранилища. ORDINARY целиком: ПриОткрытии0; обе кнопки.Нажатие1, ПередСохранениемЗначений1 alwayscancel. Первичная настройка вызывается настоящей own экспортной Подготовить85 до Open, не fake ПриОткрытии. RestoreValuesFalse присваивается и читается до native Open в ORDINARY_APP; True сам по себе не доказывал бы восстановления без собственного реально сохранённого набора UseOnOpen. В этом уроке сохранение настроек не производится вообще.
MANAGED_APP в Модуль управляемого приложения; ORDINARY_APP в Модуль обычного приложения, native ПриНачалеРаботыСистемы0. Оба startup входят в CF, но опыты запускайте раздельно, одним клиентом в соответствующем режиме. В managed форме сначала три настоящих выбора F/H/F дают1000/500/1000. Для проверки отказа записи откройте ещё форму своего счета в свежем сеансе/новом пульте, вручную отметьте согласиеFalse→True и нажмите ПроверитьЗапрет85: после nativeFalse/exception дочерняя и родительская формы остаютсяСТОП, не продолжайте F/H/F и не делайте автоматический повтор.
В managed таблице/табличной части кнопки отборA/B/Все дают ожидаемые ВИДИМЫЕ суммы750/250/1000. Это Contains: A85 и A850 оба соответствуют A. Видимость проверяйте глазами и через настоящую текущую строку каждой таблицы, не поддельным native aggregate. Полный source1000/три строки и деревоВСЕ1000/A750/B250 сверяются отдельно на сервере. При отборA Перенести85 меняет только unsaved TP.Код второй строки A850→B850, затем переустанавливает TPfilterA: вТП виден толькоA85=250, вТаблица85 по-прежнему750. Повтор Перенести85 возвращает собственный код и переустанавливаетfilterA; это явная отдельная команда, НЕ автоматический rollback после ошибки.
Для ПроверитьСтроки85 вручную выберите видимую строку в каждой из трёх таблиц, затем нажмите собственную команду. Actual ID получают native элементы данных формы, это не индекс. ДанныеСтроки может вернутьUndefined; сообщение предлагает ручную выборку/повтор только readonly проверки, не inject fake result. Строки не изменяются через returned data: generic older extension prose о «копии структуры» не подменяет actual8.5 RowData/CurrentData return contracts. Навигационные ссылки GetObjectURL0/GetDataProcessorURL0 только читаются/показываются; аргументы representation/external data не передаются, хранилище внешних данных не записывается.
&НаКлиенте
Перем Паспорт85;
&НаКлиенте
Перем Остановлен85;
&НаКлиенте
Перем Этап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");
Для Каждого Код Из СтрРазделить("A,B", ",") Цикл
Группа = Корень.Строки.Добавить();
Группа.Код85 = Код;
Группа.Сумма85 = 0;
Для Каждого Р Из Смета Цикл
Если Лев(Р.Код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 <> 1 Тогда
ВызватьИсключение "Не собственные реальные данные формы";
КонецЕсли;
Если Таблица.Колонки.Количество() <> 4 Или Дерево.Колонки.Количество() <> 2 Тогда
ВызватьИсключение "Не полный состав колонок";
КонецЕсли;
ПредставленияИсточник85.ПроверитьСмету85(Таблица);
ПредставленияИсточник85.ПроверитьСмету85(СвойОбъект.Строки85, Перенос);
Если Дерево.Строки.Количество() <> 1 Тогда
ВызватьИсключение "Не единственный корень";
КонецЕсли;
Корень = Дерево.Строки[0];
Если Корень.Код85 <> "ВСЕ" Или Корень.Сумма85 <> Таблица.Итог("Сумма85") Или Корень.Строки.Количество() <> 2 Тогда
ВызватьИсключение "Не полный корень";
КонецЕсли;
Индекс = 0;
ОбщаяСумма = 0;
Посещенные = Новый Массив;
Для Каждого Группа Из Корень.Строки Цикл
Если Группа.Код85 <> ?(Индекс = 0, "A", "B") Или Группа.Строки.Количество() <> ?(Индекс = 0, 2, 1) Тогда
ВызватьИсключение "Не полные группы";
КонецЕсли;
СуммаГруппы = 0;
Для Каждого Лист Из Группа.Строки Цикл
ИсходнаяСтрока = Таблица.Найти(Лист.Код85, "Код85");
Если ИсходнаяСтрока = Неопределено Или Лев(Лист.Код85, 1) <> Группа.Код85 Или Посещенные.Найти(Лист.Код85) <> Неопределено Или Лист.Сумма85 <> ИсходнаяСтрока.Сумма85 Или Лист.Строки.Количество() <> 0 Тогда
ВызватьИсключение "Не собственный конечный лист";
КонецЕсли;
Посещенные.Добавить(Лист.Код85);
СуммаГруппы = СуммаГруппы + Лист.Сумма85;
КонецЦикла;
Если Группа.Сумма85 <> СуммаГруппы Или СуммаГруппы <> ?(Индекс = 0, 750, 250) Тогда
ВызватьИсключение "Дерево не соответствует actual source";
КонецЕсли;
ОбщаяСумма = ОбщаяСумма + СуммаГруппы;
Индекс = Индекс + 1;
КонецЦикла;
Если Посещенные.Количество() <> 3 Или ОбщаяСумма <> 1000 Или Таблица.Итог("Сумма85") <> 1000 Тогда
ВызватьИсключение "Не независимые суммы 1000";
КонецЕсли;
Возврат Пакет;
КонецФункции
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если Остановлен85 <> Неопределено Тогда
Отказ = Истина;
ВызватьИсключение "Повторное открытие не сбрасывает СТОП";
КонецЕсли;
Остановлен85 = Истина;
Паспорт85 = ПроверитьДанные85(Ложь);
Для Каждого Имя Из СтрРазделить("Таблица85,Строки85,Дерево85", ",") Цикл
Элемент = Элементы.Найти(Имя);
Если Элемент = Неопределено Или ТипЗнч(Элемент) <> Тип("ТаблицаФормы") Или Элемент.Имя <> Имя Тогда
ВызватьИсключение "Нет своей compiled таблицы";
КонецЕсли;
КонецЦикла;
Элементы.Таблица85.ОтборСтрок = Неопределено;
Элементы.Строки85.ОтборСтрок = Неопределено;
Статус85 = ЭтаФорма.ПолучитьНавигационнуюСсылкуОбработки();
Если ТипЗнч(Статус85) <> Тип("Строка") Или Статус85 = "" Тогда
ВызватьИсключение "Нет native ссылки собственной обработки";
КонецЕсли;
Перенос85 = Ложь;
Фильтр85 = "";
Этап85 = 0;
Остановлен85 = Ложь;
КонецПроцедуры
&НаКлиенте
Процедура Остановить85() Экспорт
Остановлен85 = Истина;
Статус85 = "СТОП: опыт записи в дочерней форме. Продолжение и повтор запрещены.";
КонецПроцедуры
&НаКлиенте
Процедура ВыбратьСчет85(Команда)
Если Команда <> Команды.ВыбратьСчет85 Или Остановлен85 <> Ложь Или Этап85 > 2 Тогда
ВызватьИсключение "Не собственная команда или завершённый маршрут";
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Паспорт85, ПроверитьДанные85(Перенос85));
Нужный = Паспорт85.Счета[?(Этап85 = 1, 1, 0)].Ссылка;
Параметры = Новый Структура("Ключ,РежимВыбора,ПараметрыВыбора", Нужный, Истина, Новый ФиксированнаяСтруктура(Новый Структура("Маркер85", Паспорт85.Маркер)));
СвояФорма85 = ПолучитьФорму("ПланСчетов.Коэффициенты85.Форма.Счет85", Параметры, ЭтаФорма, Истина);
Если СвояФорма85 = Неопределено Или ТипЗнч(СвояФорма85) <> Тип("ФормаКлиентскогоПриложения") Или СвояФорма85.ВладелецФормы <> ЭтаФорма Тогда
ВызватьИсключение "Не реальная собственная managed форма счета";
КонецЕсли;
СвояФорма85.Открыть();
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если Остановлен85 <> Ложь Или ИсточникВыбора <> СвояФорма85 Или ТипЗнч(ВыбранноеЗначение) <> Тип("ПланСчетовСсылка.Коэффициенты85") Или Этап85 > 2 Тогда
ВызватьИсключение "Не настоящий выбор собственной ссылки";
КонецЕсли;
Нужный = Паспорт85.Счета[?(Этап85 = 1, 1, 0)];
Если ВыбранноеЗначение <> Нужный.Ссылка Тогда
ВызватьИсключение "Выбран не ожидаемый собственный счет";
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Паспорт85, ПроверитьДанные85(Перенос85));
Сумма = 0;
Для Каждого Р Из Таблица85 Цикл
Сумма = Сумма + Р.Количество85 * Р.Цена85;
КонецЦикла;
Если Сумма <> 1000 Или Сумма * Нужный.Коэффициент85 <> ?(Этап85 = 1, 500, 1000) Тогда
ВызватьИсключение "Не результат собственного источника";
КонецЕсли;
Статус85 = "Реальный выбор " + Нужный.Код + ": " + Строка(Сумма * Нужный.Коэффициент85);
Этап85 = Этап85 + 1;
КонецПроцедуры
&НаКлиенте
Процедура ОтборА85(Команда)
Если Команда <> Команды.ОтборА85 Тогда
ВызватьИсключение "Чужая команда";
КонецЕсли;
ПрименитьОтбор85("A");
КонецПроцедуры
&НаКлиенте
Процедура ОтборБ85(Команда)
Если Команда <> Команды.ОтборБ85 Тогда
ВызватьИсключение "Чужая команда";
КонецЕсли;
ПрименитьОтбор85("B");
КонецПроцедуры
&НаКлиенте
Процедура Все85(Команда)
Если Команда <> Команды.Все85 Тогда
ВызватьИсключение "Чужая команда";
КонецЕсли;
ПрименитьОтбор85("");
КонецПроцедуры
&НаКлиенте
Процедура ПрименитьОтбор85(Код)
Если Остановлен85 <> Ложь Или (Код <> "A" И Код <> "B" И Код <> "") Тогда
ВызватьИсключение "Не собственный доступный отбор";
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Паспорт85, ПроверитьДанные85(Перенос85));
Остановлен85 = Истина;
Попытка
Отбор = ?(Код = "", Неопределено, Новый ФиксированнаяСтруктура(Новый Структура("Код85", Код)));
Элементы.Таблица85.ОтборСтрок = Отбор;
Элементы.Строки85.ОтборСтрок = Отбор;
Если Код = "" Тогда
Если Элементы.Таблица85.ОтборСтрок <> Неопределено Или Элементы.Строки85.ОтборСтрок <> Неопределено Тогда
ВызватьИсключение "Отбор не снят";
КонецЕсли;
Иначе
Если Элементы.Таблица85.ОтборСтрок.Код85 <> Код Или Элементы.Строки85.ОтборСтрок.Код85 <> Код Тогда
ВызватьИсключение "Отбор не установлен";
КонецЕсли;
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Паспорт85, ПроверитьДанные85(Перенос85));
Фильтр85 = Код;
Статус85 = "Полный source1000 сохранён. Видимые строки проверяйте вручную: A85+A850=750; B85=250; ВСЕ=1000.";
Остановлен85 = Ложь;
Исключение
Остановлен85 = Истина;
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура Перенести85(Команда)
Если Команда <> Команды.Перенести85 Или Остановлен85 <> Ложь Или Фильтр85 <> "A" Тогда
ВызватьИсключение "Сначала примените собственный отбор A";
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Паспорт85, ПроверитьДанные85(Перенос85));
Остановлен85 = Истина;
Попытка
Объект.Строки85[1].Код85 = ?(Перенос85, "A850", "B850");
Перенос85 = Не Перенос85;
Элементы.Строки85.ОтборСтрок = Новый ФиксированнаяСтруктура(Новый Структура("Код85", "A"));
ПредставленияИсточник85.Сравнить85(Паспорт85, ПроверитьДанные85(Перенос85));
Статус85 = ?(Перенос85, "ТП содержит B850: после переустановки A виден только A85=250.", "ТП снова A850: после переустановки A видны A85+A850=750.");
Остановлен85 = Ложь;
Исключение
Остановлен85 = Истина;
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСтроки85(Команда)
Если Команда <> Команды.ПроверитьСтроки85 Или Остановлен85 <> Ложь Тогда
ВызватьИсключение "Не собственная доступная проверка";
КонецЕсли;
Для Каждого Имя Из СтрРазделить("Таблица85,Строки85,Дерево85", ",") Цикл
Поле = Элементы.Найти(Имя);
Идентификатор = Поле.ТекущаяСтрока;
Данные = Поле.ДанныеСтроки(Идентификатор);
Если Данные = Неопределено Тогда
ВызватьИсключение "В каждой из трёх таблиц вручную выберите видимую строку; затем повторите только эту проверку";
КонецЕсли;
Если Имя = "Дерево85" Тогда
Если ТипЗнч(Данные) <> Тип("ДанныеФормыЭлементДерева") Тогда
ВызватьИсключение "Не native элемент своего дерева";
КонецЕсли;
Иначе
Если ТипЗнч(Данные) <> Тип("ДанныеФормыЭлементКоллекции") Тогда
ВызватьИсключение "Не native элемент своей коллекции";
КонецЕсли;
КонецЕсли;
Если Данные.ПолучитьИдентификатор() <> Идентификатор Или Поле.ТекущиеДанные.Код85 <> Данные.Код85 Или Поле.ТекущиеДанные.Сумма85 <> Данные.Сумма85 Тогда
ВызватьИсключение "Текущие данные не соответствуют actual ID";
КонецЕсли;
Сообщить(Имя + ": " + Данные.Код85 + " / " + Строка(Данные.Сумма85));
КонецЦикла;
ПредставленияИсточник85.Сравнить85(Паспорт85, ПроверитьДанные85(Перенос85));
КонецПроцедурыПолный серверный паспорт своей CF, двух счетов и сметы
ОбщиеМодули → ПредставленияИсточник85 → Модуль, целиком
ServerДа/ServerCallДа. Native memory table remains server; клиенту только собственные scalar/ref snapshots.
Процедура ПроверитьСхему85()
Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnProcessingObjectViews85_a9b660d1-619b-41f7-a2cd-082bdc4ba164\IB"";" Тогда
ВызватьИсключение "Не собственная новая файловая ИБ";
КонецЕсли;
Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
ВызватьИсключение "Не подготовленная версия или конфигурация";
КонецЕсли;
Если Метаданные.ПланыСчетов.Количество() <> 1 Или Метаданные.Обработки.Количество() <> 1 Или Метаданные.ОбщиеМодули.Количество() <> 1 Или Метаданные.Роли.Количество() <> 1 Тогда
ВызватьИсключение "Не подготовленный состав конфигурации";
КонецЕсли;
Если Метаданные.Справочники.Количество() + Метаданные.Документы.Количество() + Метаданные.Перечисления.Количество() + Метаданные.ПланыВидовХарактеристик.Количество() + Метаданные.ПланыВидовРасчета.Количество() + Метаданные.ПланыОбмена.Количество() + Метаданные.РегистрыСведений.Количество() + Метаданные.РегистрыНакопления.Количество() + Метаданные.РегистрыБухгалтерии.Количество() + Метаданные.РегистрыРасчета.Количество() <> 0 Тогда
ВызватьИсключение "Есть другие прикладные объекты";
КонецЕсли;
Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() + РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() + РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0 Тогда
ВызватьИсключение "Расширения запрещены";
КонецЕсли;
МД = Метаданные.ПланыСчетов.Найти("Коэффициенты85");
Обр = Метаданные.Обработки.Найти("Калькулятор85");
Если МД = Неопределено Или Обр = Неопределено Или МД.МаксКоличествоСубконто <> 0 Или МД.Реквизиты.Количество() <> 2 Или МД.ТабличныеЧасти.Количество() <> 0 Или Обр.Реквизиты.Количество() <> 2 Или Обр.ТабличныеЧасти.Количество() <> 1 Тогда
ВызватьИсключение "Не собственные объекты";
КонецЕсли;
Для Каждого Реквизит Из МД.Реквизиты Цикл
Если Реквизит.Имя = "Маркер85" Тогда
Если Реквизит.Тип.Типы().Количество() <> 1 Или Не Реквизит.Тип.СодержитТип(Тип("Строка")) Или Реквизит.Тип.КвалификаторыСтроки.Длина <> 36 Тогда
ВызватьИсключение "Неверный маркер";
КонецЕсли;
ИначеЕсли Реквизит.Имя = "Коэффициент85" Тогда
Если Реквизит.Тип.Типы().Количество() <> 1 Или Не Реквизит.Тип.СодержитТип(Тип("Число")) Или Реквизит.Тип.КвалификаторыЧисла.Разрядность <> 5 Или Реквизит.Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти <> 2 Тогда
ВызватьИсключение "Неверный коэффициент";
КонецЕсли;
Иначе
ВызватьИсключение "Чужой реквизит";
КонецЕсли;
КонецЦикла;
Часть = Обр.ТабличныеЧасти.Найти("Строки85");
Если Часть = Неопределено Или Часть.Реквизиты.Количество() <> 4 Тогда
ВызватьИсключение "Не подготовленная табличная часть";
КонецЕсли;
Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Пользователь = Неопределено Тогда
ВызватьИсключение "Нет собственного пользователя";
КонецЕсли;
Соединения = ПолучитьСоединенияИнформационнойБазы();
Если Пользователь.Имя <> "Представления85Ученик" Или Соединения.Количество() <> 1 Тогда
ВызватьИсключение "Требуется один собственный сеанс";
КонецЕсли;
Если Соединения[0].Пользователь = Неопределено Или Соединения[0].Пользователь.УникальныйИдентификатор <> Пользователь.УникальныйИдентификатор Тогда
ВызватьИсключение "Не свой сеанс";
КонецЕсли;
КонецПроцедуры
Функция Пакет85() Экспорт
ПроверитьСхему85();
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка,Код,Наименование,ПометкаУдаления,Вид,Забалансовый,Родитель,Предопределенный,Порядок,Маркер85,Коэффициент85 ИЗ ПланСчетов.Коэффициенты85 УПОРЯДОЧИТЬ ПО Код");
Строки = Запрос.Выполнить().Выгрузить();
Если Строки.Количество() <> 2 Или Строки.Колонки.Количество() <> 11 Тогда
ВызватьИсключение "Не полный собственный источник из двух счетов";
КонецЕсли;
Счета = Новый Массив;
Для Каждого Р Из Строки Цикл
Если ТипЗнч(Р.Ссылка) <> Тип("ПланСчетовСсылка.Коэффициенты85") Или Р.Ссылка.Пустая() Или Р.Маркер85 <> "a9b660d1-619b-41f7-a2cd-082bdc4ba164" Или Р.ПометкаУдаления Или Р.Предопределенный Или Р.Забалансовый Или Р.Вид <> ВидСчета.Активный Или Не Р.Родитель.Пустая() Тогда
ВызватьИсключение "Чужой или изменённый счет";
КонецЕсли;
Если Не ((Р.Код = "F85" И Р.Наименование = "Полный" И Р.Коэффициент85 = 1) Или (Р.Код = "H85" И Р.Наименование = "Половина" И Р.Коэффициент85 = 0.5)) Тогда
ВызватьИсключение "Неверные учебные значения";
КонецЕсли;
Объект = Р.Ссылка.ПолучитьОбъект();
Если Объект = Неопределено Или ТипЗнч(Объект) <> Тип("ПланСчетовОбъект.Коэффициенты85") Тогда
ВызватьИсключение "Счет недоступен";
КонецЕсли;
Данные = Новый Структура;
Для Каждого Колонка Из Строки.Колонки Цикл
Данные.Вставить(Колонка.Имя, Р[Колонка.Имя]);
КонецЦикла;
Если Объект.Ссылка <> Р.Ссылка Или Объект.Код <> Р.Код Или Объект.Наименование <> Р.Наименование Или Объект.ПометкаУдаления <> Р.ПометкаУдаления Или Объект.Вид <> Р.Вид Или Объект.Забалансовый <> Р.Забалансовый Или Объект.Родитель <> Р.Родитель Или Объект.Предопределенный <> Р.Предопределенный Или Объект.Порядок <> Р.Порядок Или Объект.Маркер85 <> Р.Маркер85 Или Объект.Коэффициент85 <> Р.Коэффициент85 Или Объект.ВидыСубконто.Количество() <> 0 Тогда
ВызватьИсключение "Объект расходится с полным запросом";
КонецЕсли;
Данные.Вставить("ВерсияДанных", Объект.ВерсияДанных);
Счета.Добавить(Данные);
КонецЦикла;
Если Счета[0].Код <> "F85" Или Счета[1].Код <> "H85" Или Счета[0].Ссылка = Счета[1].Ссылка Тогда
ВызватьИсключение "Не единственные собственные ссылки";
КонецЕсли;
Возврат Новый Структура("Маркер,Счета", "a9b660d1-619b-41f7-a2cd-082bdc4ba164", Счета);
КонецФункции
Процедура Сравнить85(До, После) Экспорт
Если До.Маркер <> После.Маркер Или До.Счета.Количество() <> 2 Или После.Счета.Количество() <> 2 Тогда
ВызватьИсключение "Изменился паспорт";
КонецЕсли;
Для Индекс = 0 По 1 Цикл
Старый = До.Счета[Индекс];
Свежий = После.Счета[Индекс];
Если Старый.Количество() <> 12 Или Свежий.Количество() <> 12 Тогда
ВызватьИсключение "Не полный паспорт строки";
КонецЕсли;
Для Каждого Поле Из Старый Цикл
Если Не Свежий.Свойство(Поле.Ключ, Значение) Или Значение <> Поле.Значение Тогда
ВызватьИсключение "Изменилось поле или версия собственного счета";
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция Смета85() Экспорт
ПроверитьСхему85();
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Код85", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Количество85", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Цена85", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Сумма85", Новый ОписаниеТипов("Число"));
Коды = СтрРазделить("A85,A850,B85", ",");
Для Индекс = 0 По 2 Цикл
Р = Таблица.Добавить();
Р.Код85 = Коды[Индекс];
Р.Количество85 = ?(Индекс = 1, 2, 1);
Р.Цена85 = 250;
Р.Сумма85 = Р.Количество85 * Р.Цена85;
КонецЦикла;
Возврат Таблица;
КонецФункции
Процедура ПроверитьСмету85(Строки, Перенос = Ложь) Экспорт
Если Строки.Количество() <> 3 Или ТипЗнч(Перенос) <> Тип("Булево") Тогда
ВызватьИсключение "Не собственные три строки";
КонецЕсли;
Коды = СтрРазделить("A85,A850,B85", ",");
Для Индекс = 0 По 2 Цикл
Р = Строки[Индекс];
Код = ?(Индекс = 1 И Перенос, "B850", Коды[Индекс]);
Если ТипЗнч(Р.Код85) <> Тип("Строка") Или ТипЗнч(Р.Количество85) <> Тип("Число") Или ТипЗнч(Р.Цена85) <> Тип("Число") Или ТипЗнч(Р.Сумма85) <> Тип("Число") Или Р.Код85 <> Код Или Р.Количество85 <> ?(Индекс = 1, 2, 1) Или Р.Цена85 <> 250 Или Р.Сумма85 <> Р.Количество85 * Р.Цена85 Тогда
ВызватьИсключение "Изменилась собственная строка сметы";
КонецЕсли;
КонецЦикла;
КонецПроцедурыПолная managed форма своего счета: чтение, выбор и настоящий отказ записи
ПланыСчетов → Коэффициенты85 → Формы → Счет85 → Модуль, целиком
Genuine managed object extension, client/server directives; BeforeWrite2 не вызывает сервер.
&НаКлиенте
Перем Исходник85;
&НаКлиенте
Перем НеизвестныйИсход85;
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
СохранениеДанныхВНастройках = СохранениеДанныхФормыВНастройках.НеИспользовать;
АвтоматическоеСохранениеДанныхВНастройках = АвтоматическоеСохранениеДанныхФормыВНастройках.НеИспользовать;
ПроверитьСвойОбъект85(Ложь);
КонецПроцедуры
&НаСервере
Функция ПроверитьСвойОбъект85(Черновик)
Пакет = ПредставленияИсточник85.Пакет85();
Счет = РеквизитФормыВЗначение("Объект", Тип("ПланСчетовОбъект.Коэффициенты85"));
Если ТипЗнч(Счет) <> Тип("ПланСчетовОбъект.Коэффициенты85") Или ТипЗнч(Черновик) <> Тип("Булево") Тогда
ВызватьИсключение "Не собственный реальный объект формы";
КонецЕсли;
Свой = Неопределено;
Для Каждого Р Из Пакет.Счета Цикл
Если Р.Ссылка = Счет.Ссылка Тогда
Свой = Р;
КонецЕсли;
КонецЦикла;
Если Свой = Неопределено Тогда
ВызватьИсключение "Ссылка формы вне собственного полного источника";
КонецЕсли;
Если Счет.Код <> Свой.Код Или Счет.Наименование <> Свой.Наименование Или Счет.Маркер85 <> Пакет.Маркер Или Счет.ПометкаУдаления Или Счет.Предопределенный Или Счет.Забалансовый Или Счет.Вид <> Свой.Вид Или Счет.Родитель <> Свой.Родитель Или Счет.Порядок <> Свой.Порядок Или Счет.ВидыСубконто.Количество() <> 0 Или Счет.ВерсияДанных <> Свой.ВерсияДанных Или Счет.Коэффициент85 <> ?(Черновик, 0.75, Свой.Коэффициент85) Тогда
ВызватьИсключение "Не полный собственный объект или ожидаемый буфер";
КонецЕсли;
Возврат Пакет;
КонецФункции
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если НеизвестныйИсход85 <> Неопределено Тогда
Отказ = Истина;
ВызватьИсключение "Повторное открытие не сбрасывает СТОП";
КонецЕсли;
НеизвестныйИсход85 = Истина;
ЭтаФорма.Прочитать();
Исходник85 = ПроверитьСвойОбъект85(Ложь);
Если Не ЭтаФорма.РежимВыбора Или ТипЗнч(ЭтаФорма.ПараметрыВыбора) <> Тип("ФиксированнаяСтруктура") Или ЭтаФорма.ПараметрыВыбора.Количество() <> 1 Или ЭтаФорма.ПараметрыВыбора.Маркер85 <> Исходник85.Маркер Или Не ЭтаФорма.ВыборДоступен Тогда
Отказ = Истина;
ВызватьИсключение "Не подготовленный режим настоящего выбора";
КонецЕсли;
Если ВладелецФормы = Неопределено Или ТипЗнч(ВладелецФормы) <> Тип("ФормаКлиентскогоПриложения") Или ВладелецФормы.Объект.Маркер85 <> Исходник85.Маркер Тогда
Отказ = Истина;
ВызватьИсключение "Не собственная родительская обработка";
КонецЕсли;
Согласие85 = Ложь;
Статус85 = ЭтаФорма.ПолучитьНавигационнуюСсылкуОбъекта();
Если ТипЗнч(Статус85) <> Тип("Строка") Или Статус85 = "" Тогда
Отказ = Истина;
ВызватьИсключение "Нет собственной native навигационной ссылки";
КонецЕсли;
НеизвестныйИсход85 = Ложь;
КонецПроцедуры
&НаКлиенте
Процедура ВыборЗначения(СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если НеизвестныйИсход85 <> Ложь Тогда
ЭтаФорма.ВыборДоступен = Ложь;
Возврат;
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Исходник85, ПроверитьСвойОбъект85(Ложь));
Если Не ЭтаФорма.ВыборДоступен Или Не ЭтаФорма.РежимВыбора Или ЭтаФорма.ПараметрыВыбора.Маркер85 <> Исходник85.Маркер Тогда
Возврат;
КонецЕсли;
СтандартнаяОбработка = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьЗапрет85(Команда)
Если Команда <> Команды.ПроверитьЗапрет85 Или НеизвестныйИсход85 <> Ложь Тогда
ВызватьИсключение "Не собственная команда или уже СТОП";
КонецЕсли;
Если Согласие85 <> Истина Тогда
ВызватьИсключение "Для единственной попытки требуется явное согласие";
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Исходник85, ПроверитьСвойОбъект85(Ложь));
Согласие85 = Ложь;
НеизвестныйИсход85 = Истина;
ВладелецФормы.Остановить85();
Попытка
Объект.Коэффициент85 = 0.75;
ПроверитьСвойОбъект85(Истина);
Результат = ЭтаФорма.Записать(Новый Структура("Маркер85", Исходник85.Маркер));
Если Результат <> Ложь Тогда
ВызватьИсключение "Неожиданный исход записи; СТОП без повтора";
КонецЕсли;
ПредставленияИсточник85.Сравнить85(Исходник85, ПроверитьСвойОбъект85(Истина));
Статус85 = "Native False. Полный сохранённый источник прежний; буфер0.75 не сохранён. СТОП.";
Исключение
НеизвестныйИсход85 = Истина;
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Отказ = Истина;
КонецПроцедурыПолная ordinary обработка с намеренно отключённым восстановлением
Обработки → Калькулятор85 → Формы → Обычная85 → Модуль
Толстый ordinary клиент; native OnOpen0/Click1/BeforeSave1, никаких storage writes.
Перем Паспорт85;
Перем НеизвестныйИсход85;
Процедура Подготовить85(Пакет) Экспорт
Если НеизвестныйИсход85 <> Неопределено Тогда
ВызватьИсключение "Повторный initializer не сбрасывает СТОП";
КонецЕсли;
НеизвестныйИсход85 = Истина;
ПредставленияИсточник85.Сравнить85(Пакет, ПредставленияИсточник85.Пакет85());
Если ТипЗнч(Калькулятор85) <> Тип("ОбработкаОбъект.Калькулятор85") Или Калькулятор85.Маркер85 <> Пакет.Маркер Или ЭтаФорма.ВосстанавливатьЗначенияПриОткрытии <> Ложь Тогда
ВызватьИсключение "Не собственная ordinary форма или включено восстановление";
КонецЕсли;
Паспорт85 = Пакет;
Посчитать85();
НеизвестныйИсход85 = Ложь;
КонецПроцедуры
Процедура ПриОткрытии()
Если НеизвестныйИсход85 <> Ложь Или ЭтаФорма.ВосстанавливатьЗначенияПриОткрытии <> Ложь Тогда
ВызватьИсключение "Не подготовленное безопасное открытие";
КонецЕсли;
Посчитать85();
КонецПроцедуры
Процедура Полный85(Кнопка)
Если Кнопка <> ЭлементыФормы.Полный85 Тогда
ВызватьИсключение "Чужая кнопка";
КонецЕсли;
Коэффициент85(1);
КонецПроцедуры
Процедура Половина85(Кнопка)
Если Кнопка <> ЭлементыФормы.Половина85 Тогда
ВызватьИсключение "Чужая кнопка";
КонецЕсли;
Коэффициент85(0.5);
КонецПроцедуры
Процедура Коэффициент85(Значение)
Если НеизвестныйИсход85 <> Ложь Или (Значение <> 1 И Значение <> 0.5) Тогда
ВызватьИсключение "СТОП или чужой коэффициент";
КонецЕсли;
НеизвестныйИсход85 = Истина;
Попытка
Калькулятор85.Коэффициент85 = Значение;
Посчитать85();
НеизвестныйИсход85 = Ложь;
Исключение
НеизвестныйИсход85 = Истина;
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Процедура Посчитать85()
ПредставленияИсточник85.Сравнить85(Паспорт85, ПредставленияИсточник85.Пакет85());
Если Калькулятор85.Маркер85 <> Паспорт85.Маркер Или ЭтаФорма.ВосстанавливатьЗначенияПриОткрытии <> Ложь Тогда
ВызватьИсключение "Не собственный буфер или включено восстановление";
КонецЕсли;
Если Калькулятор85.Строки85.Количество() <> 3 Тогда
ВызватьИсключение "Не собственная локальная табличная часть";
КонецЕсли;
Коды = СтрРазделить("A85,A850,B85", ",");
Для Индекс = 0 По 2 Цикл
Р = Калькулятор85.Строки85[Индекс];
Если ТипЗнч(Р.Код85) <> Тип("Строка") Или ТипЗнч(Р.Количество85) <> Тип("Число") Или ТипЗнч(Р.Цена85) <> Тип("Число") Или ТипЗнч(Р.Сумма85) <> Тип("Число") Или Р.Код85 <> Коды[Индекс] Или Р.Количество85 <> ?(Индекс = 1, 2, 1) Или Р.Цена85 <> 250 Или Р.Сумма85 <> Р.Количество85 * Р.Цена85 Тогда
ВызватьИсключение "Изменилась собственная локальная строка";
КонецЕсли;
КонецЦикла;
Сумма = 0;
Для Каждого Р Из Калькулятор85.Строки85 Цикл
Сумма = Сумма + Р.Количество85 * Р.Цена85;
КонецЦикла;
Если Сумма <> 1000 Или (Калькулятор85.Коэффициент85 <> 1 И Калькулятор85.Коэффициент85 <> 0.5) Тогда
ВызватьИсключение "Не собственная независимая сумма";
КонецЕсли;
Статус85 = Строка(Сумма * Калькулятор85.Коэффициент85);
КонецПроцедуры
Процедура ПередСохранениемЗначений(Отказ)
Отказ = Истина;
КонецПроцедурыПолный дополнительный broad-context запрет записи своего счета
ПланыСчетов → Коэффициенты85 → Модуль объекта после manual fixture
Native BeforeWrite1 во всех контекстах; только ОтказTrue.
Процедура ПередЗаписью(Отказ)
Отказ = Истина;
КонецПроцедурыПолный managed startup своей обработки
Конфигурация → Модуль управляемого приложения
Native ПриНачалеРаботыСистемы0; отдельный Windows thick-managed launch.
Процедура ПриНачалеРаботыСистемы()
Форма = ПолучитьФорму("Обработка.Калькулятор85.Форма.Управляемая85");
Если Форма = Неопределено Или ТипЗнч(Форма) <> Тип("ФормаКлиентскогоПриложения") Тогда
ВызватьИсключение "Не подготовленная собственная managed форма";
КонецЕсли;
Форма.Открыть();
КонецПроцедурыПолный ordinary startup реального того же экземпляра обработки
Конфигурация → Модуль обычного приложения
Native ПриНачалеРаботыСистемы0; только Windows thick-ordinary launch.
Процедура ПриНачалеРаботыСистемы()
Пакет = ПредставленияИсточник85.Пакет85();
Объект = Обработки.Калькулятор85.Создать();
Объект.Маркер85 = Пакет.Маркер;
Объект.Коэффициент85 = 1;
Коды = СтрРазделить("A85,A850,B85", ",");
Для Индекс = 0 По 2 Цикл
Р = Объект.Строки85.Добавить();
Р.Код85 = Коды[Индекс];
Р.Количество85 = ?(Индекс = 1, 2, 1);
Р.Цена85 = 250;
Р.Сумма85 = Р.Количество85 * Р.Цена85;
КонецЦикла;
Форма = Объект.ПолучитьФорму("Обычная85",, Новый УникальныйИдентификатор);
Если Форма = Неопределено Или ТипЗнч(Форма) <> Тип("Форма") Или Форма.Калькулятор85 <> Объект Тогда
ВызватьИсключение "Не реальная ordinary форма того же экземпляра обработки";
КонецЕсли;
Форма.ВосстанавливатьЗначенияПриОткрытии = Ложь;
Форма.Подготовить85(Пакет);
Форма.Открыть();
КонецПроцедурыРазбор по шагам
Create287→actual processingObject; ValueToFormAttribute3530 на сервере, не invalid client transport.
Три строки250/500/250, six-node actualtreeВСЕ/A/B/leaves; все полные readback и independent sums.
Настоящие native RowFilter A/B/Undefined; ContainsA включает A85 иA850. Полный source1000 не становится750 отUI-фильтра.
OwnTPedit A850↔B850 сохраняетprice/qty/sum1000 и переустанавливает TPfilterA.
Вручную selectedrow→actualID→RowData; ни native visibleaggregate, ни detached mutable copy не выдумываются.
Как проверить результат
Типы/имена/control data bindings и native returned union проверены; Undefined просит реальный manualselect.
Целое processingObject преобразуется обратно, а не отдельнаяTabularPart; TV/tree отдельно с точнымТип.
Все retained client values — собственные primitive/ref snapshots, не менеджеры/метаданные/ValueTableRPC.
После каждого эффекта повторно проверен полный memorysource и неизменённый полныйDBsource.
Ожидаемый результат
Actual source1000; дерево A750+B250. UI ContainsA750/B250/All1000. После ownTPcode edit TPContainsA250, после отдельного возврата750; savedaccounts не меняются.
На что обратить внимание
Ожидаемые видимые суммы проверяются вручную через реальные строки, не выдаются за ответ несуществующего native aggregate.
Старый текст extension-copy не служит разрешением менять returned row; код их только читает.
При setter/roundtrip ошибке — stickyСТОП, не обещанная универсальная перерисовка/atomicUI.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.