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

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

При разработке систем обмена данными между 1С и внешними приложениями (сайтами, мобильными устройствами, сторонними учётными системами) часто возникает задача: как «зацепиться» за конкретную строку в табличной части документа? Если документ будет изменен, строки переставлены местами или часть из них удалена, стандартный НомерСтроки перестает быть надежным идентификатором. Разберем по шагам, почему штатные механизмы платформы не всегда подходят для этой задачи и какие архитектурные решения считаются наиболее правильными.

Проблема стандартного номера строки и временных идентификаторов

Первое, что приходит на ум начинающему разработчику — использовать свойство НомерСтроки. Однако, проанализируем ситуацию: пользователь может зайти в документ, удалить вторую строку, и бывшая третья строка автоматически станет второй. Если внешняя система уже получила данные о «строке №3», при попытке синхронизации она обратится не к тому товару. Хуже того, строки можно менять местами (перетаскивать мышкой), что полностью ломает логику связки по номеру.

Также в платформе существует метод ПолучитьИдентификатор() для строк табличной части. Выясним причину, по которой он не подходит для обмена: этот идентификатор является динамическим. Он гарантирует уникальность строки только в рамках текущего сеанса работы с объектом в памяти. После закрытия и повторного открытия документа эти идентификаторы будут сгенерированы заново и не совпадут с предыдущими. Для постоянного хранения и передачи «наружу» они категорически непригодны.

Решение №1: Добавление собственного реквизита типа УникальныйИдентификатор

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

Важные настройки реквизита:

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

Чтобы этот идентификатор всегда был заполнен, нам необходимо программно генерировать его при создании строки. Разберем пример кода, который можно разместить в модуле объекта документа:


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

Однако, посмотрим на важный нюанс: копирование строк. Если пользователь нажмет F9 (скопирует строку), новый реквизит скопируется вместе со старым значением, и у нас появятся две строки с одинаковым GUID. Чтобы этого избежать, в модуле формы документа следует обработать событие ПриКопировании для табличной части:


&НаКлиенте
Процедура ТоварыПриКопировании(Элемент, ОбъектКопирования)
    // Очищаем или генерируем новый ID для новой строки
    Элементы.Товары.ТекущиеДанные.ИдентификаторСтроки = Новый УникальныйИдентификатор();
КонецПроцедуры

Решение №2: Использование механизмов БСП (КлючСвязи)

В современных типовых конфигурациях, построенных на базе Библиотеки Стандартных Подсистем (БСП), таких как ERP, УТ 11 или КА, уже заложены механизмы связки строк. Рассмотрим их подробнее. Часто в документах можно встретить реквизит КлючСвязи (обычно числовой).

Этот ключ предназначен для связи основной табличной части (например, «Товары») с подчиненными (например, «СерийныеНомера» или «СкидкиНаценки»). Если вам нужно просто идентифицировать строку внутри документа для внутренних нужд системы, этот ключ может подойти. Однако для внешнего обмена GUID предпочтительнее, так как он обладает глобальной уникальностью. В последних версиях БСП для некоторых документов уже внедрены скрытые реквизиты с типом УникальныйИдентификатор именно для целей синхронизации данных.

Решение №3: Использование расширений конфигурации

Если ваша база находится на поддержке и вы не хотите снимать её с поддержки для добавления реквизитов, проанализируем возможность использования расширений. Это современный и безопасный способ. Вы создаете расширение, добавляете в него нужный документ и расширяете его табличную часть своим реквизитом. Платформа позволяет добавлять реквизиты в ТЧ через расширения, и они будут вести себя так же, как «родные» поля, сохраняясь в базе данных.

Решение №4: Хеширование состава строки (как альтернативный вариант)

Иногда возникают ситуации, когда менять структуру данных нельзя совсем (даже через расширения). В таких случаях можно использовать метод хеширования. Рассмотрим этот подход: мы берем все значимые поля строки (номенклатура, количество, цена, характеристика) и формируем из них строку, от которой вычисляем хеш-функцию (например, MD5). Эту строку-хеш мы и передаем во внешнюю систему.

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

Решение №5: Внешний регистр сведений

Если нельзя менять документ, можно создать независимый регистр сведений, где в качестве измерений будет ссылка на Документ и некий квази-идентификатор, а в ресурсах — GUID. Но выясним причину, по которой это решение считается «хрупким»: при удалении строк в документе или их перенумерации крайне сложно поддерживать актуальность записей в регистре без жесткой привязки к событиям объекта. Это создает лишнюю нагрузку на базу и усложняет код.

Подведем итоги

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

  1. Добавить реквизит ИдентификаторСтроки с типом УникальныйИдентификатор непосредственно в ТЧ документа (через расширение или основную конфигурацию).
  2. Обеспечить заполнение этого реквизита при создании и копировании строки.
  3. Использовать этот идентификатор во всех API и протоколах обмена как единственный ключ для поиска строки.
  4. Передавать во внешние системы не индекс массива, а именно этот GUID.

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

← На главную