На самом деле более эффективно передавать данные между формами через временное хранилище, работа с которым будет происходить на сервере. Ведь основная масса строк табличной части находится на сервере, а не на клиенте, и поэтому логично было бы передать их другой форме прямо с сервера, не «таская» их на клиент.
Для этого перед открытием формы подбора нужно сначала записать данные табличной части документа во временное хранилище, а в форме подбора прочитать его и загрузить в список отобранных товаров.
Изменим обработчик команды Подбор следующим образом (листинг 4.50).
Листинг 4.50. Обработчик команды «Подбор»
&НаКлиенте
Процедура Подбор(Команда)
АдресТоваровВХранилище = ПоместитьТоварыВХранилище();
ПараметрыПодбора = Новый Структура("АдресТоваровДокумента", АдресТоваровВХранилище);
ФормаПодбора = ОткрытьФорму("Документ.РасходнаяНакладная.Форма.ФормаПодбора", ПараметрыПодбора, ЭтаФорма);
КонецПроцедуры
В этом обработчике в функции ПоместитьТоварыВХранилище() мы помещаем данные, выгруженные из табличной части документа, во временное хранилище. Эта функция возвращает адрес данных в хранилище – АдресТоваровВХранилище. Затем открываем форму подбора с параметром АдресТоваровДокумента, содержащим этот адрес.
Поместим в модуле формы документа функцию ПоместитьТоварыВХранилище(), выполняющуюся на сервере с контекстом формы (листинг 4.51).
Листинг 4.51. Функция «ПоместитьТоварыВХранилище()»
&НаСервере
Функция ПоместитьТоварыВХранилище()
Возврат ПоместитьВоВременноеХранилище(Объект.Товары.Выгрузить( ,"Товар,Количество"), УникальныйИдентификатор);
КонецФункции
В самом начале модуля формы документа мы определяем клиентскую переменную АдресТоваровВХранилище, чтобы потом получить по этому адресу список отобранных товаров из формы подбора (листинг 4.52).
Листинг 4.52. Определение переменной «АдресТоваровВХранилище»
&НаКлиенте
Перем АдресТоваровВХранилище;
Теперь создадим в форме подбора строковый реквизит АдресТоваровДокумента для хранения адреса товаров в хранилище. Заполнять его будем в обработчике события формы ПриСозданииНаСервере (листинг 4.53).
Листинг 4.53. Обработчик события «ПриСозданииНаСервере»
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
АдресТоваровДокумента = Параметры.АдресТоваровДокумента;
ОтобранныеТовары.Загрузить(ПолучитьИзВременногоХранилища(АдресТоваровДокумента));
КонецПроцедуры
В этом обработчике мы сохраняем в реквизите АдресТоваровДокумента адрес товаров во временном хранилище, получаем из хранилища данные по этому адресу и загружаем их в таблицу значений ОтобранныеТовары.
Таким образом, список отобранных товаров при открытии формы подбора будет заполнен данными табличной части расходной накладной.
Теперь при закрытии формы подбора по нажатию кнопки ОК нужно записать список отобранных товаров во временное хранилище, а в форме документа прочитать его и загрузить обратно в табличную часть.
Изменим обработчик команды ОК следующим образом (листинг 4.54).
Листинг 4.54. Обработчик команды «ОК»
&НаКлиенте
Процедура ОК(Команда)
ЗаписатьПодборВХранилище();
ВладелецФормы.ОбработатьПодбор();
Закрыть();
КонецПроцедуры
Поместим в модуле формы подбора процедуру ЗаписатьПодборВХранилище(), выполняющуюся на сервере с контекстом формы, для записи данных таблицы значений ОтобранныеТовары во временное хранилище по адресу АдресТоваровДокумента (листинг 4.55).
Листинг 4.55. Процедура «ЗаписатьПодборВХранилище()»
&НаСервере
Процедура ЗаписатьПодборВХранилище()
ПоместитьВоВременноеХранилище(ОтобранныеТовары.Выгрузить(), АдресТоваровДокумента);
КонецПроцедуры
Процедуру ОбработатьПодбор() владельца формы, то есть формы объекта – документа РасходнаяНакладная, изменим следующим образом (листинг 4.56).
Листинг 4.56. Процедура «ОбработатьПодбор()»
&НаКлиенте
Процедура ОбработатьПодбор() Экспорт
ПолучитьТоварыИзХранилища(АдресТоваровВХранилище);
Модифицированность = Истина;
КонецПроцедуры
Поместим в модуле формы документа процедуру ПолучитьТоварыИзХранилища(), выполняющуюся на сервере с контекстом формы, для чтения данных из временного хранилища. В процедуру мы передаем адрес этих данных в хранилище, хранящийся в клиентской переменной АдресТоваровВХранилище (листинг 4.57).
Листинг 4.57. Процедура «ПолучитьТоварыИзХранилища()»
&НаСервере
Процедура ПолучитьТоварыИзХранилища(АдресТоваровВХранилище)
Объект.Товары.Загрузить(ПолучитьИзВременногоХранилища(АдресТоваровВХранилище));
КонецПроцедуры
В этой процедуре мы получаем товары из временного хранилища по адресу АдресТоваровВХранилище и загружаем их в табличную часть документа.
Таким образом, табличная часть расходной накладной при закрытии формы подбора по кнопке ОК будет заполнена списком отобранных товаров.
ПРИМЕЧАНИЕ
Этот пример можно посмотреть в демонстрационной конфигурации «11 (вар. 2) Использование временного хранилища для передачи данных между формами».
Запустим «1С:Предприятие», откроем документ Расходная накладная № 3 (он содержит 1000 позиций товаров) и нажмем кнопку Подбор. После этого строки табличной части документа будут помещены во временное хранилище. Затем откроется форма подбора. При ее открытии данные из хранилища будут прочитаны и загружены в список отобранных товаров.
Посмотрим, сколько вызовов сервера при этом произойдет и какой будет объем передаваемых данных между клиентом и сервером. Мы специально рассматриваем пример документа с большой табличной частью, так как на нем лучше сравнивать показатели производительности.
Таблица 4.5. Показатели производительности
| Текущие вызовы | Отправлено | Принято |
|---|---|---|
| 2 | 2 353 | 12 536 |
Мы видим, что сервер вызывается 2 раза. Один вызов происходит при записи данных табличной части в хранилище, а второй – при открытии формы подбора методом ОткрытьФорму().
Объем принятых данных отражает ситуацию, когда на клиент «приезжает» форма и видимые 35 строк табличной части.
Для наглядности рассмотрим схему передачи данных между клиентом и сервером (первый вариант решения для сравнения приведен слева), рис. 4.70.

Рис. 4.70. Схема передачи данных между клиентом и сервером
После того как пользователь произведет подбор товаров из справочника (в нашем примере выбран всего один товар) и закроет форму подбора, отобранные товары и их количество будут помещены во временное хранилище. В форме документа в процедуре ОбработатьПодбор() данные из хранилища будут прочитаны и загружены обратно в табличную часть.
Посмотрим теперь на показатели производительности.
Таблица 4.6. Показатели производительности
| Текущие вызовы | Отправлено | Принято |
|---|---|---|
| 2 | 5196 | 182538 |
Здесь один вызов сервера тратится на помещение таблицы значений ОтобранныеТовары из формы подбора в хранилище, а второй – на чтение этих данных из хранилища в форме документа.
Объем принятых данных отражает ситуацию, когда вся табличная часть «приезжает» в форму документа на клиент, так как мы ее заново загрузили на сервере из временного хранилища.
Для наглядности рассмотрим схему передачи данных между клиентом и сервером (первый вариант решения для сравнения приведен слева), рис. 4.71.

Рис. 4.71. Схема передачи данных между клиентом и сервером
Объем принятых данных близок к аналогичным показателям в первом варианте. И, действительно, все будет похоже. Здесь мы получаем всю табличную часть с сервера, и это занимает 182 538. А в первом примере мы, наоборот, передавали всю табличную часть на сервер (рис. 4.70). И там это заняло 189 303. В принципе, значения одинаковые, разница объясняется разными направлениями движения данных (может использоваться разная степень сжатия данных) и нюансами кеширования.
Для наглядности рассмотрим схему программного взаимодействия клиента и сервера (рис. 4.72).

Рис. 4.72. Схема программного взаимодействия сервера и клиента
При открытии формы подбора из процедуры Подбор() один вызов сервера произойдет при записи списка товаров табличной части документа во временное хранилище, а второй вызов – собственно при открытии формы подбора.
ПРИМЕЧАНИЕ
Заметим, что при первом открытии формы могут быть лишние серверные вызовы за счет кеширования платформой необходимой информации о форме.
При закрытии формы подбора из процедуры ОК() один вызов сервера произойдет при записи списка отобранных товаров во временное хранилище, а второй вызов – из процедуры формы документа ОбработатьПодбор() при чтении отобранных товаров из временного хранилища и загрузке их в табличную часть документа.
Итого 4 контекстных вызова сервера вместо 57 (в первом варианте)!
По объему передаваемых данных в первом случае получается: 153 302 + 189 303 + 97 690 = 440 295.
Во втором случае получается: 12 536 + 182 538 = 195 074.
То есть разница в объеме передаваемых данных больше чем в два раза!
Что показательно, в первом случае количество серверных вызовов будет увеличиваться пропорционально увеличению табличной части, а во втором варианте количество серверных вызовов будет постоянным независимо от объема табличной части. Это тоже важный момент.
Таким образом, мы видим, что при большом массиве передаваемых данных такой вариант обмена данными между формами будет более оптимальным.