В типовых конфигурациях 1С, таких как «Управление нашей фирмой» (УНФ), механизмы нумерации обычно работают линейно или в разрезе префиксов организаций. Однако в управленческом учете часто возникает потребность в «умной» нумерации, когда номер документа должен содержать идентификатор (ID) контрагента и порядковый номер документа именно для этого клиента. Рассмотрим, как реализовать такую задачу, проанализируем возможные подходы и разберем программные примеры.
Представим ситуацию: бизнес требует, чтобы у каждого контрагента был свой уникальный трехзначный код (например, 001, 002 и т.д.). Все документы этого контрагента должны иметь номер, состоящий из его ID и порядкового номера документа. Например, для контрагента с кодом 123 заказ покупателя должен иметь номер 123-001, счет — 123-001-001 и так далее.
Основные сложности:
Номер в 1С является строковым и имеет свои механизмы автогенерации, которые не учитывают связи с другими справочниками «из коробки».Рассмотрим вариант, предложенный в обсуждении, который подходит для быстрого внедрения через расширение конфигурации. Суть метода заключается в создании дополнительных реквизитов для хранения кастомного ID и их заполнении сразу после сохранения объекта.
Для начала создадим в справочнике Контрагенты реквизит ИДКонтрагента. Чтобы автоматизировать его заполнение на основе последних трех цифр стандартного кода справочника, можно использовать следующий код в расширении формы:
&НаКлиенте
Процедура Расш1_ПослеЗаписиПосле(ПараметрыЗаписи)
// Если ИД еще не заполнен, берем последние 3 цифры стандартного кода
Если НЕ ЗначениеЗаполнено(Объект.ИДКонтрагента) Тогда
Объект.ИДКонтрагента = Прав(Объект.Код, 3);
КонецЕсли;
КонецПроцедуры
Далее переходим к документам, например, к «Заказу покупателя». Проанализируем, как сформировать его внутренний идентификатор ИДЗаказПокупателя на стороне сервера, чтобы избежать лишних вызовов с клиента:
&НаСервере
Процедура Расш1_ПослеЗаписиНаСервереПосле(ТекущийОбъект, ПараметрыЗаписи)
КонтрагентЗак = Объект.Контрагент;
// Получаем объект контрагента для чтения его ИД
ОбъектКА = КонтрагентЗак.ПолучитьОбъект();
Если НЕ ЗначениеЗаполнено(Объект.ИДЗаказПокупателя) Тогда
// Формируем новый номер: ИД Контрагента + последние 3 цифры номера заказа
Объект.ИДЗаказПокупателя = ОбъектКА.ИДКонтрагента + Прав(Объект.Номер, 3);
// Здесь важно понимать, что повторная запись объекта в ПослеЗаписи может привести к рекурсии
// В реальном проекте лучше использовать ПередЗаписью или обертку ОбменДанными.Загрузка = Истина
КонецЕсли;
КонецПроцедуры
Более правильный с точки зрения архитектуры 1С подход — вмешаться в сам процесс генерации номера. Это позволяет избежать двойной записи объекта и гарантирует, что номер будет корректным еще до того, как пользователь увидит документ в списке.
Разберем, как это реализовать через Подписку на событие или в модуле объекта через расширение. Основная логика будет заключаться в изменении префикса номера в зависимости от выбранного контрагента.
Процедура Расш1_ПриУстановкеНовогоНомера(Источник, СтандартнаяОбработка, Префикс)
// Источник — это наш документ (например, ЗаказПокупателя)
// Проверяем наличие заполненного контрагента
Если ЗначениеЗаполнено(Источник.Контрагент) Тогда
ИД_Клиента = Источник.Контрагент.ИДКонтрагента;
Если ЗначениеЗаполнено(ИД_Клиента) Тогда
// Устанавливаем префикс, равный ID контрагента
// Это заставит 1С искать следующий номер внутри этого префикса
Префикс = ИД_Клиента + "-";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Преимущества этого метода:
В ходе обсуждения возник резонный вопрос: что делать, если трех цифр перестанет хватать? Проанализируем ситуацию. Если использовать только цифры, мы ограничены 1000 комбинаций. Однако 1С позволяет использовать в номерах и кодах буквы.
Рассмотрим вариант использования буквенно-цифрового кодирования (Base36). Если мы разрешим использовать цифры 0-9 и латинские буквы A-Z, то в те же 3 символа мы сможем уместить более 46 000 уникальных комбинаций. Это полностью решит проблему нехватки номеров для среднего и даже крупного бизнеса.
Будьте осторожны при изменении нумерации фискальных документов. Согласно законодательству РФ, счета-фактуры должны иметь сквозную порядковую нумерацию в хронологическом порядке. Если вы сделаете нумерацию счетов-фактур «по контрагентам» (например, 001-01, 002-01), это может вызвать претензии со стороны налоговой службы. Для таких документов лучше оставлять стандартный номер 1С, а кастомный ID выводить только в печатную форму как дополнительную информацию.
ПрефиксацияОбъектовПереопределяемый. Часто добавление логики там позволяет решить задачу наиболее «чистым» способом.ПослеЗаписи: Как мы выяснили, это приводит к двойному срабатыванию триггеров базы данных и замедляет работу. Всегда старайтесь рассчитать номер в событии ПередЗаписью.Номер (например, 11 символов минус 3 на ID и 1 на дефис) достаточно для вашей интенсивности документооборота.Таким образом, задача решается комбинированием расширения метаданных (добавление реквизита в справочник) и программной обработки событий записи или установки нового номера. Выбор метода зависит от того, насколько глубоко вы готовы менять стандартную логику нумерации конфигурации.