Второй пример поможет понять некоторые особенности работы с коллекцией, которая хранит данные таблицы в реквизите формы. Мы будем рассматривать ситуацию, когда эти данные обрабатываются по некоторому непростому алгоритму. В примере мы будем всего лишь сортировать данные, но в реальной жизни это может быть гораздо более сложный алгоритм обработки.
Примечание
Пример можно посмотреть в демонстрационной базе «Таблица в форме», форма документа Накладная, команды Сортировать без выгрузки, Сортировать с выгрузкой (неправильно), Сортировать с выгрузкой (правильно). Это локальные команды формы.
Итак, наша задача – отсортировать табличную часть документа по возрастанию значений в колонке Цена.
Самый простой способ – обратиться непосредственно к реквизиту формы и выполнить его метод Сортировать() – листинг 3.119.
Листинг 3.119. Сортировка таблицы реквизита
&НаКлиенте
Процедура СортироватьБезВыгрузки(Команда)
Объект.Товары.Сортировать("Цена");
КонецПроцедуры
Допустим, перед выполнением этого действия текущей была, например, третья строка табличной части (рис. 3.140).

Рис. 3.140. Текущая строка перед выполнением сортировки
Тогда после выполнения сортировки эта же строка останется текущей. Она уже не будет третьей, но это будет та же самая строка (рис. 3.141).

Рис. 3.141. Текущая строка после сортировки
Теперь рассмотрим другой случай. Допустим, для выполнения нашего алгоритма нужно выгрузить данные из реквизита в таблицу значений, обработать их и затем загрузить обратно (команда Сортировать с выгрузкой (неправильно)) – листинг 3.120.
Листинг 3.120. Сортировка с выгрузкой и загрузкой. Неправильный вариант
&НаКлиенте
Процедура СортироватьСВыгрузкойНеправильно(Команда)
НаСервереНеправильно();
КонецПроцедуры
&НаСервере
Процедура НаСервереНеправильно()
ТЗ = Объект.Товары.Выгрузить();
ТЗ.Сортировать("Цена");
Объект.Товары.Загрузить(ТЗ);
КонецПроцедуры
В этом случае результат окажется другим. Строки, как и раньше, будут отсортированы, однако текущей станет первая строка таблицы (рис. 3.142).

Рис. 3.142. Сброс текущей строки после сортировки
Так происходит потому, что после загрузки данных в реквизит формы в нем фактически оказывается новая коллекция данных. Они могут не совпадать с теми данными, которые были из реквизита выгружены. Поэтому текущей становится первая строка таблицы, что соответствует стандартному поведению платформы.
Однако мы знаем, что данные, которые загружены, те же самые, поменялся лишь порядок строк. Как в этом случае сохранить правильную текущую строку?
Рассмотрим третий вариант (команда Сортировать с выгрузкой (правильно)) – листинг 3.121.
Листинг 3.121. Сортировка с выгрузкой и загрузкой. Правильный вариант
&НаКлиенте
Процедура СортироватьСВыгрузкойПравильно(Команда)
НаСервереПравильно();
КонецПроцедуры
&НаСервере
Процедура НаСервереПравильно()
СтрокаКоллекции = Объект.Товары.НайтиПоИдентификатору(Элементы.Товары.ТекущаяСтрока);
ИндексСтрокиКоллекции = Объект.Товары.Индекс(СтрокаКоллекции);
ТЗ = Объект.Товары.Выгрузить();
СтрокаВыгруженнойТаблицы = ТЗ.Получить(ИндексСтрокиКоллекции);
ТЗ.Сортировать("Цена");
ИндексСтрокиПослеСортировки = ТЗ.Индекс(СтрокаВыгруженнойТаблицы);
Объект.Товары.Загрузить(ТЗ);
СтрокаКоллекции = Объект.Товары.Получить(ИндексСтрокиПослеСортировки);
Элементы.Товары.ТекущаяСтрока = СтрокаКоллекции.ПолучитьИдентификатор();
КонецПроцедуры
Прежде всего, оказавшись на сервере, мы находим ту строку реквизита, которая соответствует текущей строке в таблице формы (листинг 3.122, рис. 3.143).
Листинг 3.122. Получение строки в коллекции реквизита
СтрокаКоллекции = Объект.Товары.НайтиПоИдентификатору(Элементы.Товары.ТекущаяСтрока);

Рис. 3.143. Получение строки в коллекции реквизита
Затем мы получаем индекс этой строки (листинг 3.123, рис. 3.144).
Листинг 3.123. Получение индекса строки в реквизите
ИндексСтрокиКоллекции = Объект.Товары.Индекс(СтрокаКоллекции);

Рис. 3.144. Получение индекса строки в реквизите
Этот индекс понадобится нам в дальнейшем, чтобы найти по нему эту же строку, но уже в таблице значений, в которую мы выгрузим данные (листинг 3.124).
Листинг 3.124. Получение строки в таблице значений
ТЗ = Объект.Товары.Выгрузить();
СтрокаВыгруженнойТаблицы = ТЗ.Получить(ИндексСтрокиКоллекции);
Поскольку в процессе выгрузки мы не преобразовывали таблицу (не изменяли порядок и количество строк), то наша строка в реквизите и аналогичная строка в выгруженной таблице значений будут иметь одинаковые индексы (рис. 3.145).

Рис. 3.145. Получение строки в таблице значений
Теперь, после того как в переменной СтрокаВыгруженнойТаблицы мы запомнили «текущую строку» таблицы значений, можно эту таблицу значений сортировать (листинг 3.125, рис. 3.146).
Листинг 3.125. Сортировка таблицы значений
ТЗ.Сортировать("Цена");

Рис. 3.146. Сортировка таблицы значений
В отсортированной таблице значений порядок строк поменялся, и нам нужно определить, какой же индекс стал теперь у нашей «текущей строки» (листинг 3.126, рис. 3.147).
Листинг 3.126. Получение индекса строки в таблице значений
ИндексСтрокиПослеСортировки = ТЗ.Индекс(СтрокаВыгруженнойТаблицы);

Рис. 3.147. Получение индекса строки в таблице значений
Зная этот индекс, мы можем загрузить данные обратно в реквизит и найти уже в нем ту строку, которая соответствует «текущей» (листинг 3.127, рис. 3.148).
Листинг 3.127. Получение строки в реквизите
Объект.Товары.Загрузить(ТЗ);
СтрокаКоллекции = Объект.Товары.Получить(ИндексСтрокиПослеСортировки);

Рис. 3.148. Получение строки в реквизите
И в заключение, зная «текущую строку» в реквизите, мы можем спозиционировать курсор в таблице формы на нужную нам строку, используя идентификатор (листинг 3.128, рис. 3.149).
Листинг 3.128. Позиционирование текущей строки в таблице формы
Элементы.Товары.ТекущаяСтрока = СтрокаКоллекции.ПолучитьИдентификатор();

Рис. 3.149. Позиционирование текущей строки в таблице формы
Если теперь посмотреть, как это работает в режиме 1С:Предприятие, мы увидим, что после сортировки текущей остается та строка, которая была ею перед началом действия.