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

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

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

Причины сбоя сортировки и ошибок уникальности

Проанализируем технические особенности платформы 1С, из-за которых возникают сложности:

  1. Отсутствие периодичности у справочников: В метаданных справочника свойство нумератора «Периодичность» (например, «В пределах года») не предусмотрено. Контроль уникальности кода работает в рамках всего справочника, либо в пределах подчинения родителю или владельцу. При попытке повторно записать код Э0000001 в новом году платформа выдает ошибку нарушения уникальности.
  2. Особенности лексикографической сортировки строк: Код справочника имеет строковый тип данных. Платформа сортирует строки посимвольно слева направо. Если длина кода была увеличена (например, с 9 до 15 символов) без выравнивания старых записей, новый номер с большим числом лидирующих нулей (Э00000001) в лексикографическом порядке встает между старыми номерами с меньшим числом нулей.
  3. Ограничения интерактивной сортировки в обычных формах: В обычном интерфейсе список СправочникСписок позволяет упорядочивать данные только по стандартным полям (Код, Наименование) либо по дополнительным реквизитам, у которых в конфигураторе явно включено индексирование.

Способ 1. Использование префикса года в событии ПриУстановкеНовогоКода

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

Рассмотрим по шагам реализацию этого механизма:

  1. В конфигураторе убедимся, что длина кода справочника достаточна для размещения префикса с годом и порядкового номера (например, 11 или 15 символов).
  2. Откроем модуль объекта нужного справочника.
  3. Добавим обработчик предопределенного события ПриУстановкеНовогоКода:

Процедура ПриУстановкеНовогоКода(СтандартнаяОбработка, Префикс)
    // Формируем префикс вида "Э24-" или "Э2024/"
    Префикс = "Э" + Формат(ТекущаяДата(), "ДФ=yy") + "-";
КонецПроцедуры

Разберем логику работы: при наступлении нового календарного года значение ТекущаяДата() изменит год, соответственно изменится префикс (например, с Э23- на Э24-). Платформа найдет максимальный существующий номер именно с префиксом Э24-, не обнаружит его и автоматически начнет отсчет с Э24-000001. Контроль уникальности платформы при этом остается полностью работоспособным.

Способ 2. Индексирование реквизита даты и настройка сортировки в форме списка

Если в нетиповом справочнике уже создан отдельный реквизит Дата (или ДатаКП), исправим проблему упорядочивания элементов в форме списка:

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

Процедура ПриОткрытии()
    // Устанавливаем порядок отображения списка по дате по возрастанию или убыванию
    СправочникСписок.Порядок.Установить("Дата Возр");
КонецПроцедуры

Способ 3. Нормализация длины кодов существующих элементов

Если длина кода уже была увеличена, и порядок строк нарушился из-за разного количества лидирующих нулей, выполним нормализацию номеров. Для этого воспользуемся внешней обработкой или типовой обработкой «Групповая обработка справочников и документов» / «Универсальные подбор и обработка объектов».

Посмотрим на пример программного выравнивания строкового кода к единому формату:


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

Способ 4. Архитектурная оптимизация структуры данных

Проанализируем архитектурную составляющую. Если сущность в системе (в данном случае коммерческие предложения или реестр КП) имеет четкую привязку к дате, автору и периодической нумерации, правильнее рассмотреть следующие варианты:

  1. Перенос логики в объект метаданных «Документ»: Документы в 1С изначально поддерживают стандартный реквизит Дата, сквозную или периодическую нумерацию («В пределах года», «В пределах месяца») и хронологический порядок отображения.
  2. Подчинение справочнику «Годы»: Создается вспомогательный справочник Годы. Для целевого справочника настраивается подчинение владельцу, а в свойстве «Серии кодов» устанавливается значение В пределах подчинения владельцу. В этом случае для каждого года элементы создаются внутри своей папки/владельца, а платформа штатно начинает нумерацию с единицы в рамках выбранного года.
← На главную