Господа, хочу поделиться с вами одним из вариантов организации формы подбора.
Идея в следующем:
есть две таблицы значений – в первой находится список выбираемых данных, во второй – список выбранных данных. В качестве примера может служить любой документ с табличной частью, где нужно при помощи запроса или других средств организовать какую либо выборку, и уже руками отобрать из нее нужные записи, поместив их в табличную часть данного документа.
Для этого, перед открытием данной формы нам необходимо сформировать таблицу выборки и поместить ее во временное хранилище для передачи адреса в качестве параметра. Аналогично, необходимо поместить в хранилище и таблицу выбора (например, табличную часть документа).
Текст кода из формы документа, откуда вызываем форму выбора:
&НаКлиенте
Процедура КнопкаПодбор(Команда)
ПараметрыПодбора = Новый Структура;
ПараметрыПодбора.Вставить("ЗакрыватьПриВыборе", Ложь);
ПараметрыПодбора.Вставить("РежимВыбора", Истина);
ПараметрыПодбора.Вставить("АдресТаблицыВыбранныхДанных", АдресСпискаПодобранныхПоказаний());
ПараметрыПодбора.Вставить("АдресТаблицыИсходныхДанных", ФормированиеТаблицыПодбора(ДобавитьМесяц(ТекущаяДата(), -18*12)));//Выберем совершеннолетних
ОткрытьФорму("ОбщаяФорма.ОбщаяФормаПодбора", ПараметрыПодбора, Элементы.ФизическиеЛица);
КонецПроцедуры
&НаСервере
Функция АдресСпискаПодобранныхПоказаний()
Возврат ПоместитьВоВременноеХранилище(Объект.ФизическиеЛица.Выгрузить(,"ФизическоеЛицо"), УникальныйИдентификатор);
КонецФункции
&НаСервере
Функция ФормированиеТаблицыПодбора(ДатаРождения)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФизическиеЛица.Ссылка КАК ФизическоеЛицо,
| ФизическиеЛица.ДатаРождения
|ИЗ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ГДЕ
| ФизическиеЛица.ДатаРождения <= &ДатаРождения";
Запрос.УстановитьПараметр("ДатаРождения", ДатаРождения);
ТалицаИсходныхДанных = Запрос.Выполнить().Выгрузить();
//Уберем из исходной таблицы уже имеющиеся (если таковые есть) данные в таблице документа
Для Каждого СтрокаТаблицы Из Объект.ФизическиеЛица Цикл
НайденныеСтроки = ТалицаИсходныхДанных.НайтиСтроки(Новый Структура("ФизическоеЛицо", СтрокаТаблицы.ФизическоеЛицо));
Для Каждого ТекущаяСтрока Из НайденныеСтроки Цикл
ТалицаИсходныхДанных.Удалить(ТекущаяСтрока);
КонецЦикла;
КонецЦикла;
Возврат ПоместитьВоВременноеХранилище(ТалицаИсходныхДанных, УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура ФизическиеЛицаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
Объект.ФизическиеЛица.Очистить();
ВыбранныеДанныеВТаблицуДокумента(ВыбранноеЗначение);
КонецПроцедуры
&НаСервере
Процедура ВыбранныеДанныеВТаблицуДокумента(ВыбранноеЗначение)
Для Каждого СтрокаТаблицы Из ПолучитьИзВременногоХранилища(ВыбранноеЗначение) Цикл
НоваяСтрока = Объект.ФизическиеЛица.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицы);
КонецЦикла;
КонецПроцедуры
Далее работаем с формой подбора.
После вызова формы, считываем входные параметры, формируем таблицы на форме и переносим в них данные для подбора:
#Область НачалоРаботыСФормой
//Считываем входные параметры и формируем таблицы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ФормированиеТаблицы("ТалицаИсходныхДанных", Параметры.АдресТаблицыИсходныхДанных);
ФормированиеТаблицы("ТаблицаВыбранныхДанных", Параметры.АдресТаблицыВыбранныхДанных);
КонецПроцедуры
//Формируем таблицу на форме, соответствующую таблице в хранилище и переносим в нее данные
&НаСервере
Процедура ФормированиеТаблицы(ИмяТаблицыНаФорме, АдресТаблицыВХранилище)
ТаблицаРодителя = Новый ТаблицаЗначений;
ТаблицаРодителя = ПолучитьИзВременногоХранилища(АдресТаблицыВХранилище);
/////////////////////////////////////////////////////////
//Почистим таблицу на форме
ТаблицаВыбранныхДанных.Очистить();
МассивУдаляемыхРеквизитов = Новый Массив;
РеквизитыТЗ = ПолучитьРеквизиты(ИмяТаблицыНаФорме);
Если РеквизитыТЗ.Количество() > 0 Тогда
Для Каждого Реквизит Из РеквизитыТЗ Цикл
МассивУдаляемыхРеквизитов.Добавить(ИмяТаблицыНаФорме + "." + Реквизит.Имя);
КонецЦикла;
ЭтаФорма.ИзменитьРеквизиты(,МассивУдаляемыхРеквизитов);
Для Каждого Реквизит Из РеквизитыТЗ Цикл
УдаляемыйЭлемент = Элементы.Найти(ИмяТаблицыНаФорме + "_" + Реквизит.Имя);
Если УдаляемыйЭлемент <> Неопределено Тогда
Элементы.Удалить(УдаляемыйЭлемент);
КонецЕсли;
КонецЦикла;
КонецЕсли;
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//Создаем массив реквизитов - колонок для таблицы значений на форме
МассивРеквизитов = Новый Массив;
Для Каждого Колонка Из ТаблицаРодителя.Колонки Цикл
МассивРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ИмяТаблицыНаФорме, Колонка.Заголовок));
КонецЦикла;
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//Выводим добавленные колонки на форму
ЭтаФорма.ИзменитьРеквизиты(МассивРеквизитов);
Таблица = Элементы[ИмяТаблицыНаФорме];
Таблица.Отображение = ОтображениеТаблицы.Список;
Для Каждого Колонка Из ТаблицаРодителя.Колонки Цикл
НовыйЭлемент = Элементы.Добавить(ИмяТаблицыНаФорме + "_" + Колонка.Имя, Тип("ПолеФормы"), Таблица);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = ИмяТаблицыНаФорме + "." + Колонка.Имя;
НовыйЭлемент.Заголовок = ВспомогательныеФункции.СформироватьСиноним(Колонка.Имя);
КонецЦикла;
ТаблицаНаФорме = РеквизитФормыВЗначение(ИмяТаблицыНаФорме);
ТаблицаНаФорме.Очистить();
//Переносим данные из входящей таблицы значений в таблицу значений на форме
Для Каждого СтрокаТаблицыРодителя Из ТаблицаРодителя Цикл
НоваяСтрока = ТаблицаНаФорме.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицыРодителя);
КонецЦикла;
ЗначениеВРеквизитФормы(ТаблицаНаФорме, ИмяТаблицыНаФорме);
/////////////////////////////////////////////////////////
КонецПроцедуры
#КонецОбласти
Для обработки выбранных данных использую следующие процедуры и функции:
#Область ОбъектыДляОбработкиВыбора
&НаКлиенте
Процедура ТалицаИсходныхДанныхВыборЗначения(Элемент, Значение, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ВыборСтроки(Элемент.ТекущиеДанные);
ЭтотОбъект.ТалицаИсходныхДанных.Удалить(Элемент.ТекущиеДанные);
КонецПроцедуры
&НаКлиенте
Процедура ВыбратьВсе(Команда)
Для Каждого СтрокаТаблицы Из ЭтотОбъект.ТалицаИсходныхДанных Цикл
ВыборСтроки(СтрокаТаблицы);
КонецЦикла;
ЭтотОбъект.ТалицаИсходныхДанных.Очистить();
КонецПроцедуры
&НаКлиенте
Функция ВыборСтроки(ВыбраннаяСтрока)
НоваяСтрока = ЭтотОбъект.ТаблицаВыбранныхДанных.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ВыбраннаяСтрока);
КонецФункции
#КонецОбласти
Следующая функция из имени колонки формирует синоним для заголовка колонки таблицы на форме:
&НаСервереБезКонтекста
// Формирует синоним переменной.
// Пример: на входе "ИмяПеременнойАБВГ", на выходе "Имя переменной АБВГ"
//
// Параметры
// ИмяРеквизита - Строка. Имя переменной, имя колонки таблицы
//
// Возвращаемое значение:
// Строка - Представление переменной
//
Функция СформироватьСиноним(ИмяРеквизита)
Перем Синоним, НомерСимвола, Символ, ПредСимвол, СледСимвол, Прописная, ПредПрописная, СледПрописная, ДлинаСтроки;
Синоним = ВРег(Сред(ИмяРеквизита, 1, 1));
ДлинаСтроки = СтрДлина(ИмяРеквизита);
Для НомерСимвола = 2 По ДлинаСтроки Цикл
Символ = Сред(ИмяРеквизита, НомерСимвола, 1);
ПредСимвол = Сред(ИмяРеквизита, НомерСимвола - 1, 1);
СледСимвол = Сред(ИмяРеквизита, НомерСимвола + 1, 1);
Прописная = Символ = ВРег(Символ);
ПредПрописная = ПредСимвол = ВРег(ПредСимвол);
СледПрописная = СледСимвол = ВРег(СледСимвол);
// Варианты:
Если НЕ ПредПрописная И Прописная Тогда
Синоним = Синоним + " " + НРег(Символ);
ИначеЕсли Прописная И НЕ СледПрописная Тогда
Синоним = Синоним + " " + НРег(Символ);
Иначе
Синоним = Синоним + НРег(Символ);
Конецесли;
КонецЦикла;
Возврат Синоним;
КонецФункции // СформироватьСиноним(ИмяРеквизита)
После завершения работы, форма поместит таблицу выбранных значений во временное хранилище и вернет в вызвавший ее объект адрес этой таблицы в хранилище.
Фрагмент текста кода из формы подбора:
&НаКлиенте
Процедура ПеренестиДанные(Команда)
ОповеститьОВыборе(АдресТаблицыВыбранныхДанных());
ЭтаФорма.Закрыть();
КонецПроцедуры
//Перед отправкой результата в вызвавший ее объект, поместим таблицу выбранных данных в хранилище.
&НаСервере
Функция АдресТаблицыВыбранныхДанных()
Возврат ПоместитьВоВременноеХранилище(ЭтотОбъект.ТаблицаВыбранныхДанных.Выгрузить(), УникальныйИдентификатор);
КонецФункции