Как настроить автоматическую регистрацию документа после завершения процесса согласования в 1С:Документооборот?

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

В типовой конфигурации 1С:Документооборот (особенно в версии ПРОФ, где отсутствует механизм гибких комплексных процессов) часто возникает задача: автоматически зарегистрировать внутренний документ сразу после того, как все согласующие лица успешно утвердили документ. Разберем, как реализовать авторегистрацию через дополнительный обработчик бизнес-событий, проанализируем возможные ошибки при работе с нумерацией и рассмотрим варианты программного кода.

Принцип работы механизма бизнес-событий

Для автоматизации действий при наступлении определенных условий в системе используется механизм бизнес-событий:

  1. При завершении процесса система фиксирует событие в регистре сведений ПроизошедшиеБизнесСобытия.
  2. Регламентное задание Обработка произошедших бизнес-событий считывает накопившиеся записи и запускает назначенные обработчики.
  3. Обработчик проверяет тип процесса, его результат и выполняет регистрацию предмета (документа).

Вариант 1. Оптимальный код авторегистрации через типовые методы делопроизводства

Рассмотрим наиболее лаконичный и безопасный способ. Вместо ручной генерации номеров воспользуемся штатной функцией Делопроизводство.ЗарегистрироватьПредмет(). Она самостоятельно проверяет настройки нумератора, получает числовой и строковый номера с учетом индексов и префиксов, устанавливает дату регистрации и меняет состояние документа.

В обработчике бизнес-события (подписка Завершение процесса) укажем следующий код:


УстановитьПривилегированныйРежим(Истина);

БизнесПроцесс = Событие.Источник;

Если ТипЗнч(БизнесПроцесс) = Тип("БизнесПроцессСсылка.Согласование") 
    И БизнесПроцесс.РезультатСогласования = Перечисления.РезультатыСогласования.Согласовано Тогда
    
    ТипыДокументов = Новый Массив;
    ТипыДокументов.Добавить(Тип("СправочникСсылка.ВнутренниеДокументы"));
    
    ВидыДокументов = Новый Массив;
    ВидыДокументов.Добавить(Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Служебная записка"));
    
    // Получаем массив основных предметов процесса согласования
    ОсновныеПредметы = МультипредметностьКлиентСервер.ПолучитьМассивПредметовОбъекта(БизнесПроцесс, ТипыДокументов, Истина);
    
    Для Каждого Предмет Из ОсновныеПредметы Цикл
        
        Если ВидыДокументов.Найти(Предмет.ВидДокумента) <> Неопределено Тогда
            
            // Проверяем, не был ли документ зарегистрирован ранее
            Если ЗначениеЗаполнено(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Предмет, "РегистрационныйНомер")) Тогда
                Продолжить;
            КонецЕсли;
            
            СообщениеОбОшибке = "";
            Если Делопроизводство.ЗарегистрироватьПредмет(Предмет, СообщениеОбОшибке) Тогда
                // Фиксируем состояние в регистре сведений
                Делопроизводство.ЗаписатьСостояниеДокумента(
                    Предмет, 
                    ТекущаяДатаСеанса(), 
                    Перечисления.СостоянияДокументов.Зарегистрирован, 
                    БизнесПроцесс.Автор);
            Иначе
                // При необходимости записываем ошибку в журнал регистрации
                ЗаписьЖурналаРегистрации(
                    "Авторегистрация документа",
                    УровеньЖурналаРегистрации.Ошибка,,,
                    СообщениеОбОшибке);
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецЕсли;

Вариант 2. Прямое формирование номера через модуль «Нумерация»

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


УстановитьПривилегированныйРежим(Истина);

БизнесПроцесс = Событие.Источник;

Если ТипЗнч(БизнесПроцесс) = Тип("БизнесПроцессСсылка.Согласование") 
    И БизнесПроцесс.РезультатСогласования = Перечисления.РезультатыСогласования.Согласовано Тогда
    
    ТипыДокументов = Новый Массив;
    ТипыДокументов.Добавить(Тип("СправочникСсылка.ВнутренниеДокументы"));
    
    ВидыДокументов = Новый Массив;
    ВидыДокументов.Добавить(Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Служебная записка"));
    
    ОсновныеПредметы = МультипредметностьКлиентСервер.ПолучитьМассивПредметовОбъекта(БизнесПроцесс, ТипыДокументов, Истина);
    
    Для Каждого Предмет Из ОсновныеПредметы Цикл
        
        Если ВидыДокументов.Найти(Предмет.ВидДокумента) <> Неопределено Тогда
            
            Нумератор = Нумерация.ПолучитьНумераторДокумента(Предмет);
            
            Если Не ЗначениеЗаполнено(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Предмет, "РегистрационныйНомер")) 
                И ЗначениеЗаполнено(Нумератор) Тогда
                
                ОбъектДокумента = Предмет.ПолучитьОбъект();
                ДатаРегистрации = ТекущаяДатаСеанса();
                
                ОбъектДокумента.ДатаРегистрации = ДатаРегистрации;
                
                // Формируем числовой номер
                СтруктураПараметров = НумерацияКлиентСервер.ПолучитьПараметрыНумерации(ОбъектДокумента);
                Нумерация.СформироватьЧисловойНомерДокумента(СтруктураПараметров, ОбъектДокумента.ЧисловойНомер);
                
                // Формируем строковый номер
                ОписанияОшибок = Новый СписокЗначений;
                Нумерация.СформироватьСтроковыйНомерДокумента(СтруктураПараметров, ОбъектДокумента.РегистрационныйНомер, ОписанияОшибок);
                
                Если ЗначениеЗаполнено(ОбъектДокумента.РегистрационныйНомер) Тогда
                    ОбъектДокумента.Зарегистрировал = БизнесПроцесс.Автор;
                    ОбъектДокумента.Записать();
                    
                    Делопроизводство.ЗаписатьСостояниеДокумента(
                        ОбъектДокумента.Ссылка, 
                        ДатаРегистрации, 
                        Перечисления.СостоянияДокументов.Зарегистрирован, 
                        БизнесПроцесс.Автор);
                КонецЕсли;
                
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецЕсли;

Типичные ошибки и почему авторегистрация может не сработать

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

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

Рекомендации по отладке

Если бизнес-событие отработало, но номер не появился:

  1. Откройте регистр сведений ПроизошедшиеБизнесСобытия и проверьте, создалась ли запись по процессу и снят ли признак необходимости обработки.
  2. Запустите обработку регламентных заданий вручную через форму Регламентные и фоновые задания (кнопка Выполнить сейчас).
  3. Для интерактивной отладки временно вынесите код обработчика в отдельный серверный общий модуль и подключитесь отладчиком к фоновому заданию на сервере 1С.
← На главную