Реализация механизма подбора — одна из наиболее часто встречающихся задач при разработке в среде 1С:Предприятие 8.3. Часто стандартного подбора из справочника недостаточно, и требуется предоставить пользователю возможность выбора из предварительно подготовленного набора данных, например, из ТаблицыЗначений. В этой статье мы подробно разберем, как передать данные в форму подбора, организовать выбор и вернуть результат в основную форму обработки.
Представим ситуацию: у нас есть внешняя обработка, в которой программно сформирована ТаблицаЗначений. Нам нужно открыть вспомогательную форму, отобразить в ней эти данные, позволить пользователю выбрать одну или несколько строк и вернуть их в основную табличную часть. Для реализации этой задачи мы будем использовать механизм Временного хранилища и стандартные события формы ОбработкаВыбора.
Поскольку ТаблицаЗначений не является типом, который можно напрямую передать между клиентом и сервером в параметрах формы без потери структуры (в управляемом приложении), мы воспользуемся временным хранилищем. Рассмотрим, как подготовить данные в основной форме обработки.
Для начала проанализируем код вызова. Нам необходимо поместить таблицу во временное хранилище и передать адрес этого хранилища в открываемую форму.
&НаКлиенте
Процедура КомандаПодбор(Команда)
// Подготавливаем данные на сервере
АдресДанных = ПодготовитьДанныеДляПодбораНаСервере();
// Формируем параметры для открытия формы
ПараметрыПодбора = Новый Структура;
ПараметрыПодбора.Вставить("АдресТаблицы", АдресДанных);
// Важный нюанс для внешних обработок:
// Путь к форме должен включать полное имя внешней обработки
ИмяОснФормы = ЭтаФорма.ИмяФормы;
ПутьКФормеПодбора = СтрЗаменить(ИмяОснФормы, "ФормаОбъекта", "ФормаПодбора");
ОткрытьФорму(ПутьКФормеПодбора, ПараметрыПодбора, ЭтаФорма);
КонецПроцедуры
&НаСервере
Функция ПодготовитьДанныеДляПодбораНаСервере()
// Допустим, ТЗ_Данные - это ваша сформированная таблица значений
ТЗ_Данные = ПолучитьТаблицуДляВыбора();
// Помещаем во временное хранилище с привязкой к уникальному идентификатору формы
Возврат ПоместитьВоВременноеХранилище(ТЗ_Данные, ЭтаФорма.УникальныйИдентификатор);
КонецФункции
Теперь разберем, как форма подбора должна принять эти данные. В форме подбора нам понадобится реквизит формы с типом ТаблицаЗначений (например, с именем ТаблицаДляВыбора), который будет отображаться в элементе формы типа «Таблица».
В модуле формы подбора проанализируем обработчик ПриСозданииНаСервере. Здесь мы извлечем данные по переданному адресу.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("АдресТаблицы") Тогда
// Получаем таблицу из хранилища
ДанныеИзХранилища = ПолучитьИзВременногоХранилища(Параметры.АдресТаблицы);
Если ТипЗнч(ДанныеИзХранилища) = Тип("ТаблицаЗначений") Тогда
// Загружаем данные в реквизит формы
ЗначениеВДанныеФормы(ДанныеИзХранилища, Объект.ТаблицаДляВыбора);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратите внимание: если вы создаете форму программно, убедитесь, что колонки реквизита ТаблицаДляВыбора совпадают по именам и типам с колонками передаваемой таблицы значений, иначе данные не загрузятся.
Когда пользователь определился с выбором, нам нужно передать выбранные строки обратно. Рассмотрим вариант с использованием метода ОповеститьОВыборе. Выясним, как это работает на стороне формы подбора.
&НаКлиенте
Процедура ТаблицаДляВыбораВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем данные текущей строки
ТекущиеДанные = Элементы.ТаблицаДляВыбора.ТекущиеДанные;
// Формируем структуру с результатом
РезультатВыбора = Новый Структура;
РезультатВыбора.Вставить("Номенклатура", ТекущиеДанные.Номенклатура);
РезультатВыбора.Вставить("Количество", 1);
// Передаем данные владельцу и закрываем форму
ОповеститьОВыборе(РезультатВыбора);
КонецПроцедуры
Если требуется реализовать множественный подбор (выбор нескольких строк без закрытия формы), установите свойство формы ЗакрыватьПриВыборе в значение Ложь и используйте массив структур для передачи данных.
Вернемся к основной форме. Чтобы она «услышала» выбор из дочерней формы, необходимо использовать предопределенную процедуру ОбработкаВыбора. Рассмотрим пример заполнения основной табличной части Товары.
&НаКлиенте
Процедура ОбработкаВыбора(РезультатВыбора, ИсточникВыбора)
Если ТипЗнч(РезультатВыбора) = Тип("Структура") Тогда
// Добавляем новую строку в табличную часть обработки
НоваяСтрока = Объект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, РезультатВыбора);
КонецЕсли;
КонецПроцедуры
Выясним важную деталь, упомянутую в обсуждении. При работе с внешними обработками метод ОткрытьФорму("Форма1") может выдать ошибку «Неизвестное имя формы», так как система не понимает, к какому объекту относится эта форма. Рассмотрим правильный синтаксис обращения к форме внешней обработки:
ОткрытьФорму("ВнешняяОбработка.ИмяВашейОбработки.Форма.ИмяФормыПодбора", Параметры, ЭтаФорма);
Чтобы код оставался универсальным и не зависел от того, как пользователь переименовал файл .epf, рекомендуется определять имя программно через ЭтаФорма.ИмяФормы, как было показано в первом шаге.
Для повышения производительности и удобства при работе с большими объемами данных в подборе, придерживайтесь следующих правил:
ДанныеФормыВЗначение, работайте с объектом ТаблицаЗначений на сервере, а затем возвращайте результат обратно в ДанныеФормы.ТаблицаДляВыбора с помощью свойства Отбор или метода НайтиСтроки.Таким образом, мы проанализировали полный цикл создания подбора: от передачи исходной таблицы до обработки выбранного результата. Данный подход является наиболее гибким, так как позволяет использовать в качестве источника для подбора любые данные, которые вы можете собрать в таблицу значений.