Как реализовать двойную нумерацию обращений граждан в 1С:Документооборот?

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

В делопроизводстве государственных учреждений и крупных коммерческих организаций часто возникает задача ведения двойного учета обращений граждан. Типичный сценарий выглядит следующим образом:

  1. Необходимо вести общую сквозную нумерацию по всем поступающим обращениям (письменным, устным, личным), чтобы иметь единый реестр и понимать общий объем входящего потока.
  2. Одновременно с этим требуется вести отдельную нумерацию исключительно по письменным обращениям граждан для формирования обособленного журнала регистрации.

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

---

Шаг 1. Настройка сквозной нумерации по всем видам обращений

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

Рассмотрим пошагово, как это сделать:

  1. Перейдем в раздел НСИ (или Настройки в версии 3.0) и откроем справочник Виды документов.
  2. Создадим три разных вида документов (например, внутренних или входящих, в зависимости от принятой у вас методологии):
    • Письменное обращение
    • Устное обращение
    • Личное обращение
  3. Перейдем в раздел НСИ -> Нумераторы и нажмем кнопку Создать. Назовем новый нумератор Общий нумератор обращений граждан.
  4. Настроим формат номера в соответствии с требованиями вашей организации (например, добавим префикс или индекс года).
  5. Перейдем на вкладку Действует для в карточке нумератора и установим флажки напротив всех трех созданных нами видов документов: Письменное обращение, Устное обращение и Личное обращение.

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

---

Шаг 2. Реализация второго (отдельного) номера для письменных обращений

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

Вариант А. Настройка связанных документов (Архитектурный подход без программирования)

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

Разберем этот процесс по шагам:

  1. Создаем вид документа Обращение гражданина. Для него настраиваем сквозной нумератор (как описано в Шаге 1). При регистрации этот документ всегда будет получать первый (общий) номер.
  2. Создаем второй вид документа — например, Карточка письменного обращения или Дело по письменному обращению. Для этого вида документа настраиваем свой собственный, отдельный нумератор, который будет вести независимую последовательность номеров.
  3. В настройках связей документов (раздел Настройки и администрирование -> Связи документов) создаем новый тип связи, например, Содержит / Входит в состав или На основании.
  4. При поступлении письменного обращения пользователь регистрирует общий документ, а затем в один клик создает на его основании связанную карточку письменного обращения.

Преимущества метода:

---

Вариант Б. Дополнительный реквизит + Автоматическое заполнение через бизнес-события

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

Для начала создадим сам реквизит:

  1. Перейдем в раздел Настройки -> Наборы дополнительных реквизитов и сведений.
  2. Найдем набор для нашего вида документа Письменное обращение и добавим новый дополнительный реквизит с наименованием Второй регистрационный номер (тип значения — Строка или Число).
  3. В настройках отображения укажем, что данный реквизит должен выводиться на форму документа и быть доступен для просмотра.

Если оставить настройку в таком виде, пользователям придется вводить второй номер вручную, что приведет к ошибкам и дублированию. На форуме предлагалось использовать регламентные задания БСП или расширения конфигурации, однако в 1С:Документооборот существует гораздо более элегантный механизм — Обработчики бизнес-событий, доступный прямо в пользовательском режиме (для версий КОРП и ДГУ).

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

Важный технический нюанс: конкурентная запись и блокировка данных.

Если несколько делопроизводителей будут регистрировать письменные обращения одновременно, существует риск возникновения одинаковых номеров. Чтобы этого избежать, в коде обработчика обязательно нужно использовать объект БлокировкаДанных.

Посмотрим на пример шаблона кода для обработчика бизнес-события:


// Скрипт выполняется в контексте регистрации документа
ДокументОбъект = Событие.Источник;

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

Преимущества метода:

---

Вариант В. Использование скриптов автозаполнения шаблонов файлов

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

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

  1. Создаем шаблон файла в формате DOCX и прикрепляем его к виду документа Письменное обращение.
  2. Открываем настройки автозаполнения шаблона.
  3. Вместо простого сопоставления полей переходим на вкладку Скрипты и создаем новый скрипт для заполнения нужного поля в файле.
  4. Пишем простой алгоритм, который динамически вычисляет второй номер "на лету" на основе текущей даты и сквозного регистрационного номера, после чего подставляет результат в формируемый файл.

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

---

Резюме

Мы проанализировали различные подходы к реализации двойной нумерации обращений граждан в 1С:Документооборот. Выбор конкретного метода зависит от технических требований и готовности к написанию небольших скриптов:

← На главную