Как создать уникальную нумерацию в дополнительном реквизите документа для разных организаций с учетом префиксов в 1С:Комплексная автоматизация?

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

Мы рассмотрим распространенную задачу, которая часто возникает в крупных информационных системах, таких как 1С:Комплексная автоматизация, особенно когда в одной базе ведется учет по нескольким юридическим лицам или подразделениям. Речь пойдет о необходимости создания индивидуальной, уникальной нумерации для документов в дополнительном реквизите, которая будет зависеть от организации и иметь свой уникальный префикс.

Представьте ситуацию: у нас есть основная организация и несколько дополнительных, каждая со своим уникальным префиксом. В документе, помимо стандартного номера, требуется вести отдельный «бухгалтерский номер» в дополнительном реквизите, который формируется по своим правилам: он должен быть уникальным для каждой организации и включать ее префикс. Такая задача особенно актуальна при переносе данных из других систем (например, 1С:Бухгалтерия предприятия), где документы уже имеют свои номера, и нам нужно сохранить их логику нумерации или продолжить ее в новой системе.

Начнем с анализа проблематики и предложим комплексное решение, которое обеспечит гибкость и надежность.

Механизмы реализации уникальной нумерации

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

1. Использование отдельного регистра сведений или справочника-нумератора

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

Регистр сведений "НастройкиНумерацииДокументов":

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

  1. Измерения:
    • ВидДокумента (Тип: Строка или Перечисление.ВидыДокументов, если мы хотим строго типизировать) — определяет, для какого типа документа ведется нумерация (например, "РеализацияТоваровУслуг", "ПоступлениеТоваровУслуг").
    • Организация (Тип: СправочникСсылка.Организации) — указывает, для какой именно организации ведется нумерация.
    • Период (Тип: Дата, для периодического регистра) — если нумерация должна обнуляться, например, ежегодно.
  2. Ресурсы:
    • ТекущийНомер (Тип: Число, Неотрицательное) — хранит последний выданный порядковый номер.
  3. Реквизиты:
    • ШаблонНомера (Тип: Строка) — опционально, для более гибкого формирования номера (например, "ПРФ-{Номер:5}-ГГГГ").

Справочник "Нумераторы":

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

  1. Реквизиты справочника:
    • ВидДокумента (Аналогично регистру сведений)
    • Организация (Аналогично регистру сведений)
    • ТекущийНомер (Тип: Число)
    • Префикс (Тип: Строка) — можно хранить здесь, если префикс отличается от основного префикса организации или требуется более гибкая настройка.
    • НачалоПериода, КонецПериода (Тип: Дата) — для нумерации по периодам.

Принцип работы:

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

  1. Найти запись, соответствующую текущему виду документа и организации (и, возможно, периоду).
  2. Получить значение ТекущийНомер.
  3. Инкрементировать его (увеличить на 1).
  4. Записать новое значение обратно в регистр/справочник, обеспечивая его сохранение.
  5. Использовать этот инкрементированный номер для формирования полного номера с учетом префикса.

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

2. Расширения и подписки на события

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

Подписка на событие:

Мы создаем подписку на событие, которое срабатывает в момент, когда документ готов к записи или когда ему устанавливается новый номер. Часто используются следующие события:

Пример логики в обработчике подписки:

Предположим, у нас есть дополнительный реквизит документа с именем НомерБух.


Процедура ПриЗаписиДокументаУстановитьБухНомер(Источник, Отказ) Экспорт

    // Проверяем, что это тот тип документа, для которого нужна наша нумерация
    Если НЕ ТипЗнч(Источник) Соответствует Тип("ДокументОбъект.РеализацияТоваровУслуг") И
       НЕ ТипЗнч(Источник) Соответствует Тип("ДокументОбъект.ПоступлениеТоваровУслуг") Тогда
        Возврат;
    КонецЕсли;

    // Получаем организацию документа
    ОрганизацияДокумента = Источник.Организация;
    Если ОрганизацияДокумента = Неопределено Тогда
        Сообщить("Не указана организация в документе. Невозможно сформировать бухгалтерский номер.", СтатусСообщения.Важное);
        Отказ = Истина;
        Возврат;
    КонецЕсли;

    // Проверяем, установлен ли уже номер. Возможно, он был перенесен или уже задан вручную.
    // Если номер уже есть и документ не новый, то не генерируем новый.
    Если НЕ Источник.ЭтоНовый И НЕ ПустаяСтрока(Источник.ДополнительныеРеквизиты.Найти("НомерБух").Значение) Тогда
        Возврат;
    КонецЕсли;

    // --- Блокировка для обеспечения уникальности номера ---
    БлокировкаДанных = Новый БлокировкаДанных;
    ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрСведений.НастройкиНумерацииДокументов"); // или Справочник.Нумераторы
    ЭлементБлокировки.УстановитьЗначение("ВидДокумента", ТипЗнч(Источник).Имя);
    ЭлементБлокировки.УстановитьЗначение("Организация", ОрганизацияДокумента);
    // Если регистр периодический, добавить период
    // ЭлементБлокировки.УстановитьЗначение("Период", НачалоГода(ТекущаяДата())); 
    
    БлокировкаДанных.Установить("ДляИзменения");
    // --------------------------------------------------------

    Попытка
        // Получаем префикс организации (если он не в нумераторе)
        // Предположим, префикс хранится в реквизите справочника Организации
        ПрефиксОрганизации = СокрЛП(ОрганизацияДокумента.Префикс);
        Если ПустаяСтрока(ПрефиксОрганизации) Тогда
            Сообщить("Не указан префикс для организации " + ОрганизацияДокумента.Наименование + 
                     ". Бухгалтерский номер не будет сформирован.", СтатусСообщения.Важное);
            Отказ = Истина;
            Возврат;
        КонецЕсли;

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

        Запрос.УстановитьПараметр("ВидДокумента", ТипЗнч(Источник).Имя);
        Запрос.УстановитьПараметр("Организация", ОрганизацияДокумента);

        РезультатЗапроса = Запрос.Выполнить();
        Выборка = РезультатЗапроса.Выбрать();

        НовыйПорядковыйНомер = 1;
        Если Выборка.Следующий() Тогда
            НовыйПорядковыйНомер = Выборка.ТекущийНомер + 1;
        КонецЕсли;
        
        // Формируем строку номера с ведущими нулями
        ФорматированныйНомер = Формат(НовыйПорядковыйНомер, "ЧЦ=5; ЧВН=; ЧГ=0"); // Например, 00001, 00010
        СформированныйБухНомер = ПрефиксОрганизации + "-" + ФорматированныйНомер;

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

    Исключение
        Сообщить("Ошибка при формировании бухгалтерского номера: " + ОписаниеОшибки(), СтатусСообщения.Важное);
        Отказ = Истина;
    КонецПопытки;

КонецПроцедуры

Важные моменты при создании обработчика:

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

Формирование номера:

Мы можем задать шаблон номера. Например, если префикс организации "ОРГ1", а текущий номер "5", то итоговый номер может быть "ОРГ1-00005". Функция Формат() в 1С очень удобна для добавления ведущих нулей.

Особенности и рекомендации

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

  1. Уникальность и ее гарантии:

    Мы должны абсолютно быть уверены, что генерируемый нами "бухгалтерский номер" будет уникален в рамках каждой организации (или даже глобально, если это требуется). Комбинация префикса организации, года (если нумерация сбрасывается ежегодно) и порядкового номера должна быть достаточна для гарантии уникальности. Рекомендуем использовать индекс уникальности в регистре сведений или справочнике, если это технически возможно, для измерения ВидДокумента, Организация и Период.

  2. Производительность системы:

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

  3. Обработка исключений и ошибок:

    Наш код должен быть устойчивым к сбоям. Что произойдет, если не найден префикс организации? Что, если запись в регистр нумерации не удалась? Используйте конструкции Попытка...Исключение...КонецПопытки и информируйте пользователя о проблемах, чтобы он мог предпринять корректирующие действия.

  4. Перенос данных из других систем:

    Особое внимание уделим ситуации, когда данные переносятся из 1С:Бухгалтерия предприятия (БП) в 1С:Комплексная автоматизация (КА). Если старые номера из БП должны сохраняться в дополнительном реквизите, то:

    • На этапе миграции: При первоначальном переносе документов необходимо обеспечить, чтобы наш обработчик нумерации не срабатывал или работал в специальном режиме, просто записывая существующие номера из БП в дополнительный реквизит.
    • После миграции: Для новых документов, создаваемых уже в КА, должен использоваться описанный нами механизм генерации уникальных номеров. Важно предусмотреть, чтобы диапазон новых номеров не пересекался с перенесенными, если это нежелательно и может привести к коллизиям при уникальности. Мы можем "стартовать" нумерацию для новых документов с номера, следующего за максимальным перенесенным.
  5. Стандартная нумерация 1С:

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

  6. GUID как связь между базами:

    Для связывания документов между различными базами 1С (например, между КА и БП) GUID (Globally Unique Identifier) играет ключевую роль. Каждый объект 1С (документ, справочник и т.д.) имеет свой уникальный GUID, который является глобально уникальным и не меняется при переносе объекта между базами или при изменении его номера. Это позволяет однозначно идентифицировать один и тот же документ в разных системах, независимо от его номера или префикса. Поэтому, даже если вы используете свою собственную нумерацию, связь по GUID всегда остается наиболее надежным способом сопоставления объектов.

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

← На главную