Глобальный контекст.УдалитьОбъекты

Методы · DeleteObjects

Удаляет объекты, ссылки на которые переданы в параметре <СписокСсылок>. При проверке ссылочной целостности поиск осуществляется среди всех данных, из которых могут быть ссылки на переданные объекты. Если на какой-либо объект нет доступа, то вызывается исключение. Требует монопольного режима доступа к базе данных.

Синтаксис

УдалитьОбъекты(<СписокСсылок>, <Проверять>, <НайденныеДанные>, <ОбластьПоиска>, <ВключитьОбъекты>, <ИсключитьОбъекты>)

Примеры платформы

Помеченные = НайтиПомеченныеНаУдаление();
Найденные = 0;
УдалитьОбъекты(Помеченные, Истина, Найденные);
Для каждого Ссылка из Найденные Цикл
    СтрСообщения = "Объект не удален: " + СокрЛП(Ссылка[0]);
    СтрСсылка = ", используется в " + СокрЛП(Ссылка[1]);
    Сообщить (СтрСообщения + СтрСсылка);
КонецЦикла;
Полное описание, параметры и ограничения

Глобальный контекст.УдалитьОбъекты (Global context.DeleteObjects)

Глобальный контекст (Global context)

УдалитьОбъекты (DeleteObjects)

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

Синтаксис:
УдалитьОбъекты(<СписокСсылок>, <Проверять>, <НайденныеДанные>, <ОбластьПоиска>, <ВключитьОбъекты>, <ИсключитьОбъекты>)
Параметры:

<СписокСсылок> (обязательный)
Тип: Массив.
Список ссылок на объекты, которые нужно удалить.

<Проверять> (необязательный)
Тип: Булево.
Определяет, выполнять ли контроль ссылочной целостности при выполнении процедуры. Истина - перед удалением проверяется, нет ли ссылок на удаляемый объект. Если есть, то объект не удаляется, а ссылки помещаются в таблицу значений <НайденныеДанные>. Ложь - проверка не выполняется.
Значение по умолчанию: Ложь.

<НайденныеДанные> (необязательный)
Тип: ТаблицаЗначений.
Содержит ссылки на найденные объекты в виде ТаблицаЗначений, состоящей из колонок с индексами: 0 - искомая ссылка; 1 - ссылка на объект, если найденная ссылка соответствует объектной таблице или значение, идентифицирующее запись необъектной таблицы; 2 - объект метаданных, которому соответствуют данные, в которых найдена ссылка.
В таблицу выводятся только непосредственно препятствующие удалению объекты (без рекурсии).

<ОбластьПоиска> (необязательный)
Тип: Массив.
Определяет область поиска объектов, которые следует удалить. Область устанавливается комбинацией разделителей, в состав которых включены объекты метаданных, среди данных которых следует выполнять поиск.
Элемент массива имеет тип Массив.
Элемент вложенного массива имеет тип:
Объект метаданных – Общий реквизит, разделяющий данные.

Строка – имя общего реквизита, разделяющего данные.
По умолчанию имеет значение Неопределено.
Допустимые значения:
Неопределено,

Массив с комбинациями разделителей, определяющий область поиска,

Пустой массив - область поиска определяется параметрами метода <ВключитьОбъекты> и <ИсключитьОбъекты>.
Примечание. Если комбинация разделителей содержит повторы, то вызывается исключение, т.к. в конфигурации не может быть объектов метаданных, дважды включенных в состав одного разделителя.
Значение по умолчанию: Неопределено.

<ВключитьОбъекты> (необязательный)
Тип: Массив.
Позволяет явно указать объекты метаданных, которые должны присутствовать в области поиска ссылок на объекты.
Элементом массива могут быть:
Объект метаданных.

Строка – полное имя объекта метаданных.
Допустимые значения:
Неопределено,

Пустой массив,

Массив объектов метаданных.

Значение по умолчанию: Неопределено.

<ИсключитьОбъекты> (необязательный)
Тип: Массив.
В качестве элементов массива могут выступать:
Объект метаданных,

Строка – полное имя объекта метаданных.
Свойство позволяет явно указать объекты метаданных, которые следует исключить из области поиска ссылок на объекты.
Допустимые значения:
Неопределено

Пустой массив (нет объектов, которые необходимо дополнительно включить в область поиска).

Массив объектов метаданных.

Значение по умолчанию: Неопределено.
Описание:

Удаляет объекты, ссылки на которые переданы в параметре <СписокСсылок>.
При проверке ссылочной целостности поиск осуществляется среди всех данных, из которых могут быть ссылки на переданные объекты. Если на какой-либо объект нет доступа, то вызывается исключение.
Требует монопольного режима доступа к базе данных.

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

Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Вызов метода выполняет обращение к серверу.

Примечание:
Ответственность за удаление объектов, на которые, возможно, имеются ссылки в недоступных данному сеансу данных, возлагается на вызывающего метод.

Если выполняется контроль ссылочной целостности, поиск ссылок выполняется в области данных, определенной параметрами <ОбластьПоиска>, <ВключитьОбъекты> и <ИсключитьОбъекты>.
Ссылки на найденные объекты возвращаются в таблице значений со следующими колонками:
Поле 1 - Исходная ссылка;

Поле 2 - Ссылка на объект (для объектных данных) или значение (для необъектных данных);

Поле 3 - Объект метаданных, которому соответствуют данные, в которых найдена ссылка;

Поле 4 - Комбинации разделителей, идентифицирующих подобласть, в данных которой найдена ссылка на объект.
Если необходимо осуществлять поиск ссылок на объекты в подобластях, то необходимо в параметре <ОбластьПоиска> указывать комбинации разделителей с использованием неустановленных в сеансе разделителей. Если в комбинации разделителей будут указаны только реквизиты, разделяющие данные в режиме НезависимоИСовместно (помимо любых реквизитов, установленных в сеансе), то поиск будет выполняться в этих объектах, как среди доступных данных и результаты будут записаны в поле 2. Если хотя бы один неустановленный в сеансе реквизит, разделяет данные в режиме Независимо, то будет выполнена проверка наличия ссылок в подобласти и возвращены значения разделителей, идентифицирующих подобласть. Результат будет записан в поле 4.

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

У текущего пользователя должен быть доступ на запись параметров сеанса, отвечающих за использование и за значение реквизита.

Этот реквизит не является безопасным. - Требование актуально для информационных баз, опубликованных на веб-сервере.
В разделенном режиме метод не устанавливает монопольного режима доступа, а использует управляемые блокировки с учетом текущего разделения.

На мобильной платформе параметры <ОбластьПоиска>, <ВключитьОбъекты>, <ИсключитьОбъекты> игнорируются.
Пример:

// удаление помеченных объектов с контролем ссылочной целостности

Помеченные = НайтиПомеченныеНаУдаление();
Найденные = 0;
УдалитьОбъекты(Помеченные, Истина, Найденные);
Для каждого Ссылка из Найденные Цикл
СтрСообщения = "Объект не удален: " + СокрЛП(Ссылка[0]);
СтрСсылка = ", используется в " + СокрЛП(Ссылка[1]);
Сообщить (СтрСообщения + СтрСсылка);
КонецЦикла;

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

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

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

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

Пометка, найденная ссылка и контролируемое удаление: почему один объект останется

На собственных трёх сохранённых записях увидеть разницу между пометкой и удалением, проверить настоящую зависимость USE85→BLOCK85 и отдельно согласовать удаление только свободного FREE85.

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

Полный общий client-only модуль новой собственной Windows FileCF8.5.1.1343, только толстый обычный клиент. Реальные записи/монополия/удаление лишь будущие ручные этапы со своим явным согласием.

Подготовка

  1. Только совершенно новая собственная пустая File ИБ C:\1c-labs\OwnDeleteRefs85_3a8e7d41-9216-4bba-86ac-610c70f427d9\IB на отдельном учебном Windows стенде8.5.1.1343. Если путь/регистрация уже существуют — не переиспользуйте и не очищайте, остановитесь. Exact File="путь"; проверяется буквально; UUID в пути — лабораторная метка, не измеренный UUIDИБ. Здесь VM/каталог/CF/ИБ/данные не создавались и1С не запускалась.

  2. Конфигурация УчебноеУдалениеСсылок85: РежимСовместимостиНеИспользовать, ОсновнойРежимЗапускаОбычноеПриложение. Сервис→Параметры→Общие→вид редактирования конфигурации для режима запуска «Управляемое приложение и обычное приложение». Это параметр редактора, не metadataSupportedRunModes. Два справочника, одна обработка, один общий модуль и одна роль. Остальные прикладные объекты/разделители/расширения/параметрысеанса/подписки/задания/источники/хранилища отсутствуют; модули объектов/менеджеров пустые.

  3. Справочник Кандидаты85: неиерархический, без владельцев/табличных частей/предопределённых. КодСтрока12, Наименование80, автонумерацияНет, контрольуникальностиДа. Реквизиты Маркер85 единственныйтипСтрока36, Сумма85 единственныйтипЧисло10,0. Справочник Использования85: те же стандартные настройки, реквизиты Маркер85Строка36, Сумма85Число10,0, Кандидат85 единственныйтипСправочникСсылка.Кандидаты85. Никаких иных реквизитов или связей.

  4. Роль Уборка85Администратор только своей новойCF: Администрирование для списка пользователей, АктивныеПользователи, право установки монопольного режима; все права чтения/добавления/изменения/пометки/удаления обоих собственных справочников и использования обработки. Без RLS/ограничений чтения/разделителей. Единственный пользователь Уборка85Ученик с этой ролью; подключается только он. Это полная учебная роль, не рекомендации производственных прав.

  5. ДО вставки startup вручную сохраните ровно3записи обычными стандартными формами: Кандидаты85 BLOCK85/Сохранить/Сумма85=100 и FREE85/Удалить/200; Использования85 USE85/Связь/100, Кандидат85=реально сохранённый BLOCK85, не UUID-литерал. Маркер85 у всех3a8e7d41-9216-4bba-86ac-610c70f427d9; ПредопределенныйFalse. Обе записи кандидатов вручную пометьте на удаление, USE85 НЕ помечайте. Пометка не равна физическому удалению: USE85 сохраняет настоящую ссылку на BLOCK85.

  6. ОбщийМодуль УборкаПамять85: ГлобальныйНет, КлиентОбычноеПриложениеДа, КлиентУправляемоеПриложениеНет, СерверНет, ВнешнееСоединениеНет, ПривилегированныйНет, повторноеиспользованиеНеИспользовать. MAIN CODE полностью в этот модуль. Обработка Уборка85: единственная основная ОБЫЧНАЯ форма Пульт85, форма сама ничего не записывает при открытии. Реквизиты формы Подтверждаю85Булево начальноеFalse, Статус85Строка2000readonly. Кнопки Монопольно85/Удалить85: обе nativeНажатие→Этап85(Кнопка); формаПриОткрытии0→ПриОткрытии. FORM целиком в модуль; APPLICATION целиком в МодульОбычногоПриложения. Ни событие, ни кнопку вручную не вызывают.

  7. Сохраните/обновите вручную исключительно новуюCF. Закройте Конфигуратор и любые другие подключения своего стенда; не открывайте второе окно/фоновые сеансы/консоль запросов. Запустите толстый обычный клиент. Открытие читает полный объём обоих собственных справочников безГДЕ, сверяет все поля и actualGetObject; записей и блокировки пока нет.

  8. Первое отдельное согласие: поставьте флажок и нажмите Монопольно85. До установки блокировки код заново проверяет exactFile/схему/пользователя/единственное подключение/полный fixture. NativeУстановитьМонопольныйРежимTrue применяется только к своей новойИБ без разделителей; нет завершения чужих сеансов/параметров bypass. Затем getter и полный readback. Неудача запрещает продолжение, блокировка может уже существовать: код не снимает её blindfinally.

  9. В 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.

  10. Второе НОВОЕ согласие: прочитайте статус, снова поставьте флажок и нажмите Удалить85. Список refs получен заново, полный source/зависимость сверены перед процедурой. Проверять всегдаИстина: native defaultЛожь опасен и не используется. Процедура УдалитьОбъекты не возвращает значение: Оставшиеся — native выходной параметр. Ожидаемый будущий outcome: FREE85 физически исчезнет, BLOCK85 не удалится из-заUSE85, обе сохранённые ссылки/все поля останутся. Полные запросы подтверждают кандидатов300→100 и объектов3→2, новое marked-search1 и прежнюю собственную зависимость.

  11. Любое исключение/лишняя зависимость/чужая ссылка/неожиданная структура выходной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.Открыть();
#Иначе
    ВызватьИсключение "Только собственный толстый обычный клиент";
#КонецЕсли
КонецПроцедуры

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

  1. Вручную подготовить собственную новуюCF и actual2marked кандидата100/200 плюс одну непомеченную actualUsage100.

  2. Полным query/GetObject подтвердить каждую собственную ссылку/поле и единственный сеанс, затем отдельно согласовать собственную монополию.

  3. FindMarked с тремя явными scope массивами даёт только2actualref; FindByRefs с четырьмя аргументами даёт собственную dependency, не придуманную ссылку.

  4. Новое согласие → свежий полный whitelist → DeleteObjects(6args, CheckTrue, actualoutputTable) без назначения return.

  5. Проверить actualremaining dependency и оба полных sources: только свободная запись исчезла, blocked и usage полностью сохранены, actual numeric300→100/objects3→2.

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

  1. Проверяются обе ссылки кандидатных объектов, собственная ссылка использования и все3 positional поля dependency, не только число строк.

  2. У неизвестного/дублированного refs или несоответствующего metadata/ref/marker/amount fullguard отказывает доdelete.

  3. Статические native/callback/readonly/arity/consent/owner/scope mutations; реальных запусков и удаления0.

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

Будущий ручной результат: FREE85 удалён, BLOCK85 и USE85 сохранены; сумма кандидатов300→100, объекты3→2, oneactualremaining dependency. Здесь только полный authored код/подготовка и статические проверки;1С/ИБ/БД/UI/runtime0.

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

  1. DeleteObjects может удалить и непомеченный объект, если его ref передан: список здесь берётся изactual marked-search и строгого own whitelist, не из unknowninput.

  2. Один сеанс и монопольная блокировка не оправдывают удаление production. Поиск ограничен доступностью/разделением/правами; отсутствие чужих источников задаётся именно новой собственной минимальнойCF, не выводится из одной таблицы зависимостей.

  3. NativeDelete parameter описывает3 positional columns, notes также упоминают4-е поле комбинаций разделителей. Для своейNoSplit fixture принимается только реальный3-column return; иной shape — стоп, не угадывание default четвёртого поля/не обрезание. Поля/порядок nativecolumnnames не выдумываются.

  4. Remaining показывает только непосредственно препятствующие объекты, не рекурсивный граф. Этот урок имеет ровноодну заранее подготовленную непосредственную связь и не обещает обработки произвольной конфигурации.

  5. Никакой обещанной атомарности нескольких этапов/rollback. Исключение после setter/delete оставляет неизвестный исход; штатный native результат и полный readback проверяются отдельно от статических тестов.

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

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

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

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

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