Всё, что вы хотели знать о диапазонах номеров, но боялись спросить…

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

Транзакции

Вот для примера возьмём нумерацию бухгалтерских документов.

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

Стандартная транзакция для ведения нумерации бухгалтерских документов: FBN1.

Если мы посмотрим на эту транзакцию в se93, то в нижней части увидим имя объекта SNRO:

Параметры транзакции FBN1

Таблицы

Главная таблица, где хранится сама нумерация – NRIV:

Пример содержимого таблицы NRIV

Структура её проста и понятна.

Объект – это собственно объект SNRO.

Подобъект – это сущность высокого уровня, в рамках которого будет формироваться своя уникальная нумерация . Для бухгалтерских документов – это всегда БЕ (в разных БЕ могут быть документы с одинаковыми номерами), для дебиторов/кредиторов такого подобъекта нет – значит номера уникальны для всего манданта. В SNRO можно посмотреть, что именно является подобъектом:

Объект диапазона номеров RF_BELEG

Описательная часть диапазонов номеров находится в таблице TNRO:

Пример содержимого таблицы TNRO

Тоже ничего особо страшного, просто и понятно.

Основная разница между нумерацией контрагентов и нумерацией бухгалтерских документов – это зависимость от времени. Нумерация бухгалтерских документов начинается с начала каждый год.

Собственные объекты нумерации

В транзакции SNRO можно создавать собственные объекты нумерации для использования в собственных разработках. Если вам нужна нумерация – то следует использовать именно SNRO, в SAP ERP нет никаких триггеров и автоинкрементных полей.

Создать объект нумерации – просто. Использовать также легко – для этого есть функциональный модуль ‘NUMBER_GET_NEXT’. Параметры бесхитростны и не должны вызывать трепета у бывалых программистов.

Развитой логикой этот механизм не обладает, поэтому никогда не ждите, что он будет откручивать номер назад. Каждый вызов этой функции будет накручивать счётчик – и тут не важно, сохранили ли вы документ в базу или нет. Поэтому просто старайтесь получать этот номер уже после всех логических проверок прямо перед записью документа в таблицу.

С точки зрения такой простой логики – эти бухгалтерские хотелки “без пропусков” очень вредны с точки зрения системы.

Изредка в реальной жизни можно встретить решения по схеме «MAX+1». Одна из неприятностей, которая в таком случае может произойти – это дублирование номеров при  параллельном использовании. Не берите такой грех на душу.

Копирование

Общего подхода к копированию нет. Есть специализированные транзакции для особо сложных случаев, например: https://entropii.net/?p=956.

Перенос

Диапазоны номеров переносятся только один раз – в самом начале, вручную – они автоматически не включаются в запрос на перенос.

Если перенести диапазоны номеров снова, то вместе с ними перенесутся и значения текущих номеров. А эти номера будут нулевыми, так как в манданте настройки мы не проводим документы. И вот что будет дальше: система выдаёт номер 1 для нового документа, документ пытается сохраниться в базу данных, а там такой номер уже есть. Система валится без сохранения документа.

В таком случае остаётся только выбирать максимальный номер по каждому диапазону из существующих в манданте и вручную обновлять статус каждого.  Предполагаю также, что текущий номер можно напрямую обновить в таблице NRIV – это уже относится к методологии “кувалды и чьей-то матери”.

Предел нумерации

Теоретический предел самого SNRO – двадцать знаков (в общем случае). Однако, обычные номера используют десятизначный тип данных. Это значит что сюда умещается максимум десять миллиардов значений. Если вы используете схему AABBBBBBBB, то значит каждый диапазон может вместить сто миллионов значений. Для обычной организации это вполне разумные и заоблачные цифры.

Если вы, например, для нумерации группы кредиторов используете диапазон 0000400000-0000409999 (пусть это будут юрлица-резиденты), то вы должны отдавать себе отчёт, что у вас будет всего лишь 10000 (десять тысяч) юридических лиц на всю жизнь. Ну для небольшой организации это может и не проблема, однако если у вас в системе используется много БЕ и бухгалтера каждой БЕ создают себе отдельных кредиторов только в своей БЕ, то паралич может наступить довольно скоро. Чуть более длинный номер – небольшая плата за гарантии.

Конечно, диапазон можно расширить вручную потом, но это будет не так красиво. Надеюсь, что никто никогда не делает конкатенацию с лидирующими нулями (‘0000’), иначе проблемы могут ещё быть и неожиданными.

Общие замечания

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

То есть: номер 01 соответствует диапазону 0100000000-0199999999, а для 10 должен быть указан диапазон 1000000000-1099999999.

В общем случае SNRO не умеет делать смешанную нумерацию с буквами и цифрами вида A000000001 – это считается уже внешней нумерацией.

В каких случаях можно использовать внешнюю нумерацию:

  • Если у вас ничтожно малое число объектов, и специально обученного пользователя не затруднит ввести такой номер вручную по заранее обговорённой схеме
  • Список объектов заводится консультантами в качестве настройки, и в обозримом времени не будет дополняться (например: технические контрагенты)
  • Если у вас записи приходят из системы с гарантированной уникальностью записей (например: бизнес-партнёры)
  • Если вы можете предоставить надёжный алгоритм, который будет справляться с генерацией уникального хитрого номера (пример: нумерация партий или договоров).

А как же GUID?

Некоторые модули используют GUID в качестве уникальных ключей (например RCM, TR), поэтому его объекты не имеют видимого номера. Да, они обходятся без счётчиков, диапазонов номеров и прочей засоряющей систему трескотни.

Не буду категорически утверждать, хорошо это или плохо, но так тоже можно, и это не грех.

PS.

Всегда ли нумерация идёт подряд?

Как может случиться так, что порядок номеров в документах не соответствует порядку их создания?

В реальной жизни действительно может сложиться такая ситуация, что документ с номером 155 создан два часа назад, а документ 145 создан один час назад.

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

Это не глюк и не махинации.

Это связано с тем, что у вас (а) рабочая система может быть представлена несколькими инстансами, и (б) используется буферизация номеров. Основная проблема в том, что буфер находится в конкретном инстансе. При этом буферизация и балансировка (то есть горизонтальное масштабирование) — это инструменты улучшения производительности.

Если эти звёзды сходятся, то сценарий примерно такой:

  • пользователь заходит
  • балансировщик нагрузки закидывает его в инстанс 1
  • он создает документ с номером 155 из того буфера, который сейчас держит инстанс
  • пользователь выходит
  • пользователь снова заходит
  • в инстанс уже набежали другие пользователи, и балансировщик закидывает его в инстанс 2
  • он сторнирует документ 155, а инстанс 2 более редкий, поэтому буфер там старый и используется реже, поэтому буфер который взяли позавчера (140-149) ещё не весь потрачен и новый номер получился 145.

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

Добавить комментарий

Ваш адрес email не будет опубликован.