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

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

При интеграции 1С со сторонними веб-сервисами, интернет-магазинами или мобильными приложениями разработчики часто сталкиваются с требованием передавать постоянный уникальный идентификатор (Id / UUID) каждой строки табличной части документа. Однако в объектной модели платформы 1С у строк табличных частей встроенный неизменяемый идентификатор отсутствует.

Разберем, почему платформа 1С так устроена, и рассмотрим практические способы решения этой задачи.

Почему в 1С у строки табличной части нет постоянного идентификатора?

Проанализируем внутреннее устройство платформы и механизм хранения данных в СУБД:

  1. Перезапись табличной части при сохранении: В базе данных строки табличной части хранятся в отдельной таблице, где первичным ключом выступает пара полей: ссылка на документ-владелец и номер строки (НомерСтроки). При каждом проведении или записи документа платформа физически удаляет все старые строки из таблицы СУБД операцией DELETE и записывает текущее состояние заново операцией INSERT.
  2. Нестабильность номера строки: Поле НомерСтроки отражает лишь текущую позицию строки в списке. Если пользователь удалит строку, добавит новую в середину или выполнит сортировку, номера строк изменятся, что приведет к рассинхронизации с внешней системой.
  3. Ограничение метода формы ПолучитьИдентификатор(): В управляемых формах у элементов коллекции данных формы существует метод ПолучитьИдентификатор(). Однако возвращаемое им числовое значение является временным идентификатором времени выполнения (Runtime ID). Оно существует только в оперативной памяти конкретного сеанса и уничтожается при закрытии формы.

Способ 1. Добавление реквизита типа «УникальныйИдентификатор» или «Строка» в табличную часть

Это классический и наиболее надежный способ организации двустороннего обмена. Добавим в табличную часть документа новый реквизит (например, ИдентификаторСтроки с типом Строка(36) или УникальныйИдентификатор).

Посмотрим на алгоритм заполнения в модуле объекта документа. Заполнять идентификатор необходимо на сервере перед записью, чтобы логика работала как при интерактивном вводе через форму, так и при программной загрузке данных:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Для Каждого Стр Из Работы Цикл
        Если Не ЗначениеЗаполнено(Стр.ИдентификаторСтроки) Тогда
            Стр.ИдентификаторСтроки = Новый УникальныйИдентификатор();
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Важный нюанс при интерактивном копировании: Если пользователь копирует документ в интерфейсе (по кнопке «Скопировать»), значения реквизитов табличной части переносятся в новый документ. Чтобы избежать дублирования идентификаторов строк в разных документах, обязательно очистим их в событии ПриКопировании модуля объекта:


Процедура ПриКопировании(ОбъектОснование)
    
    Для Каждого Стр Из Работы Цикл
        Стр.ИдентификаторСтроки = Неопределено; // Или пустая строка/пустой UUID
    КонецЦикла;
    
КонецПроцедуры

Способ 2. Использование механизма кодов строк (как в типовых конфигурациях 1С)

В типовых конфигурациях («1С:ERP Управление предприятием», «1С:Комплексная автоматизация», «1С:Управление торговлей») строки связываются между собой с помощью числовых реквизитов КодСтроки (в табличной части) и МаксимальныйКодСтроки (в шапке документа).

Разберем логику работы этого механизма:

  1. В шапке документа создается реквизит МаксимальныйКодСтроки (тип Число), хранящий последний выданный номер.
  2. В табличной части создается реквизит КодСтроки (тип Число).
  3. При добавлении строки ей присваивается инкрементное значение: МаксимальныйКодСтроки + 1, после чего счетчик в шапке увеличивается.
  4. Даже если строка с максимальным номером будет удалена пользователем, счетчик не уменьшается, благодаря чему каждый новый КодСтроки в пределах документа гарантированно уникален.

Для передачи во внешнюю систему в качестве глобального идентификатора можно сформировать составной ключ, объединив строковый УникальныйИдентификатор ссылки документа и КодСтроки:


ИдентификаторСтрокиДляAPI = Строка(ДокументСсылка.УникальныйИдентификатор()) + "_" + Строка(Стр.КодСтроки);

Способ 3. Динамическая генерация без изменения структуры метаданных

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

  1. Одноразовая выгрузка (без обратной синхронизации): Если документ выгружается во внешнюю систему один раз без необходимости последующего обновления конкретных строк, достаточно генерировать временный Новый УникальныйИдентификатор() непосредственно в цикле формирования структуры выгрузки (JSON/XML).
  2. Детерминированное хеширование полей строки: Если состав строки уникален (комбинация номенклатуры, количества и цены), сформируем постоянный неизменяемый хеш с помощью объекта платформы ХешированиеДанных:
    
    Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
    Хеш.Добавить(Строка(ДокументСсылка.УникальныйИдентификатор()));
    Хеш.Добавить(Строка(Стр.Номенклатура.УникальныйИдентификатор()));
    Хеш.Добавить(Строка(Стр.Количество));
    Хеш.Добавить(Строка(Стр.Цена));
    
    ИдентификаторСтроки = Хеш.ХешСумма;
    
    При повторной выгрузке документа с тем же составом строки вычисленный хеш полностью совпадет.
  3. Использование отдельного регистра сведений: Создадим независимый нетиповой регистр сведений со структурой: Документ (измерение), НомерСтроки или хеш (измерение), УникальныйИдентификаторСтроки (ресурс). При первой выгрузке записываем сгенерированный UUID в регистр, а при последующих — считываем сохраненное значение.
← На главную