Есть управляемая форма документа. На ней две табличные части. В форме есть некая серверная процедура, которая пересчитывает часть данных в табличных частях, в этой процедуре табличные части выгружаются в таблицы значений, передаются в общий модуль для обработки, потом загружаются обратно.
Процедура пересчета серверная и вызывается из разных мест модуля формы, и из серверных процедур и из клиентских.
Как сохранить при этом текущие строки в табличных частях?

Я думал их куда-то записывать перед вызовом процедуры, это надо найти все точки начала процесса пересчета на клиентской стороне и записать куда-то, например в клиентские глобальные переменные формы (или в реквизиты формы, наверное это все равно), и еще туда же записывать какой-то флажок, что надо восстановить положения в табличных частях, и потом после пересчета искать текущие строки. Но во-первых это ничего себе алгоритм для такого вроде бы небольшого дела. Во-вторых, непонятно, как узнать момент, когда нужно это восстановление? например, если пересчет инициализирован обработкой подбора, в какой момент на клиентской части надо выполнять это дело?...
Как правильно сделать?
---
Сделал я в итоге, совсем простого метода не нашлось, пришлось в каждое место, откуда вызывается переформирование таблиц, добавить пару строк

```1c
    // это ключи, в которых хранятся текущие позиции списков, чтобы можно было их восстановить после манипуляций
    // структура содержит две структуры с ключами для поиска в каждой из ТЧ и два флажка, нужен там поиск или нет
    &НаКлиенте
    Перем СтруктураТекущихКлючей;

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

    Если Элементы.ГотоваяПродукция.ТекущиеДанные <> Неопределено Тогда
    СтруктураТекущихКлючей.ТекущийКлючПродукции.Вставить("Номенклатура", Элементы.ГотоваяПродукция.ТекущиеДанные.Номенклатура);
    СтруктураТекущихКлючей.ТекущийКлючПродукции.Вставить("Характеристика", Элементы.ГотоваяПродукция.ТекущиеДанные.Характеристика);
    СтруктураТекущихКлючей.ТекущийКлючПродукции.Вставить("КлючСвязи", Элементы.ГотоваяПродукция.ТекущиеДанные.КлючСвязи);
    СтруктураТекущихКлючей.Вставить("ВосстанавливатьПродукцию", Истина);
    Иначе
    СтруктураТекущихКлючей.Вставить("ВосстанавливатьПродукцию", Ложь);
    КонецЕсли;
    КонецПроцедуры

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

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

    // и вот такие вызовы везде, где надо
    &НаКлиенте
    Процедура МатериалыПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
    ЗаполнитьКлючи();
    ЗаполнитьСтоимостьНаСервере();
    ВосстановитьТекущиеСтроки();
    КонецПроцедуры

    СтруктураТекущихКлючей = Новый Структура;
    СтруктураТекущихКлючей.Вставить("ТекущийКлючПродукции", Новый Структура);
    СтруктураТекущихКлючей.Вставить("ТекущийКлючМатериалов", Новый Структура);
```
---
Я в похожей ситуации сохранял в структуру ключевые поля для идентификации строки в таблице. Эту структуру передавал в качестве параметров далее в процедуры. По окончании расчетов на основании ключевых полей получал идентификатор строки и, таким образом, восстанавливал текущую строку. В случае изменения состава (кол-ва) строк работает корректно.
---
это верно, но вот например я вызываю стандартный подбор номенклатуры. Он открывает штатную обработку, потом вызывается ОбработкаПодбора и в ней в конце мой пересчет.
Куда тут передавать лишние параметры? Переписывать все штатные процедуры? И в какой момент потом вызывать возврат текущей строки, закончилась обработка подбора и на этом все действие завершились, и это на стороне сервера...
---
Как же плохо не читать книги по используемым механизмам...
А ведь в книге по УФ, и в профразработке этот случай описан и разобран...
---
оно http://its.1c.ru/db/pubmanagedui#content:230:1? Ну, я думаю ТС с этим знаком.
---
Если бы он был знаком - вопроса бы не возникло.
---
а) у меня нет доступа и б) судя по комментариям "знатоков" (6), это не работает, иначе знатоки бы описали алгоритм в двух словах :)
---
"Судя по комментариев знатоков" - это работает. И работает хорошо.
А расписывать алгоритм - открой книжку и прочитай.
Или получи тестовый доступ на неделю к ИТС.
---
Надо сохранить текущую строку (которая выделена), или восстановить порядок строк?
---
текущую сохранить. Порядок строк не нарушается, там все нормально.
---
может добавить реквизит формы (число) и в него записывать номер текущей строки и после всех манипуляций с таблицой установить текущую строку взяв номер строки из реквизита?
---
Сделал я в итоге, совсем простого метода не нашлось, пришлось в каждое место, откуда вызывается переформирование таблиц, добавить пару строк

```1c
    // это ключи, в которых хранятся текущие позиции списков, чтобы можно было их восстановить после манипуляций
    // структура содержит две структуры с ключами для поиска в каждой из ТЧ и два флажка, нужен там поиск или нет
    &НаКлиенте
    Перем СтруктураТекущихКлючей;

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

    Если Элементы.ГотоваяПродукция.ТекущиеДанные <> Неопределено Тогда
    СтруктураТекущихКлючей.ТекущийКлючПродукции.Вставить("Номенклатура", Элементы.ГотоваяПродукция.ТекущиеДанные.Номенклатура);
    СтруктураТекущихКлючей.ТекущийКлючПродукции.Вставить("Характеристика", Элементы.ГотоваяПродукция.ТекущиеДанные.Характеристика);
    СтруктураТекущихКлючей.ТекущийКлючПродукции.Вставить("КлючСвязи", Элементы.ГотоваяПродукция.ТекущиеДанные.КлючСвязи);
    СтруктураТекущихКлючей.Вставить("ВосстанавливатьПродукцию", Истина);
    Иначе
    СтруктураТекущихКлючей.Вставить("ВосстанавливатьПродукцию", Ложь);
    КонецЕсли;
    КонецПроцедуры

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

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

    // и вот такие вызовы везде, где надо
    &НаКлиенте
    Процедура МатериалыПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
    ЗаполнитьКлючи();
    ЗаполнитьСтоимостьНаСервере();
    ВосстановитьТекущиеСтроки();
    КонецПроцедуры

    СтруктураТекущихКлючей = Новый Структура;
    СтруктураТекущихКлючей.Вставить("ТекущийКлючПродукции", Новый Структура);
    СтруктураТекущихКлючей.Вставить("ТекущийКлючМатериалов", Новый Структура);
```