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

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

При разработке на управляемых формах 1С начинающие программисты часто сталкиваются с проблемой: при попытке программно обработать строки, которые пользователь выделил в табличной части, данные в коде «не совпадают» с тем, что видит пользователь. Возникает ощущение, что индексы строк перепутаны или платформа работает некорректно. Давайте разберемся, почему это происходит и как раз и навсегда решить эту задачу.

Понимаем природу идентификатора строки

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

Почему индексы — плохой помощник? Рассмотрим ситуацию:

  1. Вы добавили пять строк в таблицу. Платформа присвоила им идентификаторы.
  2. Пользователь удалил вторую строку.
  3. Теперь физический индекс (номер строки) изменился, но идентификатор, который остался у объекта, «помнит» именно ту строку, которую выбрал пользователь.
  4. Если вы попытаетесь обращаться к строке по индексу, вы неизбежно получите ошибку либо обработаете не ту строку.

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

Решение через метод НайтиПоИдентификатору

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

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

Разберем пример кода:


// Получаем коллекцию выделенных строк от элемента формы
МассивВыделенныхСтрок = Элементы.Товары.ВыделенныеСтроки;

// Перебираем каждый идентификатор
Для Каждого ИдентификаторСтроки Из МассивВыделенныхСтрок Цикл
    // Находим строку в табличной части объекта по идентификатору
    СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(ИдентификаторСтроки);
    
    // Проверяем, что строка найдена (на всякий случай)
    Если СтрокаТЧ <> Неопределено Тогда
        // Теперь мы работаем с конкретным объектом строки
        СтрокаТЧ.Цена = СтрокаТЧ.Цена * 1.1; // Пример: увеличим цену на 10%
    КонецЕсли;
КонецЦикла;

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

Что делать, если нужно сохранить связь после записи документа?

Иногда задача усложняется: нужно записать документ, а потом выполнить действия с теми же самыми строками. Проблема в том, что после вызова ЭтаФорма.Записать() форма может перечитаться, и старые идентификаторы станут недействительными.

Если вам требуется «длительная» идентификация строк, рекомендуем использовать подход с дополнительной колонкой-ключом:

  1. Добавьте в табличную часть колонку КлючСтроки (тип Строка или UUID).
  2. При добавлении новой строки программно заполняйте этот ключ уникальным значением: СтрокаТЧ.КлючСтроки = Строка(Новый УникальныйИдентификатор);.
  3. Теперь, даже если форма обновится, у вас будет «вечный» ключ, по которому вы сможете найти нужную строку в любой момент через НайтиСтроки() по структуре отбора.

Советы по работе на клиенте и сервере

Помните, что Элементы.ИмяТаблицы.ВыделенныеСтроки доступно только на клиенте. Если обработка данных должна происходить на сервере, передавайте массив идентификаторов в качестве параметра серверной процедуры:


// На клиенте:
МассивВыделенных = Элементы.Товары.ВыделенныеСтроки;
ОбработатьСтрокиНаСервере(МассивВыделенных);

// На сервере:
&НаСервере
Процедура ОбработатьСтрокиНаСервере(МассивИдентификаторов)
    Для Каждого Ид Из МассивИдентификаторов Цикл
        СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Ид);
        // ... ваша логика
    КонецЦикла;
КонецПроцедуры

Использование этого метода позволит вам избавиться от ошибок рассинхронизации и сделает код профессиональным и устойчивым к действиям пользователя. Пробуйте, внедряйте и ваши формы 1С станут работать как часы!

← На главную