Передача данных между управляемыми формами - 1С-ИнтеГрация

Передача данных между управляемыми формами



Поставленная задача

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

Подбор осуществлястя только по элементам справочника. При переносе в табличную часть, если товар уже в нее был добавлен, нужно увеличить количество в этой строке на значение, указанное в подборе.

Реализация

Для демонстрации двух вариантов передачи данных между управляемыми формами реализуем оба варианта в подборе.

Без обращения к серверу

Основная характеристика первого варианта - это отсутствие вызова сервера при переносе подобранных товаров в табличную часть документа. Все действия происходят на стороне клиента. Для реализации подобного подбора нужно выполнить ряд несложных действий.

Создадим форму списка у справочника "Товары". При этом не назначим ее основной. В реквизиты формы добавим таблицу "ПодобранныеТовары" и разместим соответствующий элемент формы. При этом для полей динамического списка "ЭтоГруппа" и "Ссылка" установим флаг "Использовать всегда". Далее Вы увидите для чего.

Теперь нам нужно написать программный код обработки выбора в динамическом списке. Все действия выбора будут сводитсья к добавлению строки в таблицу "Подобранные товары" элементов справочника. Если элемент уже был добавлен в таблицу, то увеличиваем его количество. Программный код обработки выбора (событие "Выбор") списка номенклатуры приведен на следующем листинге:

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

Если ТекДанные.ЭтоГруппа Тогда Возврат; КонецЕсли;
// Отключаем стандартную обработку
СтандартнаяОбработка = Ложь;
// Ищем товар в таблице "Подобранные товары". Если нет - добавляем строку, иначе добавляем количество
РезультатПоиска = ПодобранныеТовары.НайтиСтроки(Новый Структура("Товар", ТекДанные.Ссылка));
Если РезультатПоиска.Количество() = 0 Тогда
Стр = ПодобранныеТовары.Добавить();
Стр.Товар = ТекДанные.Ссылка;
Иначе
Стр = РезультатПоиска[0];
КонецЕсли;
Стр.Количество = Стр.Количество + 1;
КонецПроцедуры
 Форма подбора товаров вызывается из формы документа по команде "Подбор".

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

&НаКлиенте
Процедура Подбор(Команда)
// Первый параметр - полное имя формы, третий параметр - элемент формы, в который осуществляется подбор.
// Последним параметром передается уникальный идентификатор формы.

ОткрытьФорму("Справочник.Товары.Форма.ПодборТоваров", , Элементы.Товары, УникальныйИдентификатор);
КонецПроцедуры
Когда в форме выбора необходимые товары подобраны выполняется команда "ПеренестиВДокументКлиент". Обработчик события очень простой:

&НаКлиенте
Процедура ПеренестиВДокументКлиент(Команда)
// Передаем в родительский элемент формы "Товары" данные выбора - таблицу "Подобранные товары"
ОповеститьОВыборе(ПодобранныеТовары);
КонецПроцедуры
После выполнения метода "ОповеститьОВыборе" данные передаются в обработчик "ОбработкаВыбора" элемента формы документа "Товары", и далее обрабатывается:

// Заполняем таблицу документа подобранными товарами
Для Каждого Стр Из ВыбранноеЗначение Цикл
РезультатПоиска = Объект.Товары.НайтиСтроки(Новый Структура("Товар", Стр.Товар));
Если РезультатПоиска.Количество() = 0 Тогда 
НовСтр = Объект.Товары.Добавить();
НовСтр.Товар = Стр.Товар;
Иначе
НовСтр = РезультатПоиска[0];
КонецЕсли;
НовСтр.Количество = НовСтр.Количество + Стр.Количество;
КонецЦикла;
В результате таблица товаров документа будет заполнена. При использвовании этого варианта передачи данных между формами не было произведено вызовов к серверу. Однако у подобного подхода есть несколько больших минусов:

Большие объемы данных могут передаваться некорректно. По опыту работы с управляемыми формами скажу, что очень часто возникали ошибки типа "Ошибка передачи данных", если размер таблицы был больше мегабайта.
Если передаваемые данные требуют обработки (получение остатков товара, цен и т.д.), то все эти действия необходимо выполнять на серверной стороне. Поэтому было бы правильней в форме подбора поместить их на серверную сторону, а уже на стороне документа обработать и и поместить в объект документа.
Поэтому рассмотрим вариант передачи данных между формами через сервер. 
 
С обращением к серверу

Отличия в реализации подбора будут в этом случае только в передаче данных в документ и, затем, обработки подобранных товаров в документе. Вот таким образом будет выглядеть команда передачи данных в документ из подбора:

&НаКлиенте
Процедура ПеренестиВДокументСервер(Команда)
// Помещаем подобранные товары во временное хранилище на сервере
// и получаем соответствующий адрес в нем

Адрес = ПодготовитьДанныеДляПодбора();
// Передаем в родительский элемент формы данные выбора
// Адрес - это строка, длинной не более 60 символов.

ОповеститьОВыборе(Адрес);
КонецПроцедуры
&НаСервере
Функция ПодготовитьДанныеДляПодбора()
// Выгружаем таблицу формы в таблицу значений для корректного отображения на сервере
ТаблицаПодобранныхТоваров = ПодобранныеТовары.Выгрузить();
// Помещаем во временное хранилище и возвращаем адрес
// Вторым параметром передаем уник. идентификатор формы. После закрытия формы данные во временном
// хранилище будут очищены

Возврат ПоместитьВоВременноеХранилище(ТаблицаПодобранныхТоваров, УникальныйИдентификатор);
КонецФункции
КонецПроцедуры

Теперь алгоритм обработки выбора элемента формы документа "Товары" изменится следующим образом:

&НаКлиенте
Процедура ТоварыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
// Обрабатываем значение выбора на сервере
ОбработкатьВыбранноеЗначение(ВыбранноеЗначение);
КонецПроцедуры
&НаСервере
Процедура ОбработкатьВыбранноеЗначение(ВыбранноеЗначение)
// Получаем таблицу подобранных товаров на сервере
ТаблицаПодобранныхТоваров = ПолучитьИзВременногоХранилища(ВыбранноеЗначение);
// Переносим в таблицу "Товары" подобранные элементы
Для Каждого Стр Из ТаблицаПодобранныхТоваров Цикл
РезультатПоиска = Объект.Товары.НайтиСтроки(Новый Структура("Товар", Стр.Товар));
Если РезультатПоиска.Количество() = 0 Тогда
НовСтр = Объект.Товары.Добавить();
НовСтр.Товар = Стр.Товар;
Иначе
НовСтр = РезультатПоиска[0];
КонецЕсли;
НовСтр.Количество = НовСтр.Количество + Стр.Количество;
КонецЦикла;
КонецПроцедуры

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

Вместо выводов

Способ передачи данных между формами зависит от конкретной задачи, поэтому не стоит думать, что использование временного хранилища на сервере является абсолютно правильным решением. В типовых конфигурациях, таких как "Управление торговлей 11" или "Розница" подбор осуществляется с использованием временного хранилища на сервере. Однако для простых задач, на подобии рассмотренного примера, осуществление передачи данных на клиенсткой стороне куда оптимальней, нежели вызов сервера.


Источник



Назад в раздел