Многие пользователи и компании сталкиваются с необходимостью настройки автонумерации документов в системе 1С:Документооборот по уникальным, специфическим алгоритмам, которые выходят за рамки стандартных настроек. Рассмотрим ситуацию, когда требуется формировать номер документа в формате, например, "Номер дня в году / Порядковый номер документа за этот день". Допустим, мы хотим получить номера вида: 01.01.22г. № 1/01, № 1/02, № 1/03; 02.01.22г. № 2/01, № 2/02, № 2/03. Попробуем разобраться, как реализовать такую логику, учитывая ограничения типового функционала.
Прежде всего, следует отметить, что стандартные настройки автонумерации документов в 1С:Документооборот, к сожалению, не позволяют реализовать такую сложную логику без доработки. Типовые нумераторы предлагают периодичность по "Году", "Кварталу", "Месяцу" или "Дню", но не предусматривают одновременное использование нескольких счетчиков в одном номере (например, "порядковый номер дня в году" и "порядковый номер за день") или использование сложных выражений для формирования частей номера. Поэтому, если вы планируете использовать подобный алгоритм, будьте готовы к тому, что потребуется вмешательство программиста.
Даже если бы мы могли привязать два нумератора к одному виду документа, это не решило бы проблему автоматически. Стандартный механизм не умеет комбинировать их таким образом, чтобы первый нумератор давал номер дня в году, а второй — порядковый номер внутри этого дня с автоматическим сбросом. В результате, для достижения желаемого формата номера, нам придется обратиться к программной реализации.
В современных версиях 1С:Документооборот, начиная с 2.1 и далее в 3.0, имеется возможность использовать пользовательские выражения на встроенном языке 1С непосредственно в справочнике Нумераторы. Это очень мощный инструмент, который позволяет расширить логику формирования номера, не снимая при этом конфигурацию с поддержки. Это означает, что мы можем добавить необходимый код, не изменяя саму структуру конфигурации, что упрощает обновления системы в будущем.
Разберем по шагам, как это можно реализовать:
ДеньГода() или вычислить разность дат. Например, если у нас есть дата документа ДатаДокумента, то номер дня в году можно получить так:
ДеньГода(ДатаДокумента)
Если нам нужен двузначный формат с лидирующим нулем (например, "01", "02"), нам потребуется дополнительное форматирование:
Формат(ДеньГода(ДатаДокумента), "ЧЦ=2; ЧВН=; ЧС=0")
Примерная логика скрипта внутри нумератора (псевдокод, требующий адаптации под конкретный объект ДокументОбъект и его метаданные):
// Получаем дату документа, для которого формируется номер
ДатаДокумента = Параметры.ДокументОбъект.Дата;
// Формируем порядковый номер дня в году
НомерДняГода = Формат(ДеньГода(ДатаДокумента), "ЧЦ=2; ЧВН=; ЧС=0");
// Определяем начало и конец текущих суток
НачалоДня = НачалоДня(ДатаДокумента);
КонецДня = КонецДня(ДатаДокумента);
// Запрос для поиска последнего номера за текущий день
// Это пример логики, требующий более детальной реализации с учетом специфики запросов и полей номера
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| МАКСИМУМ(Документ.Номер) КАК ПоследнийНомер
|ИЗ
| Документ.НашВидДокумента КАК Документ
|ГДЕ
| Документ.Дата МЕЖДУ &НачалоДня И &КонецДня
| И Документ.ВидДокумента = &ВидДокумента"; // Предполагается поле для вида документа
Запрос.УстановитьПараметр("НачалоДня", НачалоДня);
Запрос.УстановитьПараметр("КонецДня", КонецДня);
Запрос.УстановитьПараметр("ВидДокумента", Параметры.ДокументОбъект.ВидДокумента); // Пример
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
ПорядковыйИндекс = 0;
Если Выборка.Следующий() И Не Пустая(Выборка.ПоследнийНомер) Тогда
// Извлекаем числовую часть после дроби
// Предполагаем, что формат номера уже "X/YY"
ЧастиНомера = СтрРазделить(Выборка.ПоследнийНомер, "/", Ложь);
Если ЧастиНомера.Количество() > 1 Тогда
ПоследнийИндексСтрока = ЧастиНомера[ЧастиНомера.Количество() - 1];
ПорядковыйИндекс = Число(ПоследнийИндексСтрока);
КонецЕсли;
КонецЕсли;
ПорядковыйИндекс = ПорядковыйИндекс + 1;
ИндексСтрока = Формат(ПорядковыйИндекс, "ЧЦ=2; ЧВН=; ЧС=0");
Возврат НомерДняГода + "/" + ИндексСтрока;
Обратите внимание, что этот код — лишь концептуальный пример. Реальная реализация потребует тщательной работы с запросами, учетом возможных ошибок парсинга номеров и оптимизации для производительности, особенно при большом объеме документов.
В 1С:Документооборот 3.0 архитектура нумерации претерпела изменения. Настройки нумерации теперь вынесены в отдельные блоки управления правилами обработки документов, что предоставляет большую гибкость. Появились "Разрезы нумерации", которые позволяют более детально настроить условия для формирования номера. Однако, для настолько специфического алгоритма, как "Номер дня в году / Порядковый номер в сутках", даже в версии 3.0 программное расширение логики все равно потребуется. Разница будет заключаться в том, как именно эта логика будет встраиваться в новые механизмы обработки событий при регистрации документов и работы с разрезами нумерации. Принципы написания скриптов остаются схожими, но точки интеграции могут отличаться.
При использовании нестандартных алгоритмов нумерации, таких как "НомерДня/Индекс", стандартный механизм контроля уникальности номеров в 1С может работать некорректно. Типовой механизм рассчитан на линейное приращение номера и может не распознавать числовую часть номера, разделённую символом дроби или другими нестандартными разделителями. Это создает риск возникновения "дырок" в нумерации или, что хуже, задвоения номеров, особенно при одновременной работе нескольких пользователей.
Для предотвращения таких ситуаций программисту необходимо будет:
ПередЗаписью или ПриЗаписи для объекта документа. В этом обработчике мы будем выполнять запрос к базе данных, чтобы проверить, существует ли уже документ с таким же сформированным номером. Если такой номер найден, необходимо выдать пользователю ошибку и предложить переформировать номер или изменить его вручную.Примерный псевдокод для проверки уникальности:
// В обработчике события ПередЗаписью() документа
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Документ.Ссылка
|ИЗ
| Документ.НашВидДокумента КАК Документ
|ГДЕ
| Документ.Номер = &Номер
| И Документ.Ссылка <> &Ссылка"; // Исключаем сам себя при изменении
Запрос.УстановитьПараметр("Номер", ЭтотОбъект.Номер);
Запрос.УстановитьПараметр("Ссылка", ЭтотОбъект.Ссылка);
Если Не Запрос.Выполнить().Пустой() Тогда
Отказ = Истина;
Сообщить("Документ с таким номером уже существует!", СтатусСообщения.Важное);
КонецЕсли;
В 1С:Документооборот существует штатный функционал "Индексы нумерации". Обычно они используются для добавления префиксов или суффиксов к номеру в зависимости от контрагента, подразделения или вида документа. Теоретически, можно было бы использовать этот механизм, если бы мы могли программно ежедневно обновлять некий служебный индекс, который бы представлял собой номер дня в году. Однако, для связки "Номер дня года + Индекс внутри дня" этого все равно недостаточно без написания дополнительного кода.
То есть, мы могли бы настроить индекс, который ежедневно сбрасывается и содержит номер дня, но тогда все документы за этот день будут иметь один и тот же порядковый номер (например, № 01.01.22г. 1). Для получения инкрементальной части номера (01, 02, 03) внутри одного дня, мы все равно вернемся к необходимости программной доработки.
Критически важно учитывать риски, если ваша организация уже вела учет документов в текущем году и решила перейти на новую схему нумерации. Автоматическое пересчитывание старых номеров под новый формат 1С не умеет выполнять самостоятельно. Это может привести к следующим проблемам:
Для минимизации этих рисков при внедрении новой нумерации в середине периода рекомендуем:
Если мы хотим избежать глубоких изменений в типовом механизме нумерации и минимизировать риски, существует элегантное альтернативное решение. Мы можем сохранить стандартный системный номер документа (который будет просто линейно увеличиваться) и создать дополнительный строковый реквизит для документа.
Этот дополнительный реквизит будет использоваться исключительно для визуального отображения нужного формата номера в печатных формах, реестрах или списках документов. Заполнение этого реквизита будет происходить в момент регистрации документа с помощью простого расширения конфигурации или скрипта, который будет вызываться при записи документа.
Преимущества такого подхода:
Для реализации этого метода:
НомерДополнительный, тип — Строка).НомерДополнительный вместо или в дополнение к стандартному номеру документа.Этот подход позволяет удовлетворить требование к отображению номера в нужном формате, не вмешиваясь в базовые механизмы нумерации 1С:Документооборот, что является наиболее безопасным и рекомендуемым способом для нестандартных задач.
В итоге, для настройки автонумерации документов в 1С:Документооборот по алгоритму "Порядковый номер дня в году / Индекс внутри дня" потребуется программирование. Стандартными средствами реализовать это невозможно. Мы рассмотрели два основных пути: использование скриптов в нумераторах (для чего нужен программист) или создание дополнительного реквизита с программным заполнением. Выбор конкретного метода будет зависеть от сложности требований, версии 1С:Документооборот и готовности к внесению изменений в конфигурацию. В любом случае, при возникновении подобных задач всегда лучше обращаться к опытным специалистам, которые смогут реализовать функционал качественно и с учетом всех нюансов вашей конфигурации и бизнес-процессов.