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