При попытке окончательного удаления помеченных объектов в «1С:Зарплата и Управление Персоналом» (или других типовых конфигурациях) пользователи нередко сталкиваются с ситуацией: документ помечен на удаление, но стандартная процедура сообщает о невозможности удаления из-за наличия ссылки в объекте ЗадачаИсполнителя. При этом пользователь или бухгалтер утверждают, что задача уже выполнена, закрыта или даже помечена на удаление. Разберем детально, почему так происходит и какими способами можно разорвать эту связь и удалить документ.
Проанализируем механику работы платформы и типовых конфигураций, чтобы понять корень проблемы:
Выполнена = Ложь). Когда пользователь нажимает кнопку завершения задачи, она просто исчезает из текущего списка. Пользователь считает задачу удаленной, однако физически объект Задача.ЗадачаИсполнителя остается в информационной базе, а его реквизит (например, Предмет или Объект) продолжает хранить прямую ссылку на документ начисления зарплаты.Рассмотрим порядок действий без доработки конфигурации и написания внешнего кода:
Если найти задачу через интерфейс затруднительно, воспользуемся штатным инструментом Поиск ссылок на объект (меню «Все функции» / «Стандартные» или «Операции» в обычном интерфейсе). Найдя ссылку, перейдем непосредственно в карточку задачи и пометим её.
Бывают ситуации, когда задач накопилось слишком много или они генерируются бизнес-процессами регулярно и загромождают базу. В таком случае разберем программный способ поиска и физического удаления выполненных задач через внешнюю обработку.
Посмотрим на пример кода, который находит выполненные задачи за определенный период и удаляет их из базы данных напрямую:
Процедура УдалитьВыполненныеЗадачи()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Задачи.Ссылка КАК Ссылка
|ИЗ
| Задача.ЗадачаИсполнителя КАК Задачи
|ГДЕ
| Задачи.Выполнена = ИСТИНА
| И Задачи.Дата < ДОБАВИТЬКДАТЕ(&АктуальныйПериод, МЕСЯЦ, -3)";
Запрос.УстановитьПараметр("АктуальныйПериод", ТекущаяДата());
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Попытка
ОбъектЗадачи = Выборка.Ссылка.ПолучитьОбъект();
Если ОбъектЗадачи <> Неопределено Тогда
ОбъектЗадачи.Удалить();
КонецЕсли;
Исключение
Сообщить("Не удалось удалить задачу: " + Выборка.Ссылка + " по причине: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Обратите внимание на риски: метод Удалить() осуществляет непосредственное удаление объекта из базы данных без проверки ссылочной целостности. Если задача привязана к активному маршруту бизнес-процесса, прямое удаление может привести к образованию «битых» ссылок вида <Объект не найден> в точках маршрута или служебных регистрах сведений. Поэтому перед массовым удалением обязательно создадим резервную копию базы.
Если для регламентированного или управленческого учета требуется сохранить факт выполнения задачи сотрудником, физически удалять задачу не следует. Вместо этого очистим реквизит, указывающий на удаляемый документ.
Разберем по шагам, как очистить реквизит задачи программно:
Процедура ОчиститьСсылкуВЗадаче(СсылкаНаЗадачу)
ОбъектЗадачи = СсылкаНаЗадачу.ПолучитьОбъект();
Если ОбъектЗадачи <> Неопределено Тогда
// Очищаем реквизит, ссылающийся на удаляемый документ
ОбъектЗадачи.Предмет = Неопределено;
Попытка
ОбъектЗадачи.Записать();
Сообщить("Ссылка на документ в задаче успешно очищена.");
Исключение
Сообщить("Ошибка при записи задачи: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Также для этой цели можно применить типовую сервисную обработку Поиск и замена значений, заменив ссылку на удаляемый документ в задаче на пустое значение соответствующего типа. После разрыва связи документ начисления зарплаты успешно удалится стандартной обработкой удаления помеченных объектов.