При интеграции 1С со сторонними веб-сервисами, интернет-магазинами или мобильными приложениями разработчики часто сталкиваются с требованием передавать постоянный уникальный идентификатор (Id / UUID) каждой строки табличной части документа. Однако в объектной модели платформы 1С у строк табличных частей встроенный неизменяемый идентификатор отсутствует.
Разберем, почему платформа 1С так устроена, и рассмотрим практические способы решения этой задачи.
Проанализируем внутреннее устройство платформы и механизм хранения данных в СУБД:
НомерСтроки). При каждом проведении или записи документа платформа физически удаляет все старые строки из таблицы СУБД операцией DELETE и записывает текущее состояние заново операцией INSERT.НомерСтроки отражает лишь текущую позицию строки в списке. Если пользователь удалит строку, добавит новую в середину или выполнит сортировку, номера строк изменятся, что приведет к рассинхронизации с внешней системой.ПолучитьИдентификатор(): В управляемых формах у элементов коллекции данных формы существует метод ПолучитьИдентификатор(). Однако возвращаемое им числовое значение является временным идентификатором времени выполнения (Runtime ID). Оно существует только в оперативной памяти конкретного сеанса и уничтожается при закрытии формы.Это классический и наиболее надежный способ организации двустороннего обмена. Добавим в табличную часть документа новый реквизит (например, ИдентификаторСтроки с типом Строка(36) или УникальныйИдентификатор).
Посмотрим на алгоритм заполнения в модуле объекта документа. Заполнять идентификатор необходимо на сервере перед записью, чтобы логика работала как при интерактивном вводе через форму, так и при программной загрузке данных:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Для Каждого Стр Из Работы Цикл
Если Не ЗначениеЗаполнено(Стр.ИдентификаторСтроки) Тогда
Стр.ИдентификаторСтроки = Новый УникальныйИдентификатор();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важный нюанс при интерактивном копировании: Если пользователь копирует документ в интерфейсе (по кнопке «Скопировать»), значения реквизитов табличной части переносятся в новый документ. Чтобы избежать дублирования идентификаторов строк в разных документах, обязательно очистим их в событии ПриКопировании модуля объекта:
Процедура ПриКопировании(ОбъектОснование)
Для Каждого Стр Из Работы Цикл
Стр.ИдентификаторСтроки = Неопределено; // Или пустая строка/пустой UUID
КонецЦикла;
КонецПроцедуры
В типовых конфигурациях («1С:ERP Управление предприятием», «1С:Комплексная автоматизация», «1С:Управление торговлей») строки связываются между собой с помощью числовых реквизитов КодСтроки (в табличной части) и МаксимальныйКодСтроки (в шапке документа).
Разберем логику работы этого механизма:
МаксимальныйКодСтроки (тип Число), хранящий последний выданный номер.КодСтроки (тип Число).МаксимальныйКодСтроки + 1, после чего счетчик в шапке увеличивается.КодСтроки в пределах документа гарантированно уникален.Для передачи во внешнюю систему в качестве глобального идентификатора можно сформировать составной ключ, объединив строковый УникальныйИдентификатор ссылки документа и КодСтроки:
ИдентификаторСтрокиДляAPI = Строка(ДокументСсылка.УникальныйИдентификатор()) + "_" + Строка(Стр.КодСтроки);
Если конфигурация находится на поддержке и добавлять новые реквизиты в метаданные запрещено, рассмотрим альтернативные варианты генерации идентификатора в момент выгрузки:
Новый УникальныйИдентификатор() непосредственно в цикле формирования структуры выгрузки (JSON/XML).ХешированиеДанных:
Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
Хеш.Добавить(Строка(ДокументСсылка.УникальныйИдентификатор()));
Хеш.Добавить(Строка(Стр.Номенклатура.УникальныйИдентификатор()));
Хеш.Добавить(Строка(Стр.Количество));
Хеш.Добавить(Строка(Стр.Цена));
ИдентификаторСтроки = Хеш.ХешСумма;
Документ (измерение), НомерСтроки или хеш (измерение), УникальныйИдентификаторСтроки (ресурс). При первой выгрузке записываем сгенерированный UUID в регистр, а при последующих — считываем сохраненное значение.