Как изменить нумерацию документов "Заказ покупателя" в 1С:УНФ с учетом контрагента, даты и ежемесячным обнулением?

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

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

Общие принципы нумерации документов в 1С:УНФ

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

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

В 1С:УНФ длина номера документа, как правило, составляет 11 символов (для счетов-фактур – 12). При этом первые 5 символов обычно зарезервированы под системные префиксы, оставляя 6 знаков для порядкового номера. Понимание этой структуры поможет нам при разработке собственного формата нумерации.

Требования к нумерации документа "Заказ покупателя"

Наша цель – настроить нумерацию для документа «Заказ покупателя» таким образом, чтобы она соответствовала следующему формату: ИИ-0310-001, где:

  1. «ИИ» – это уникальный префикс, формируемый для каждого конкретного контрагента (например, инициалы «Иванов Иван»).
  2. «0310» – это день и месяц создания документа (например, 3 октября).
  3. «001» – это порядковый номер, который должен обнуляться каждый месяц.

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

Настройка уникального префикса по контрагентам

Стандартная 1С:УНФ не предоставляет прямой встроенной возможности настроить уникальный префикс для каждого контрагента для всех типов документов, включая «Заказ покупателя», по аналогии с префиксом организации. Обычно префиксы жестко привязаны к организации или информационной базе.

Однако, существуют исключения. Например, для некоторых специфических документов, таких как «Договоры контрагентов» (часто в разделе «CRM»), система может предлагать расширенные настройки нумерации, включающие параметры вида контрагента или дату заключения договора. Но для «Заказа покупателя» такой гибкости по умолчанию нет.

Возможные пути реализации префикса по контрагентам:

  1. Использование расширений (Extension): На рынке 1С существуют готовые расширения, разработанные сторонними компаниями, которые значительно расширяют функционал автоматической нумерации документов. Такие расширения могут позволять настраивать сложные шаблоны номеров, включать в них данные из реквизитов документа (например, данные контрагента), использовать различные параметры даты и префиксы. Преимущество расширений в том, что они подключаются к базе без изменения основной конфигурации, что существенно облегчает процесс ее обновления. Если вы найдете подходящее расширение, это может быть наиболее эффективным и «чистым» способом решения задачи.
  2. Доработка конфигурации через «Конфигуратор» (с использованием подписки на событие): Если готовые расширения не покрывают все ваши специфические требования или если вам нужна очень тонкая и уникальная логика, единственный путь – это программная доработка. Мы можем реализовать это с помощью подписки на событие ПриЗаписи документа «Заказ покупателя». Это позволит программно формировать номер документа согласно любой, даже самой сложной, логике. Данный подход требует высокой квалификации программиста 1С и может усложнить процесс обновления конфигурации.

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

Включение дня и месяца в номер документа (например, «0310» для 3 октября)

Включение элементов даты в формат номера документа – это стандартная возможность систем 1С. В типовых конфигурациях предусмотрены специальные «нумераторы», где мы можем определить шаблон номера. В эти шаблоны можно включать различные элементы даты:

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

Обнуление нумерации каждый месяц

Функциональность периодичности нумерации также является стандартной для 1С и широко применяется. Мы можем настроить, чтобы порядковый номер документа обнулялся по истечении определенного периода. Для нашей задачи нам требуется ежемесячное обнуление.

В настройках нумератора для документа «Заказ покупателя» мы сможем указать требуемую периодичность – «Месяц». Это означает, что с началом каждого нового календарного месяца порядковый номер для документов этого типа будет сбрасываться до 001 (или минимального значения, указанного в настройках). Таким образом, требование -001 с ежемесячным обнулением легко реализуется штатными средствами 1С.

Комплексное решение: как собрать все воедино

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

Вариант 1: Использование Расширений

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

  1. Префикс, выбираемый из свойств контрагента.
  2. Дату (день и месяц) с помощью параметров шаблона.
  3. Порядковый номер с периодичностью «Месяц».

Это сохранит конфигурацию типовой и упростит ее обновление.

Вариант 2: Доработка через Конфигуратор и Подписку на событие

Если расширения не подходят, мы вынуждены будем обратиться к Конфигуратору. Основной механизм будет заключаться в использовании подписки на событие ПриЗаписи документа «Заказ покупателя».

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

Пример концептуального кода для подписки на событие ПриЗаписи:


// Создаем подписку на событие "ПриЗаписи" для документа "ЗаказПокупателя"
// Источник: Документ.ЗаказПокупателя
// Обработчик: ОбщийМодуль.МояНумерацияДокументов.ПриЗаписиЗаказПокупателя

// В ОбщемМодуле "МояНумерацияДокументов" (или любом другом подходящем)

Процедура ПриЗаписиЗаказПокупателя(Источник, Отказ, РежимЗаписи) Экспорт

    Если РежимЗаписи = РежимЗаписиДокумента.Удаление Тогда
        Возврат;
    КонецЕсли;

    Если Источник.ОбменДанными.Загрузка Тогда
        // При загрузке данных нумерацию не трогаем, пусть номер приходит как есть
        Возврат;
    КонецЕсли;

    // Предполагаем, что стандартная автонумерация отключена для документа "ЗаказПокупателя"
    // и мы полностью управляем номером.

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

        Если Не ЗначениеЗаполнено(ПрефиксКонтрагента) Тогда
            // Если префикс не найден, генерируем из имени, например, ИИ для "Иванов Иван"
            Фамилия = ""; Имя = ""; Отчество = "";
            СтрокаФИО = Источник.Контрагент.НаименованиеПолное; // Или другое поле ФИО
            
            МассивСтрок = СтрРазделить(СтрокаФИО, " ", Ложь);
            Если МассивСтрок.Количество() > 0 Тогда Фамилия = МассивСтрок[0]; КонецЕсли;
            Если МассивСтрок.Количество() > 1 Тогда Имя = МассивСтрок[1]; КонецЕсли;
            // Если нужно, можно добавить логику для отчества
            
            Если СтрДлина(Фамилия) > 0 И СтрДлина(Имя) > 0 Тогда
                ПрефиксКонтрагента = Лев(Фамилия, 1) + Лев(Имя, 1);
            ИначеЕсли СтрДлина(Фамилия) > 0 Тогда
                ПрефиксКонтрагента = Лев(Фамилия, 2);
            Иначе
                ПрефиксКонтрагента = "КН"; // Префикс по умолчанию
            КонецЕсли;
        КонецЕсли;

    Иначе
        ПрефиксКонтрагента = "КН"; // Префикс по умолчанию, если контрагент не заполнен
    КонецЕсли;

    // 2. Формируем часть номера с датой (ДДММ)
    ДатаДокумента = Источник.Дата;
    СтрокаДаты = Формат(ДатаДокумента, "ДФ=ддММ");

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

    // Обновляем регистр сведений с новым номером
    Движение = РегистрыСведений.ПоследниеНомераЗаказов.СоздатьМенеджерЗаписи();
    Движение.Контрагент = Источник.Контрагент;
    Движение.МесяцГод = МесяцГод;
    Движение.Номер = ПорядковыйНомер;
    Движение.Записать();

    // Форматируем порядковый номер до 3 знаков с ведущими нулями
    СтрокаПорядковогоНомера = Формат(ПорядковыйНомер, "ЧЦ=3; ЧВН=; ЧНН=0");

    // 4. Собираем итоговый номер
    НовыйНомер = ПрефиксКонтрагента + "-" + СтрокаДаты + "-" + СтрокаПорядковогоНомера;

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

    Если ЗапросУникальность.Выполнить().Выбрать().Следующий() Тогда
        // Если номер уже существует, увеличиваем порядковый номер и пробуем снова
        // Это может произойти, если кто-то вручную изменил номер или при сбое
        ПорядковыйНомер = ПорядковыйНомер + 1;
        СтрокаПорядковогоНомера = Формат(ПорядковыйНомер, "ЧЦ=3; ЧВН=; ЧНН=0");
        НовыйНомер = ПрефиксКонтрагента + "-" + СтрокаДаты + "-" + СтрокаПорядковогоНомера;
        // Обновляем регистр с новым номером
        Движение.Номер = ПорядковыйНомер;
        Движение.Записать();
    КонецЕсли;

    // Устанавливаем сформированный номер документу
    Источник.УстановитьНовыйНомер(НовыйНомер);

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

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

Резюме и рекомендации

Как мы видим, реализация сложной нумерации для документа «Заказ покупателя» в 1С:УНФ, включающей уникальный префикс по контрагенту, дату и ежемесячное обнуление, требует внимательного подхода. Часть задачи (включение даты и периодичность обнуления) может быть решена штатными средствами через настройку нумераторов. Однако, для формирования уникального префикса по каждому контрагенту потребуется либо использование специализированных расширений, либо программная доработка конфигурации через Конфигуратор с использованием подписок на событие ПриЗаписи.

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

← На главную