Как заменить ссылку и GUID на простой числовой номер в 1С?

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

Часто при разработке партионного учета в качестве уникального идентификатора партии разработчики используют связку Ссылка на документ оприходования и GUID строки табличной части этого документа. Для программы и базы данных такая комбинация работает отлично, гарантируя уникальность. Но когда дело доходит до пользователей, возникают проблемы: им сложно визуально воспринимать и, тем более, вводить для поиска длинные строки или уникальные идентификаторы. Пользователи хотят видеть простой, короткий числовой номер (максимум 5-6 знаков). Разберем по шагам, как можно решить эту задачу, избежав лишних блокировок таблиц и сохранив уникальность.

Вариант 1: Разделение хранения и представления

Прежде чем придумывать сложные алгоритмы генерации, давайте проанализируем ситуацию с точки зрения пользовательского интерфейса. Возможно, нам вообще не нужно преобразовывать GUID в число для хранения. Мы можем оставить под капотом надежную связку Ссылка + УникальныйИдентификатор, а пользователю выводить составное, легко читаемое представление.

Рассмотрим подробнее этот подход. Мы можем формировать читаемый код партии "на лету", склеивая номер документа оприходования и код строки. Важно: не используйте для этого стандартный НомерСтроки из табличной части, так как при сортировке строк пользователем номера могут измениться, и привязка сломается. Лучше добавить в табличную часть скрытый реквизит КодСтроки, который будет заполняться программно один раз при добавлении новой строки.

В результате пользователь увидит номер партии в формате, например, 0000015/3 (где 15 — номер документа, а 3 — неизменный код строки). Это легко диктовать по телефону и удобно вводить вручную.

Вариант 2: Использование даты, времени и номера строки

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

Посмотрим на пример формирования такого ключа. Можно взять дату документа, отбросить лишние разряды (например, год или месяц, если партии оборачиваются быстро) и добавить к ним номер строки. Если перевести текущее время в миллисекунды, мы получим первую часть числа, а номер или уникальный ключ строки даст вторую.

Например, дата 10.02.2022 20:05:00 и строка 38 превратятся в число 1002222005038. Оно получается достаточно коротким для того, чтобы зашить его в штрихкод стандарта EAN-13.

Вариант 3: Хеширование данных (Base64 и CRC32)

Рассмотрим программные методы преобразования связки в хеш-значение. В теме на форуме был предложен алгоритм перевода идентификатора в строку формата Base64.

Посмотрим на пример кода генерации идентификатора в Base64:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Объект.Идентификатор = Новый УникальныйИдентификатор;
КонецПроцедуры

Функция УникальныйИдентификаторВBase64(Идентификатор)
    ИдентификаторСтрокой = Строка(Идентификатор);
    ИдентификаторСтрокой = СтрЗаменить(ИдентификаторСтрокой, "-", "");
    ИдентификаторДвоичныеДанные = ПолучитьДвоичныеДанныеИзHexСтроки(ИдентификаторСтрокой);
    ИдентификаторBase64 = Base64Строка(ИдентификаторДвоичныеДанные);
    Возврат ИдентификаторBase64;
КонецФункции

К сожалению, строка Base64 (вида U7yYVX30EeyWhuDVXoOOIQ==) получается визуально перегруженной и не решает главную задачу — сделать код простым для пользователя.

Вместо этого разберем более современный подход. Начиная с платформы 1С версии 8.3.13, можно использовать объект ХешированиеДанных с алгоритмом CRC32. Вы можете передать строковое представление вашей комбинации (Ссылка + GUID) в функцию хеширования. На выходе мы получим обычное 10-значное десятичное число. Хотя вероятность коллизии (совпадения хешей для разных строк) существует, в рамках одной локальной базы партий она минимальна.

Вариант 4: Получение автономера платформы (без записи)

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

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

  1. Создаем пустой элемент служебного справочника партий программно.
  2. Вызываем встроенный метод платформы УстановитьНовыйНомер().
  3. Считываем присвоенный номер и сохраняем его в реквизит нашей партии (или табличной части документа).
  4. Отказываемся от записи созданного элемента справочника.

В этом случае платформа на уровне СУБД безопасно выдает следующий уникальный номер без тяжелых блокировок, и при этом в базе не скапливаются пустые справочные элементы. Единственный побочный эффект — в нумерации справочника будут "дыры", но для идентификации партий это абсолютно не критично.

Вариант 5: Математическая генерация ID без блокировок (Алгоритм Snowflake)

Разберем продвинутый алгоритм генерации короткого числового кода, который часто применяется в высоконагруженных системах. Вы можете сгенерировать 64-битное число (тип Число в 1С прекрасно с ним справляется), используя битовые сдвиги или математическое умножение.

Формула генерации состоит из трех компонентов:

  1. Метка времени: Текущее время в миллисекундах или секундах с фиксированной даты начала отсчета (например, с начала текущего года). Это гарантирует, что номер всегда будет возрастать.
  2. Идентификатор сеанса: Уникальный номер узла или рабочего места (предотвращает дубли при одновременном создании записей разными пользователями).
  3. Счетчик: В нашем случае это может быть код или номер строки документа.

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

Итоги

Подводя черту, выясним причину, почему нет "серебряной пули". Идеально короткий номер в 5 знаков можно получить только с использованием отдельного справочника соответствий и системной нумерации (с решением проблемы "ненужных" партий программно). Если же база работает под высокой нагрузкой и блокировки таблиц недопустимы, лучше всего генерировать составной числовой код на основе миллисекунд и кода строки, либо использовать скрытое хранение связки Ссылка + GUID, отображая пользователю понятную текстовую комбинацию номера оприходования.

← На главную