Почему документ не удаляется в 1С из-за ссылки на задачу исполнителя и как это исправить

Программист 1С v8.3 (Обычные формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При попытке окончательного удаления помеченных объектов в «1С:Зарплата и Управление Персоналом» (или других типовых конфигурациях) пользователи нередко сталкиваются с ситуацией: документ помечен на удаление, но стандартная процедура сообщает о невозможности удаления из-за наличия ссылки в объекте ЗадачаИсполнителя. При этом пользователь или бухгалтер утверждают, что задача уже выполнена, закрыта или даже помечена на удаление. Разберем детально, почему так происходит и какими способами можно разорвать эту связь и удалить документ.

Выясним причину: почему платформа видит ссылку в «удаленной» задаче

Проанализируем механику работы платформы и типовых конфигураций, чтобы понять корень проблемы:

  1. Интерфейсный отбор вместо фактического удаления. В интерфейсе списков задач практически всегда установлен фильтр по умолчанию: отображать только невыполненные задачи (Выполнена = Ложь). Когда пользователь нажимает кнопку завершения задачи, она просто исчезает из текущего списка. Пользователь считает задачу удаленной, однако физически объект Задача.ЗадачаИсполнителя остается в информационной базе, а его реквизит (например, Предмет или Объект) продолжает хранить прямую ссылку на документ начисления зарплаты.
  2. Пометка на удаление не очищает реквизиты. Если задачу просто пометили на удаление, ссылка на документ в ней сохраняется. Контроль ссылочной целостности платформы не позволит удалить документ до тех пор, пока ссылающийся объект физически присутствует в базе данных.
  3. Ограничения прав доступа (RLS). Если операцию поиска или удаления выполняет пользователь с ограниченными правами, платформа видит блокирующую ссылку на уровне СУБД, но не может отобразить саму задачу в интерфейсе из-за ограничений по организации или подразделению.
  4. Особенности тестирования и исправления. Стандартное тестирование и исправление (ТИИ) проверяет целостность ссылок, но если ссылка ведет на существующий, пусть и помеченный объект, система считает такую связь абсолютно корректной и не предпринимает никаких действий.

Способ 1. Совместное удаление взаимосвязанных объектов через штатный интерфейс

Рассмотрим порядок действий без доработки конфигурации и написания внешнего кода:

  1. Откроем список задач исполнителей и снимем в форме все установленные отборы (включая отбор по выполненным задачам).
  2. Найдем задачу, номер и дату которой сообщает система контроля удаления.
  3. Установим на задачу пометку на удаление.
  4. Запустим обработку «Удаление помеченных объектов».
  5. Важный момент: в списке объектов, подлежащих удалению, необходимо отметить флажками одновременно и сам документ начисления, и найденную задачу исполнителя. В этом случае платформа удалит оба связанных объекта в рамках одной транзакции без конфликта зависимостей.

Если найти задачу через интерфейс затруднительно, воспользуемся штатным инструментом Поиск ссылок на объект (меню «Все функции» / «Стандартные» или «Операции» в обычном интерфейсе). Найдя ссылку, перейдем непосредственно в карточку задачи и пометим её.

Способ 2. Программное удаление зависших задач исполнителей

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

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


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

Обратите внимание на риски: метод Удалить() осуществляет непосредственное удаление объекта из базы данных без проверки ссылочной целостности. Если задача привязана к активному маршруту бизнес-процесса, прямое удаление может привести к образованию «битых» ссылок вида <Объект не найден> в точках маршрута или служебных регистрах сведений. Поэтому перед массовым удалением обязательно создадим резервную копию базы.

Способ 3. Очистка реквизита задачи без её удаления

Если для регламентированного или управленческого учета требуется сохранить факт выполнения задачи сотрудником, физически удалять задачу не следует. Вместо этого очистим реквизит, указывающий на удаляемый документ.

Разберем по шагам, как очистить реквизит задачи программно:


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

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

← На главную