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

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

При разработке обработок и форм в управляемом приложении 1С часто возникает задача обработать только те строки табличной части, которые пользователь выделил мышью. Однако разработчики нередко сталкиваются со странным мнением платформы о нумерации: после очистки и повторного заполнения таблицы индексы выделенных строк неожиданно начинаются не с нуля, а продолжают сквозной отсчет, например, с 10, 15 или 100.

Разберем подробнее причины такого поведения платформы 1С, выясним разницу между порядковыми индексами и идентификаторами строк, а также рассмотрим правильные способы получения данных из выделенных строк.

Выясним причину: идентификаторы строк вместо порядковых индексов

Главная ошибка заключается в путанице между **индексом строки** и ее **внутренним идентификатором** в контексте управляемой формы.

Свойство элемента формы ВыделенныеСтроки возвращает не массив порядковых номеров строк (0, 1, 2...), а массив числовых **идентификаторов** элементов коллекции ДанныеФормыКоллекция. Когда мы добавляем строку в коллекцию данных формы, платформа присваивает ей уникальное число в рамках текущего сеанса работы формы.

Выполнение метода Объект.ЗаявкиДляОбработки.Очистить() удаляет данные из таблицы, но **не сбрасывает счетчик идентификаторов** формы. При добавлении новых строк платформа продолжат задавать им новые числовые ID. Именно поэтому при повторном заполнении выделенные строки получают значения 10, 11, 12 и так далее.

Как правильно получать данные выделенной строки по ее идентификатору

Чтобы обратиться к данным строки коллекции формы по известному идентификатору из массива ВыделенныеСтроки, необходимо использовать специализированный метод коллекции НайтиПоИдентификатору().

Проанализируем пример корректной обработки выделенных строк на клиенте:


&НаКлиенте
Процедура ОбработатьВыделенныеСтроки()
    
    // Получаем массив идентификаторов выделенных строк элемента формы
    МассивИдентификаторов = Элементы.ЗаявкиДляОбработки.ВыделенныеСтроки;
    
    Для Каждого ИдентификаторИзМассива Из МассивИдентификаторов Цикл
        
        // Находим элемент коллекции по его числовому ID
        СтрокаТаблицы = Объект.ЗаявкиДляОбработки.НайтиПоИдентификатору(ИдентификаторИзМассива);
        
        Если СтрокаТаблицы <> Неопределено Тогда
            // Обрабатываем полученную строку
            Сообщить("Обрабатываем документ: " + СтрокаТаблицы.Документ);
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Как узнать порядковый индекс строки в коллекции

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

Рассмотрим по шагам, как определить порядковый индекс выделенной строки:

  1. Получаем идентификатор из свойства ВыделенныеСтроки.
  2. Находим объект строки методом НайтиПоИдентификатору().
  3. Передаем найденный объект в метод Индекс().

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


СтрокаТаблицы = Объект.ЗаявкиДляОбработки.НайтиПоИдентификатору(ИдентификаторСтроки);
Если СтрокаТаблицы <> Неопределено Тогда
    ПорядковыйИндекс = Объект.ЗаявкиДляОбработки.Индекс(СтрокаТаблицы);
    Сообщить("Порядковый номер строки в таблице: " + ПорядковыйИндекс);
КонецЕсли;

Передача выделенных данных на сервер для обработки

В управляемых формах контекст элементов формы (включая свойство Элементы.ЗаявкиДляОбработки.ВыделенныеСтроки) доступен только на клиенте. Чтобы выполнить тяжелую обработку или изменение объектов в базе данных, необходимо передавать с клиента на сервер массив ссылок или ключей, а не идентификаторы элементов формы.

Разберем правильную схему работы:


&НаКлиенте
Процедура КнопкаОбработатьНаКлиенте()
    
    МассивСсылок = Новый Массив;
    
    Для Каждого ИдентификаторИзМассива Из Элементы.ЗаявкиДляОбработки.ВыделенныеСтроки Цикл
        СтрокаТаблицы = Объект.ЗаявкиДляОбработки.НайтиПоИдентификатору(ИдентификаторИзМассива);
        Если СтрокаТаблицы <> Неопределено Тогда
            МассивСсылок.Добавить(СтрокаТаблицы.ДокументСсылка);
        КонецЕсли;
    КонецЦикла;
    
    Если МассивСсылок.Количество() > 0 Тогда
        ОбработатьДокументыНаСервере(МассивСсылок);
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура ОбработатьДокументыНаСервере(МассивСсылок)
    
    Для Каждого СсылкаДок Из МассивСсылок Цикл
        // Выполняем действия с документами в базе данных
    КонецЦикла;
    
КонецПроцедуры

Советы по сохранению выделения при перезаполнении таблицы

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

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