При работе в 1С:Управление нашей фирмой (УНФ) часто возникает потребность в нестандартной нумерации документов, особенно для таких важных, как «Заказ покупателя». Типовой функционал 1С предоставляет достаточно гибкие настройки, но в некоторых случаях требуется более сложная логика, например, включение уникального префикса по каждому контрагенту, дня и месяца в номер документа, а также ежемесячное обнуление порядкового номера. Давайте рассмотрим, как мы можем реализовать такую задачу, используя как штатные средства, так и возможности доработки конфигурации.
Прежде чем углубляться в специфические настройки, напомним, как работает стандартная нумерация документов в 1С:УНФ. Обычно номер документа формируется из нескольких компонентов, обеспечивающих его уникальность:
В 1С:УНФ длина номера документа, как правило, составляет 11 символов (для счетов-фактур – 12). При этом первые 5 символов обычно зарезервированы под системные префиксы, оставляя 6 знаков для порядкового номера. Понимание этой структуры поможет нам при разработке собственного формата нумерации.
Наша цель – настроить нумерацию для документа «Заказ покупателя» таким образом, чтобы она соответствовала следующему формату: ИИ-0310-001, где:
Рассмотрим, насколько эти требования выполнимы штатными средствами и что потребуется для их реализации.
Стандартная 1С:УНФ не предоставляет прямой встроенной возможности настроить уникальный префикс для каждого контрагента для всех типов документов, включая «Заказ покупателя», по аналогии с префиксом организации. Обычно префиксы жестко привязаны к организации или информационной базе.
Однако, существуют исключения. Например, для некоторых специфических документов, таких как «Договоры контрагентов» (часто в разделе «CRM»), система может предлагать расширенные настройки нумерации, включающие параметры вида контрагента или дату заключения договора. Но для «Заказа покупателя» такой гибкости по умолчанию нет.
ПриЗаписи документа «Заказ покупателя». Это позволит программно формировать номер документа согласно любой, даже самой сложной, логике. Данный подход требует высокой квалификации программиста 1С и может усложнить процесс обновления конфигурации.При использовании доработки через Конфигуратор, мы должны будем:
Включение элементов даты в формат номера документа – это стандартная возможность систем 1С. В типовых конфигурациях предусмотрены специальные «нумераторы», где мы можем определить шаблон номера. В эти шаблоны можно включать различные элементы даты:
ДД или DD)ММ или MM)КК или QQ)ГГ или YY – двухзначный; ГГГГ или YYYY – четырехзначный).Для нашей задачи нам потребуется включить день и месяц. Например, если мы хотим получить формат ДДММ, мы можем указать это в шаблоне нумератора. Это достаточно просто настраивается через пользовательский интерфейс или в режиме конфигуратора для соответствующего объекта нумерации.
Функциональность периодичности нумерации также является стандартной для 1С и широко применяется. Мы можем настроить, чтобы порядковый номер документа обнулялся по истечении определенного периода. Для нашей задачи нам требуется ежемесячное обнуление.
В настройках нумератора для документа «Заказ покупателя» мы сможем указать требуемую периодичность – «Месяц». Это означает, что с началом каждого нового календарного месяца порядковый номер для документов этого типа будет сбрасываться до 001 (или минимального значения, указанного в настройках). Таким образом, требование -001 с ежемесячным обнулением легко реализуется штатными средствами 1С.
Наибольшую сложность в нашей задаче представляет уникальный префикс по контрагентам. Объединение всех требований потребует комбинированного подхода.
Если вы найдете расширение, которое позволяет настраивать шаблоны нумерации с привязкой к реквизитам документа (например, к контрагенту), то это будет наиболее простой и наименее инвазивный способ. Вы сможете настроить шаблон, который будет включать:
Это сохранит конфигурацию типовой и упростит ее обновление.
Если расширения не подходят, мы вынуждены будем обратиться к Конфигуратору. Основной механизм будет заключаться в использовании подписки на событие ПриЗаписи документа «Заказ покупателя».
Конфигураторе.ПрефиксДляНумерацииДокументов, в справочнике «Контрагенты». Или же мы можем программно формировать префикс на основе имени контрагента (например, две первые буквы фамилии и имени).ПриЗаписи для документа «Заказ покупателя». В модуле подписки напишем код, который будет формировать номер.Номер документа.Пример концептуального кода для подписки на событие ПриЗаписи:
// Создаем подписку на событие "ПриЗаписи" для документа "ЗаказПокупателя"
// Источник: Документ.ЗаказПокупателя
// Обработчик: ОбщийМодуль.МояНумерацияДокументов.ПриЗаписиЗаказПокупателя
// В ОбщемМодуле "МояНумерацияДокументов" (или любом другом подходящем)
Процедура ПриЗаписиЗаказПокупателя(Источник, Отказ, РежимЗаписи) Экспорт
Если РежимЗаписи = РежимЗаписиДокумента.Удаление Тогда
Возврат;
КонецЕсли;
Если Источник.ОбменДанными.Загрузка Тогда
// При загрузке данных нумерацию не трогаем, пусть номер приходит как есть
Возврат;
КонецЕсли;
// Предполагаем, что стандартная автонумерация отключена для документа "ЗаказПокупателя"
// и мы полностью управляем номером.
// 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С:УНФ, включающей уникальный префикс по контрагенту, дату и ежемесячное обнуление, требует внимательного подхода. Часть задачи (включение даты и периодичность обнуления) может быть решена штатными средствами через настройку нумераторов. Однако, для формирования уникального префикса по каждому контрагенту потребуется либо использование специализированных расширений, либо программная доработка конфигурации через Конфигуратор с использованием подписок на событие ПриЗаписи.
Мы рекомендуем начинать поиск с готовых расширений, так как они позволяют достичь требуемого результата без модификации типовой конфигурации, что значительно упрощает дальнейшие обновления. Если подходящих расширений нет, тогда стоит рассмотреть вариант с доработкой, но всегда оценивайте риски и затраты на поддержку такого решения.