В процессе разработки в среде 1С:Предприятие часто возникает задача однозначной идентификации конкретной строки в табличной части документа или справочника. Это может потребоваться для связи нескольких таблиц между собой, фиксации порядка строк или реализации сложной логики сравнения данных. В этой статье мы подробно разберем, что такое идентификатор строки, чем он отличается от UUID и какими способами можно запретить пользователю менять порядок строк в документе — решается через настройка проверок ввода данных и контроля перед записью.
Для начала проанализируем важный технический нюанс, который часто путает начинающих разработчиков. В 1С существует два принципиально разных понятия:
ПолучитьИдентификатор(). Оно уникально только в рамках текущего сеанса работы с формой. Как только форма закрывается, этот идентификатор перестает существовать. При следующем открытии той же строки может быть присвоен другой номер.Рассмотрим ситуацию: если нам нужно программно выделить строку на клиенте или найти её в рамках одного серверного вызова, достаточно использовать ПолучитьИдентификатор(). Посмотрим на пример кода:
// Пример поиска строки и позиционирования на ней в управляемой форме
мСтроки = Объект.Товары.НайтиСтроки(Новый Структура("Артикул", ИскомыйАртикул));
Если мСтроки.Количество() > 0 Тогда
// Получаем внутренний идентификатор строки формы
ИдентификаторСтр = мСтроки[0].ПолучитьИдентификатор();
// Устанавливаем текущую строку в табличном поле на форме
Элементы.Товары.ТекущаяСтрока = ИдентификаторСтр;
КонецЕсли;
Если ваша задача требует «отзеркаливания» таблицы или сохранения связи между строками разных табличных частей (например, как это сделано в типовых конфигурациях ЗУП или ERP), стандартного идентификатора формы будет недостаточно. Выясним причину: при записи документа НомерСтроки может измениться из-за сортировки или удаления других строк.
Для решения этой задачи мы рекомендуем добавить в табличную часть собственный реквизит, например, КлючСвязи с типом Число или ИдентификаторСтроки с типом Строка(36). Проанализируем процесс реализации:
КлючСвязи.ПередЗаписью или ПриУстановкеНовогоНомера реализуйте генерацию значения.УникальныйИдентификатор().Пример генерации строкового UUID для строки:
// В модуле объекта или при добавлении строки
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.ИдентификаторСтроки = Строка(Новый УникальныйИдентификатор());
Важный момент: если пользователь скопирует строку, 1С скопирует и ваш «уникальный» идентификатор. Чтобы избежать дублей, обязательно используйте событие таблицы ПриКопировании на форме, где очищайте или обновляйте этот реквизит для новой строки.
Часто программисты пытаются решить проблему через код, когда достаточно настроить свойства формы. Рассмотрим ситуацию, когда нужно запретить пользователю перемещать строки кнопками «Вверх» и «Вниз», но оставить возможность редактирования данных — поможет гибкая настройка прав и запрет редактирования объектов.
Проанализируем шаги по настройке командной панели табличной части:
ИзменятьПорядокСтрок в значение Ложь. Однако, как показывает практика, это не всегда блокирует контекстное меню (поможет блокировка объектов и аудит изменений в 1С).Такой подход гарантирует, что пользователь не сможет случайно или намеренно нарушить последовательность строк, используя стандартные инструменты платформы.
Разберем еще один интересный инструмент, который предоставляет платформа 1С. В табличных частях на форме существует скрытый системный реквизит ИсходныйНомерСтроки. Он хранит индекс строки, который был у неё в момент загрузки данных в форму.
Мы можем использовать его для программной проверки: изменился ли порядок строк перед записью документа. Если последовательность чисел в этом реквизите нарушена (например, после 1 идет 5, а потом 3), значит, пользователь применял сортировку или перемещение.
Пример функции для проверки изменения порядка:
Функция ПорядокСтрокИзменен(КоллекцияТЧ) Экспорт
ПредыдущийНомер = 0;
Для Каждого СтрокаТЧ Из КоллекцияТЧ Цикл
Если СтрокаТЧ.ИсходныйНомерСтроки < ПредыдущийНомер Тогда
Возврат Истина; // Порядок нарушен
КонецЕсли;
ПредыдущийНомер = СтрокаТЧ.ИсходныйНомерСтроки;
КонецЦикла;
Возврат Ложь;
КонецФункции
Если задача стоит максимально жестко — позволить пользователю как угодно крутить таблицу на экране, но в базе данных сохранять её строго в первоначальном виде, — мы можем применить метод «скрытой колонки». Рассмотрим этот алгоритм:
ИндексСортировки (Число).ПередЗаписью выполняем принудительную сортировку коллекции табличной части по этому реквизиту: ЭтотОбъект.Товары.Сортировать("ИндексСортировки Возр");.Это самый надежный способ сохранить структуру документа, даже если в форме включена возможность интерактивной сортировки по любой колонке (например, по цене или наименованию).
Подведем итоги нашего анализа. Для временных манипуляций в рамках одной формы используйте ПолучитьИдентификатор(). Для надежной связи между таблицами и сохранения данных в базе — создавайте свой реквизит КлючСвязи. Чтобы ограничить действия пользователя, используйте ручную настройку командной панели и контекстного меню. Сочетание этих методов позволит вам полностью контролировать жизненный цикл строк в ваших документах — для этого подойдёт модуль управления формами и контроля ввода данных.