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

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

Разработчики, занимающиеся интеграцией 1С с интернет-магазинами и внешними CRM-системами, часто сталкиваются со следующей проблемой. При выгрузке контрагентов на сайт необходимо передавать уникальные идентификаторы (GUID) их контактной информации (адресов доставки, телефонов и т.д.). Однако стандартные механизмы Библиотеки стандартных подсистем (БСП) в 1С при записи объекта полностью очищают табличную часть КонтактнаяИнформация и перезаписывают её заново на основе данных формы.

Это приводит к тому, что любые добавленные вручную реквизиты строк (например, строковые уникальные идентификаторы) очищаются при каждом сохранении элемента справочника. В этой статье мы подробно разберем, почему это происходит, и рассмотрим два эффективных способа решения данной проблемы: штатный механизм БСП и альтернативный вариант с минимальной доработкой системы.

Выясняем причину: почему БСП перезаписывает контактную информацию?

Для начала проанализируем, как работает подсистема управления контактной информацией в БСП. На управляемой форме элемента (например, контрагента) физически нет привычной таблицы контактной информации. Вместо этого механизмы БСП динамически создают реквизиты на форме и выводят их в удобном для пользователя виде. При этом один вид контактной информации (например, «Адрес доставки») может быть множественным — пользователь может добавлять неограниченное количество адресов.

Перед записью объекта на сервере срабатывает процедура общего модуля:


УправлениеКонтактнойИнформацией.ПередЗаписьюНаСервере(Форма, Объект, Отказ = Ложь)

Этот обработчик собирает измененные данные с формы, полностью очищает табличную часть КонтактнаяИнформация у записываемого объекта и заполняет её заново. Из-за этого дефолтного поведения любые попытки просто «добавить колонку ГУИД в ТЧ» и записывать её стандартными методами обречены на неудачу — при первой же интерактивной перезаписи объекта данные в этой колонке будут потеряны.

---

Способ 1. Использование штатного механизма БСП (Рекомендуемый)

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

Для реализации этого механизма выполним следующие шаги:

  1. Добавление реквизита в табличную часть: Перейдем в конфигуратор и откроем справочник-владелец контактной информации (например, Контрагенты). В его табличную часть КонтактнаяИнформация добавим новый реквизит ИдентификаторСтрокиТабличнойЧасти с типом данных Число (7, 0).
  2. Поддержка со стороны БСП: Программные механизмы общего модуля УправлениеКонтактнойИнформацией автоматически распознают этот реквизит. При записи объекта БСП больше не будет хаотично перетирать строки. Она сопоставит строки формы и строки табличной части по этому идентификатору.

Как получить стабильный GUID для сайта на основе этого механизма?

Поскольку сайту обычно требуется именно UUID в формате строки, мы можем генерировать так называемый детерминированный GUID «на лету» прямо в процессе выгрузки данных. В качестве основы мы возьмем уникальный идентификатор самого контрагента и числовой идентификатор строки.

Рассмотрим пример функции, которая генерирует стабильный уникальный идентификатор для сайта:


Функция ПолучитьДетерминированныйГУИД(СсылкаВладельца, ИдентификаторСтроки) Экспорт
    
    // Получаем строковое представление ГУИДа контрагента
    ГУИДВладельца = Строка(СсылкаВладельца.УникальныйИдентификатор());
    
    // Преобразуем числовой идентификатор строки в строку фиксированной длины (с ведущими нулями)
    Суффикс = Формат(ИдентификаторСтроки, "ЧГ=0");
    Суффикс = Прав("000000000000" + Суффикс, 12);
    
    // Заменяем последние 12 символов исходного ГУИДа на наш уникальный суффикс строки КИ
    НовыйГУИДСтрока = Лев(ГУИДВладельца, 24) + Суффикс;
    
    Возврат Новый УникальныйИдентификатор(НовыйГУИДСтрока);
    
КонецФункции

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

---

Способ 2. Доработка модуля УправлениеКонтактнойИнформацией (Альтернативный)

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

Разберем по шагам, как реализовать этот подход:

  1. Добавим в табличную часть КонтактнаяИнформация справочника Контрагенты реквизит ИдентификаторСтроки с типом Строка (36) или УникальныйИдентификатор.
  2. Если на форме контрагента используется отдельная вспомогательная таблица для КИ (например, список адресов доставки), добавим аналогичную колонку и туда.
  3. В общем модуле УправлениеКонтактнойИнформацией найдем процедуры, отвечающие за перенос данных из формы в объект (например, ЗаписатьКонтактнуюИнформациюОбъекта). Нам необходимо дописать сопоставление и заполнение нашего реквизита.

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


// В цикле обхода данных контактной информации перед записью объекта:
Если НЕ ЗначениеЗаполнено(СтрокаТаблицыОбъекта.ИдентификаторСтроки) Тогда
    СтрокаТаблицыОбъекта.ИдентификаторСтроки = Новый УникальныйИдентификатор();
КонецЕсли;

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

---

Пример выгрузки контактной информации с уникальными идентификаторами

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


Процедура ВыгрузитьКонтактнуюИнформацию(СсылкаКонтрагента)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	КонтрагентыКонтактнаяИнформация.Ссылка КАК Контрагент,
        |	КонтрагентыКонтактнаяИнформация.Вид КАК ВидКИ,
        |	КонтрагентыКонтактнаяИнформация.Представление КАК Представление,
        |	КонтрагентыКонтактнаяИнформация.ИдентификаторСтрокиТабличнойЧасти КАК ИдентификаторСтроки
        |ИЗ
        |	Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
        |ГДЕ
        |	КонтрагентыКонтактнаяИнформация.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаКонтрагента);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        
        // Получаем детерминированный стабильный ГУИД для интеграции
        ГУИДСтрокиКИ = ПолучитьДетерминированныйГУИД(Выборка.Контрагент, Выборка.ИдентификаторСтроки);
        
        // Формируем структуру для отправки на сайт
        ДанныеАдреса = Новый Структура;
        ДанныеАдреса.Вставить("ID", Строка(ГУИДСтрокиКИ));
        ДанныеАдреса.Вставить("Type", Строка(Выборка.ВидКИ));
        ДанныеАдреса.Вставить("Value", Выборка.Представление);
        
        // Отправка данных на сайт (внешний HTTP-запрос)...
        
    КонецЦикла;
    
КонецПроцедуры

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

← На главную