Как реализовать подбор в управляемой форме 1С 8.3 из произвольной таблицы значений

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Реализация механизма подбора — одна из наиболее часто встречающихся задач при разработке в среде 1С:Предприятие 8.3. Часто стандартного подбора из справочника недостаточно, и требуется предоставить пользователю возможность выбора из предварительно подготовленного набора данных, например, из ТаблицыЗначений. В этой статье мы подробно разберем, как передать данные в форму подбора, организовать выбор и вернуть результат в основную форму обработки.

Постановка задачи и общая схема решения

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

Шаг 1. Передача данных в форму подбора через временное хранилище

Поскольку ТаблицаЗначений не является типом, который можно напрямую передать между клиентом и сервером в параметрах формы без потери структуры (в управляемом приложении), мы воспользуемся временным хранилищем. Рассмотрим, как подготовить данные в основной форме обработки.

Для начала проанализируем код вызова. Нам необходимо поместить таблицу во временное хранилище и передать адрес этого хранилища в открываемую форму.


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

&НаСервере
Функция ПодготовитьДанныеДляПодбораНаСервере()
    
    // Допустим, ТЗ_Данные - это ваша сформированная таблица значений
    ТЗ_Данные = ПолучитьТаблицуДляВыбора(); 
    
    // Помещаем во временное хранилище с привязкой к уникальному идентификатору формы
    Возврат ПоместитьВоВременноеХранилище(ТЗ_Данные, ЭтаФорма.УникальныйИдентификатор);
    
КонецФункции

Шаг 2. Получение и отображение данных в форме подбора

Теперь разберем, как форма подбора должна принять эти данные. В форме подбора нам понадобится реквизит формы с типом ТаблицаЗначений (например, с именем ТаблицаДляВыбора), который будет отображаться в элементе формы типа «Таблица».

В модуле формы подбора проанализируем обработчик ПриСозданииНаСервере. Здесь мы извлечем данные по переданному адресу.


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

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

Шаг 3. Реализация выбора и возврат результата

Когда пользователь определился с выбором, нам нужно передать выбранные строки обратно. Рассмотрим вариант с использованием метода ОповеститьОВыборе. Выясним, как это работает на стороне формы подбора.


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

Если требуется реализовать множественный подбор (выбор нескольких строк без закрытия формы), установите свойство формы ЗакрыватьПриВыборе в значение Ложь и используйте массив структур для передачи данных.

Шаг 4. Обработка результата в основной форме

Вернемся к основной форме. Чтобы она «услышала» выбор из дочерней формы, необходимо использовать предопределенную процедуру ОбработкаВыбора. Рассмотрим пример заполнения основной табличной части Товары.


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

Особенности работы с внешними обработками

Выясним важную деталь, упомянутую в обсуждении. При работе с внешними обработками метод ОткрытьФорму("Форма1") может выдать ошибку «Неизвестное имя формы», так как система не понимает, к какому объекту относится эта форма. Рассмотрим правильный синтаксис обращения к форме внешней обработки:

ОткрытьФорму("ВнешняяОбработка.ИмяВашейОбработки.Форма.ИмяФормыПодбора", Параметры, ЭтаФорма);

Чтобы код оставался универсальным и не зависел от того, как пользователь переименовал файл .epf, рекомендуется определять имя программно через ЭтаФорма.ИмяФормы, как было показано в первом шаге.

Рекомендации по оптимизации

Для повышения производительности и удобства при работе с большими объемами данных в подборе, придерживайтесь следующих правил:

  1. Используйте УникальныйИдентификатор формы при помещении во временное хранилище. Это гарантирует, что данные будут автоматически удалены из памяти сервера после закрытия формы.
  2. Если в окне подбора нужно производить сложные вычисления или фильтрацию, делайте это в модуле формы подбора через ДанныеФормыВЗначение, работайте с объектом ТаблицаЗначений на сервере, а затем возвращайте результат обратно в ДанныеФормы.
  3. Для удобства пользователя реализуйте в форме подбора строку поиска, которая будет фильтровать данные в элементе ТаблицаДляВыбора с помощью свойства Отбор или метода НайтиСтроки.

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

← На главную