На собственных трёх сохранённых записях увидеть разницу между пометкой и удалением, проверить настоящую зависимость USE85→BLOCK85 и отдельно согласовать удаление только свободного FREE85.
Где и как запускать
Полный общий client-only модуль новой собственной Windows FileCF8.5.1.1343, только толстый обычный клиент. Реальные записи/монополия/удаление лишь будущие ручные этапы со своим явным согласием.
Подготовка
Только совершенно новая собственная пустая File ИБ C:\1c-labs\OwnDeleteRefs85_3a8e7d41-9216-4bba-86ac-610c70f427d9\IB на отдельном учебном Windows стенде8.5.1.1343. Если путь/регистрация уже существуют — не переиспользуйте и не очищайте, остановитесь. Exact File="путь"; проверяется буквально; UUID в пути — лабораторная метка, не измеренный UUIDИБ. Здесь VM/каталог/CF/ИБ/данные не создавались и1С не запускалась.
Конфигурация УчебноеУдалениеСсылок85: РежимСовместимостиНеИспользовать, ОсновнойРежимЗапускаОбычноеПриложение. Сервис→Параметры→Общие→вид редактирования конфигурации для режима запуска «Управляемое приложение и обычное приложение». Это параметр редактора, не metadataSupportedRunModes. Два справочника, одна обработка, один общий модуль и одна роль. Остальные прикладные объекты/разделители/расширения/параметрысеанса/подписки/задания/источники/хранилища отсутствуют; модули объектов/менеджеров пустые.
Справочник Кандидаты85: неиерархический, без владельцев/табличных частей/предопределённых. КодСтрока12, Наименование80, автонумерацияНет, контрольуникальностиДа. Реквизиты Маркер85 единственныйтипСтрока36, Сумма85 единственныйтипЧисло10,0. Справочник Использования85: те же стандартные настройки, реквизиты Маркер85Строка36, Сумма85Число10,0, Кандидат85 единственныйтипСправочникСсылка.Кандидаты85. Никаких иных реквизитов или связей.
Роль Уборка85Администратор только своей новойCF: Администрирование для списка пользователей, АктивныеПользователи, право установки монопольного режима; все права чтения/добавления/изменения/пометки/удаления обоих собственных справочников и использования обработки. Без RLS/ограничений чтения/разделителей. Единственный пользователь Уборка85Ученик с этой ролью; подключается только он. Это полная учебная роль, не рекомендации производственных прав.
ДО вставки startup вручную сохраните ровно3записи обычными стандартными формами: Кандидаты85 BLOCK85/Сохранить/Сумма85=100 и FREE85/Удалить/200; Использования85 USE85/Связь/100, Кандидат85=реально сохранённый BLOCK85, не UUID-литерал. Маркер85 у всех3a8e7d41-9216-4bba-86ac-610c70f427d9; ПредопределенныйFalse. Обе записи кандидатов вручную пометьте на удаление, USE85 НЕ помечайте. Пометка не равна физическому удалению: USE85 сохраняет настоящую ссылку на BLOCK85.
ОбщийМодуль УборкаПамять85: ГлобальныйНет, КлиентОбычноеПриложениеДа, КлиентУправляемоеПриложениеНет, СерверНет, ВнешнееСоединениеНет, ПривилегированныйНет, повторноеиспользованиеНеИспользовать. MAIN CODE полностью в этот модуль. Обработка Уборка85: единственная основная ОБЫЧНАЯ форма Пульт85, форма сама ничего не записывает при открытии. Реквизиты формы Подтверждаю85Булево начальноеFalse, Статус85Строка2000readonly. Кнопки Монопольно85/Удалить85: обе nativeНажатие→Этап85(Кнопка); формаПриОткрытии0→ПриОткрытии. FORM целиком в модуль; APPLICATION целиком в МодульОбычногоПриложения. Ни событие, ни кнопку вручную не вызывают.
Сохраните/обновите вручную исключительно новуюCF. Закройте Конфигуратор и любые другие подключения своего стенда; не открывайте второе окно/фоновые сеансы/консоль запросов. Запустите толстый обычный клиент. Открытие читает полный объём обоих собственных справочников безГДЕ, сверяет все поля и actualGetObject; записей и блокировки пока нет.
Первое отдельное согласие: поставьте флажок и нажмите Монопольно85. До установки блокировки код заново проверяет exactFile/схему/пользователя/единственное подключение/полный fixture. NativeУстановитьМонопольныйРежимTrue применяется только к своей новойИБ без разделителей; нет завершения чужих сеансов/параметров bypass. Затем getter и полный readback. Неудача запрещает продолжение, блокировка может уже существовать: код не снимает её blindfinally.
В ownОбласть85 все три scope аргумента заданы: пустой массив комбинаций разделителей, Включить именно два собственных metadata каталога, явный пустой Исключить. NativeFindMarked иначе при Неопределено вИсключить может игнорировать include/exclude; старый compatibility≤8.3.4 тоже меняет семантику, поэтому запрещён. Мобильная платформа игнорирует scope — не поддерживается. Найденные2refs обязаны быть только BLOCK/FREE, без дубликатов. NativeFindByRefs возвращает actual USE→BLOCK; проверены каждая positional колонка0/1/2 и metadataИспользования85.
Второе НОВОЕ согласие: прочитайте статус, снова поставьте флажок и нажмите Удалить85. Список refs получен заново, полный source/зависимость сверены перед процедурой. Проверять всегдаИстина: native defaultЛожь опасен и не используется. Процедура УдалитьОбъекты не возвращает значение: Оставшиеся — native выходной параметр. Ожидаемый будущий outcome: FREE85 физически исчезнет, BLOCK85 не удалится из-заUSE85, обе сохранённые ссылки/все поля останутся. Полные запросы подтверждают кандидатов300→100 и объектов3→2, новое marked-search1 и прежнюю собственную зависимость.
Любое исключение/лишняя зависимость/чужая ссылка/неожиданная структура выходнойTV означает stickyСТОП, даже если часть операции уже выполнена. Повторов/rollback/автоочистки/снятия монополии кодом нет. Проверьте вручную только свой стенд, затем закройте только этот учебный клиент. Не обходите блокировку и не выполняйте упражнение на production или реальной копии. Отмена/отсутствие согласия не вызывает deletion; открытие формы повторно после выполненного удаления тоже откажет исходному fullfixture.
#Если ТолстыйКлиентОбычноеПриложение Тогда
Процедура ПроверитьСтенд85()
Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnDeleteRefs85_3a8e7d41-9216-4bba-86ac-610c70f427d9\IB"";" Или Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или Метаданные.ОсновнойРежимЗапуска <> РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение Или ТранзакцияАктивна() Тогда
ВызватьИсключение "Только собственный exact File стенд без совместимости и активной транзакции";
КонецЕсли;
Если Метаданные.Справочники.Количество() <> 2 Или Метаданные.Обработки.Количество() <> 1
Или Метаданные.ОбщиеМодули.Количество() <> 1 Или Метаданные.Роли.Количество() <> 1
Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Константы.Количество() <> 0
Или Метаданные.Отчеты.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.ОбщиеФормы.Количество() <> 0
Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0
Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0
Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0
Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0
Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0
Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПараметрыСеанса.Количество() <> 0
Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0
Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Или Метаданные.ХранилищаНастроек.Количество() <> 0 Тогда
ВызватьИсключение "Чужие метаданные/данные/разделители/дополнительные зависимости запрещены";
КонецЕсли;
Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0
Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() <> 0
Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0 Тогда
ВызватьИсключение "Расширения не допускаются";
КонецЕсли;
Если Метаданные.Справочники.Найти("Кандидаты85") = Неопределено Или Метаданные.Справочники.Найти("Использования85") = Неопределено
Или Метаданные.Обработки.Найти("Уборка85") = Неопределено Или Метаданные.ОбщиеМодули.Найти("УборкаПамять85") = Неопределено
Или Не РольДоступна("Уборка85Администратор") Тогда
ВызватьИсключение "Собственная схема/роль не найдена";
КонецЕсли;
Для Каждого Имя Из СтрРазделить("Кандидаты85,Использования85", ",") Цикл
МД = Метаданные.Справочники.Найти(Имя);
Если МД.Иерархический Или МД.Владельцы.Количество() <> 0 Или МД.ТабличныеЧасти.Количество() <> 0
Или МД.Реквизиты.Количество() <> ?(Имя = "Кандидаты85", 2, 3) Тогда
ВызватьИсключение "Каталоги без иерархии/владельцев/табличных частей, только объявленные собственные поля";
КонецЕсли;
КонецЦикла;
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
Если ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
ВызватьИсключение "Нужен единственный свой пользователь";
КонецЕсли;
Если Пользователи[0].Имя <> "Уборка85Ученик" Или Текущий.УникальныйИдентификатор <> Пользователи[0].УникальныйИдентификатор Тогда
ВызватьИсключение "Не подтвержден собственный текущий пользователь";
КонецЕсли;
Соединения = ПолучитьСоединенияИнформационнойБазы();
Если ТипЗнч(Соединения) <> Тип("Массив") Или Соединения.Количество() <> 1 Тогда
ВызватьИсключение "Закройте остальные подключения только своего стенда";
КонецЕсли;
Если Соединения[0].НомерСоединения <> НомерСоединенияИнформационнойБазы()
Или Соединения[0].Пользователь.УникальныйИдентификатор <> Текущий.УникальныйИдентификатор Тогда
ВызватьИсключение "Единственное подключение должно быть текущим и собственным";
КонецЕсли;
КонецПроцедуры
Функция ПрочитатьИсточник85(СвободныйУдален) Экспорт
ПроверитьСтенд85();
Если ТипЗнч(СвободныйУдален) <> Тип("Булево") Тогда
ВызватьИсключение "Неизвестная стадия учебного источника";
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка,Код,Наименование,ПометкаУдаления,Предопределенный,Маркер85,Сумма85 ИЗ Справочник.Кандидаты85";
Кандидаты = Запрос.Выполнить().Выгрузить();
Если ТипЗнч(Кандидаты) <> Тип("ТаблицаЗначений") Или Кандидаты.Колонки.Количество() <> 7
Или Кандидаты.Количество() <> ?(СвободныйУдален, 1, 2) Тогда
ВызватьИсключение "Полный объём кандидатов не совпал";
КонецЕсли;
Блокированный = Неопределено;
Свободный = Неопределено;
Сумма = 0;
Для Каждого Строка Из Кандидаты Цикл
Если ТипЗнч(Строка.Ссылка) <> Тип("СправочникСсылка.Кандидаты85") Или Строка.Ссылка.Пустая()
Или ТипЗнч(Строка.ПометкаУдаления) <> Тип("Булево") Или Не Строка.ПометкаУдаления
Или Строка.Предопределенный Или Строка.Маркер85 <> "3a8e7d41-9216-4bba-86ac-610c70f427d9"
Или ТипЗнч(Строка.Сумма85) <> Тип("Число") Тогда
ВызватьИсключение "Не подтверждены собственные типы/пометки/маркер кандидатов";
КонецЕсли;
Если Строка.Код = "BLOCK85" И Строка.Наименование = "Сохранить" И Строка.Сумма85 = 100 И Блокированный = Неопределено Тогда
Блокированный = Строка.Ссылка;
ИначеЕсли Не СвободныйУдален И Строка.Код = "FREE85" И Строка.Наименование = "Удалить" И Строка.Сумма85 = 200 И Свободный = Неопределено Тогда
Свободный = Строка.Ссылка;
Иначе
ВызватьИсключение "Лишняя/изменённая собственная запись кандидата";
КонецЕсли;
Объект = Строка.Ссылка.ПолучитьОбъект();
Если ТипЗнч(Объект) <> Тип("СправочникОбъект.Кандидаты85") Или Объект.Метаданные() <> Метаданные.Справочники.Кандидаты85
Или Объект.Ссылка <> Строка.Ссылка Или Объект.Код <> Строка.Код Или Объект.Наименование <> Строка.Наименование
Или Объект.ПометкаУдаления <> Строка.ПометкаУдаления Или Объект.Предопределенный <> Строка.Предопределенный
Или Объект.Маркер85 <> Строка.Маркер85 Или Объект.Сумма85 <> Строка.Сумма85 Тогда
ВызватьИсключение "Actual объект кандидата не совпал со всем query source";
КонецЕсли;
Сумма = Сумма + Строка.Сумма85;
КонецЦикла;
Если Блокированный = Неопределено Или Не СвободныйУдален И (Свободный = Неопределено Или Свободный = Блокированный)
Или Сумма <> ?(СвободныйУдален, 100, 300) Тогда
ВызватьИсключение "Полные actual refs/числа кандидатов не подтверждены";
КонецЕсли;
Запрос.Текст = "ВЫБРАТЬ Ссылка,Код,Наименование,ПометкаУдаления,Предопределенный,Маркер85,Кандидат85,Сумма85 ИЗ Справочник.Использования85";
Использования = Запрос.Выполнить().Выгрузить();
Если ТипЗнч(Использования) <> Тип("ТаблицаЗначений") Или Использования.Количество() <> 1 Или Использования.Колонки.Количество() <> 8 Тогда
ВызватьИсключение "Нужно единственное actual собственное использование";
КонецЕсли;
Строка = Использования[0];
Если ТипЗнч(Строка.Ссылка) <> Тип("СправочникСсылка.Использования85") Или Строка.Ссылка.Пустая()
Или Строка.Код <> "USE85" Или Строка.Наименование <> "Связь" Или Строка.ПометкаУдаления Или Строка.Предопределенный
Или Строка.Маркер85 <> "3a8e7d41-9216-4bba-86ac-610c70f427d9" Или ТипЗнч(Строка.Кандидат85) <> Тип("СправочникСсылка.Кандидаты85")
Или Строка.Кандидат85 <> Блокированный Или ТипЗнч(Строка.Сумма85) <> Тип("Число") Или Строка.Сумма85 <> 100 Тогда
ВызватьИсключение "Изменено/чужое использование кандидата";
КонецЕсли;
Объект = Строка.Ссылка.ПолучитьОбъект();
Если ТипЗнч(Объект) <> Тип("СправочникОбъект.Использования85") Или Объект.Метаданные() <> Метаданные.Справочники.Использования85
Или Объект.Ссылка <> Строка.Ссылка Или Объект.Код <> Строка.Код Или Объект.Наименование <> Строка.Наименование
Или Объект.ПометкаУдаления <> Строка.ПометкаУдаления Или Объект.Предопределенный <> Строка.Предопределенный
Или Объект.Маркер85 <> Строка.Маркер85 Или Объект.Кандидат85 <> Строка.Кандидат85 Или Объект.Сумма85 <> Строка.Сумма85 Тогда
ВызватьИсключение "Actual объект использования не совпал со всем query source";
КонецЕсли;
Возврат Новый Структура("Блокированный,Свободный,Использование,Сумма,Объекты", Блокированный, Свободный, Строка.Ссылка, Сумма, Кандидаты.Количество() + Использования.Количество());
КонецФункции
Функция Область85()
Включить = Новый Массив;
Включить.Добавить(Метаданные.Справочники.Кандидаты85);
Включить.Добавить(Метаданные.Справочники.Использования85);
Возврат Новый Структура("Разделители,Включить,Исключить", Новый Массив, Включить, Новый Массив);
КонецФункции
Функция Помеченные85(Паспорт, Область, После)
Найденные = НайтиПомеченныеНаУдаление(Область.Разделители, Область.Включить, Область.Исключить);
Если ТипЗнч(Найденные) <> Тип("Массив") Или Найденные.Количество() <> ?(После, 1, 2) Тогда
ВызватьИсключение "Native marked-search не подтвердил собственный объём";
КонецЕсли;
Проверенные = Новый Массив;
Для Каждого Ссылка Из Найденные Цикл
Если ТипЗнч(Ссылка) <> Тип("СправочникСсылка.Кандидаты85") Или Ссылка.Пустая() Или Проверенные.Найти(Ссылка) <> Неопределено
Или Ссылка <> Паспорт.Блокированный И (После Или Ссылка <> Паспорт.Свободный) Тогда
ВызватьИсключение "Native marked-search содержит чужую/дублированную ссылку";
КонецЕсли;
Проверенные.Добавить(Ссылка);
КонецЦикла;
Возврат Найденные;
КонецФункции
Процедура ПроверитьЗависимость85(Таблица, Паспорт)
Если ТипЗнч(Таблица) <> Тип("ТаблицаЗначений") Или Таблица.Колонки.Количество() <> 3 Или Таблица.Количество() <> 1 Тогда
ВызватьИсключение "Только3 documented positional columns/1своя зависимость; иной return-shape требует ручной сверки, не обрезания";
КонецЕсли;
Если ТипЗнч(Таблица[0][0]) <> Тип("СправочникСсылка.Кандидаты85") Или Таблица[0][0] <> Паспорт.Блокированный
Или ТипЗнч(Таблица[0][1]) <> Тип("СправочникСсылка.Использования85") Или Таблица[0][1] <> Паспорт.Использование
Или Таблица[0][2] <> Метаданные.Справочники.Использования85 Тогда
ВызватьИсключение "Не подтверждены ВСЕ actual ссылки и metadata источника зависимости";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьПаспорт85(Паспорт, После)
Если ТипЗнч(Паспорт) <> Тип("Структура") Или Паспорт.Количество() <> 5 Тогда
ВызватьИсключение "Неизвестный собственный паспорт";
КонецЕсли;
Если ТипЗнч(Паспорт.Блокированный) <> Тип("СправочникСсылка.Кандидаты85") Или Паспорт.Блокированный.Пустая()
Или ТипЗнч(Паспорт.Свободный) <> Тип("СправочникСсылка.Кандидаты85") Или Паспорт.Свободный.Пустая()
Или Паспорт.Свободный = Паспорт.Блокированный Или ТипЗнч(Паспорт.Использование) <> Тип("СправочникСсылка.Использования85")
Или Паспорт.Использование.Пустая() Или ТипЗнч(Паспорт.Сумма) <> Тип("Число") Или Паспорт.Сумма <> 300
Или ТипЗнч(Паспорт.Объекты) <> Тип("Число") Или Паспорт.Объекты <> 3 Тогда
ВызватьИсключение "Не подтверждён полный первоначальный own паспорт3refs/300/3";
КонецЕсли;
Факт = ПрочитатьИсточник85(После);
Если Факт.Блокированный <> Паспорт.Блокированный Или Факт.Использование <> Паспорт.Использование
Или Не После И Факт.Свободный <> Паспорт.Свободный Тогда
ВызватьИсключение "Полный свежий source не подтвердил whitelist actual refs";
КонецЕсли;
КонецПроцедуры
Функция ПодготовитьМонопольно85(Подтверждение) Экспорт
Если ТипЗнч(Подтверждение) <> Тип("Булево") Или Не Подтверждение Тогда
ВызватьИсключение "Отдельно подтвердите монопольный режим только своего стенда";
КонецЕсли;
Паспорт = ПрочитатьИсточник85(Ложь);
Если МонопольныйРежим() Тогда
ВызватьИсключение "Уже существующий монопольный этап не переиспользуется";
КонецЕсли;
ПроверитьПаспорт85(Паспорт, Ложь);
УстановитьМонопольныйРежим(Истина);
Если Не МонопольныйРежим() Тогда
ВызватьИсключение "Actual монопольная блокировка не подтверждена";
КонецЕсли;
Область = Область85();
Ссылки = Помеченные85(Паспорт, Область, Ложь);
ПроверитьЗависимость85(НайтиПоСсылкам(Ссылки, Область.Разделители, Область.Включить, Область.Исключить), Паспорт);
ПроверитьПаспорт85(Паспорт, Ложь);
Возврат Паспорт;
КонецФункции
Функция ПопытатьсяУдалить85(Паспорт, Подтверждение) Экспорт
Если ТипЗнч(Подтверждение) <> Тип("Булево") Или Не Подтверждение Тогда
ВызватьИсключение "Заново подтвердите проверяемую попытку удаления своих BLOCK85/FREE85";
КонецЕсли;
ПроверитьПаспорт85(Паспорт, Ложь);
Если Не МонопольныйРежим() Тогда
ВызватьИсключение "Удаление без actual монопольного режима запрещено";
КонецЕсли;
Область = Область85();
Ссылки = Помеченные85(Паспорт, Область, Ложь);
ПроверитьЗависимость85(НайтиПоСсылкам(Ссылки, Область.Разделители, Область.Включить, Область.Исключить), Паспорт);
ПроверитьПаспорт85(Паспорт, Ложь);
Оставшиеся = Новый ТаблицаЗначений;
УдалитьОбъекты(Ссылки, Истина, Оставшиеся, Область.Разделители, Область.Включить, Область.Исключить);
ПроверитьЗависимость85(Оставшиеся, Паспорт);
ПроверитьПаспорт85(Паспорт, Истина);
После = ПрочитатьИсточник85(Истина);
СсылкиПосле = Помеченные85(Паспорт, Область, Истина);
ПроверитьЗависимость85(НайтиПоСсылкам(СсылкиПосле, Область.Разделители, Область.Включить, Область.Исключить), Паспорт);
ПроверитьПаспорт85(Паспорт, Истина);
Возврат После;
КонецФункции
#КонецЕслиПолный пульт двух отдельно согласованных этапов
Обработки → Уборка85 → Формы → Пульт85 → Модуль, целиком
Толстый обычный клиент; actual own ButtonClick1/OnOpen0. StickyUnknown до каждого изменяемого этапа.
Перем Паспорт85, НеизвестныйИсход85, Завершено85;
Процедура ПриОткрытии()
НеизвестныйИсход85 = Истина;
Подтверждаю85 = Ложь;
УборкаПамять85.ПрочитатьИсточник85(Ложь);
Паспорт85 = Неопределено;
Завершено85 = Ложь;
НеизвестныйИсход85 = Ложь;
Статус85 = "Подготовлено3своих объекта. Отдельно подтвердите монопольный этап; затем новое согласие перед удалением.";
КонецПроцедуры
Процедура Этап85(Кнопка)
Если Кнопка <> ЭлементыФормы.Монопольно85 И Кнопка <> ЭлементыФормы.Удалить85 Тогда
ВызватьИсключение "Нужна actual собственная кнопка";
КонецЕсли;
Если Кнопка.Имя <> ?(Кнопка = ЭлементыФормы.Монопольно85, "Монопольно85", "Удалить85")
Или НеизвестныйИсход85 <> Ложь Или Завершено85 <> Ложь Тогда
ВызватьИсключение "Неверный source-control/предыдущая ошибка/завершённый опыт";
КонецЕсли;
Если ТипЗнч(Подтверждаю85) <> Тип("Булево") Или Не Подтверждаю85 Тогда
ВызватьИсключение "Поставьте своё согласие на один следующий этап";
КонецЕсли;
Подтверждаю85 = Ложь;
НеизвестныйИсход85 = Истина;
Попытка
Если Кнопка = ЭлементыФормы.Монопольно85 Тогда
Если Паспорт85 <> Неопределено Тогда
ВызватьИсключение "Монопольный этап нельзя повторять";
КонецЕсли;
Паспорт85 = УборкаПамять85.ПодготовитьМонопольно85(Истина);
Статус85 = "Actual2marked/однаUSE85→BLOCK85 проверены, source300/3неизменен. Теперь отдельное согласие: FREE85 исчезнет, BLOCK85 должен остаться.";
Иначе
Если Паспорт85 = Неопределено Тогда
ВызватьИсключение "Нет собственного завершённого монопольного этапа";
КонецЕсли;
После = УборкаПамять85.ПопытатьсяУдалить85(Паспорт85, Истина);
Статус85 = "Actual сумма кандидатов: " + Формат(Паспорт85.Сумма, "ЧГ=0;ЧДЦ=0") + "→" + Формат(После.Сумма, "ЧГ=0;ЧДЦ=0")
+ "; объектов: " + Формат(Паспорт85.Объекты, "ЧГ=0") + "→" + Формат(После.Объекты, "ЧГ=0") + ". BLOCK85 и USE85 сохранены. Закройте только этот учебный клиент; повторов нет.";
Завершено85 = Истина;
КонецЕсли;
НеизвестныйИсход85 = Ложь;
Исключение
НеизвестныйИсход85 = Истина;
Статус85 = "СТОП: исход блокировки/удаления неизвестен, возможно частичное изменение. Не повторять и не снимать блокировку кодом. " + ОписаниеОшибки();
ВызватьИсключение;
КонецПопытки;
КонецПроцедурыПолный startup собственной формы
Конфигурация → Модуль обычного приложения, целиком ПОСЛЕ ручного fixture
NativeOnStart0, ordinarythick; own ProcessingManager.GetForm/freshkey→actualOpen; никакого ручного eventcall.
Процедура ПриНачалеРаботыСистемы()
#Если ТолстыйКлиентОбычноеПриложение Тогда
СвойКлюч85 = Новый УникальныйИдентификатор;
Форма85 = Обработки.Уборка85.ПолучитьФорму("Пульт85",, СвойКлюч85);
Если Форма85 = Неопределено Или ТипЗнч(Форма85) <> Тип("Форма") Или Форма85.Открыта() Или Форма85.КлючУникальности <> СвойКлюч85 Тогда
ВызватьИсключение "Не подтверждена новая собственная ordinary форма";
КонецЕсли;
Форма85.Открыть();
#Иначе
ВызватьИсключение "Только собственный толстый обычный клиент";
#КонецЕсли
КонецПроцедурыРазбор по шагам
Вручную подготовить собственную новуюCF и actual2marked кандидата100/200 плюс одну непомеченную actualUsage100.
Полным query/GetObject подтвердить каждую собственную ссылку/поле и единственный сеанс, затем отдельно согласовать собственную монополию.
FindMarked с тремя явными scope массивами даёт только2actualref; FindByRefs с четырьмя аргументами даёт собственную dependency, не придуманную ссылку.
Новое согласие → свежий полный whitelist → DeleteObjects(6args, CheckTrue, actualoutputTable) без назначения return.
Проверить actualremaining dependency и оба полных sources: только свободная запись исчезла, blocked и usage полностью сохранены, actual numeric300→100/objects3→2.
Как проверить результат
Проверяются обе ссылки кандидатных объектов, собственная ссылка использования и все3 positional поля dependency, не только число строк.
У неизвестного/дублированного refs или несоответствующего metadata/ref/marker/amount fullguard отказывает доdelete.
Статические native/callback/readonly/arity/consent/owner/scope mutations; реальных запусков и удаления0.
Ожидаемый результат
Будущий ручной результат: FREE85 удалён, BLOCK85 и USE85 сохранены; сумма кандидатов300→100, объекты3→2, oneactualremaining dependency. Здесь только полный authored код/подготовка и статические проверки;1С/ИБ/БД/UI/runtime0.
На что обратить внимание
DeleteObjects может удалить и непомеченный объект, если его ref передан: список здесь берётся изactual marked-search и строгого own whitelist, не из unknowninput.
Один сеанс и монопольная блокировка не оправдывают удаление production. Поиск ограничен доступностью/разделением/правами; отсутствие чужих источников задаётся именно новой собственной минимальнойCF, не выводится из одной таблицы зависимостей.
NativeDelete parameter описывает3 positional columns, notes также упоминают4-е поле комбинаций разделителей. Для своейNoSplit fixture принимается только реальный3-column return; иной shape — стоп, не угадывание default четвёртого поля/не обрезание. Поля/порядок nativecolumnnames не выдумываются.
Remaining показывает только непосредственно препятствующие объекты, не рекурсивный граф. Этот урок имеет ровноодну заранее подготовленную непосредственную связь и не обещает обработки произвольной конфигурации.
Никакой обещанной атомарности нескольких этапов/rollback. Исключение после setter/delete оставляет неизвестный исход; штатный native результат и полный readback проверяются отдельно от статических тестов.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.