Выбор элементов справочников в поле формы


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

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

Для элемента формы, отвечающего за правило подбора заполняем его «список значений для выбора» необходимыми вариантами как на рисунке 1. Устанавливаем событие «ПриИзменении» для этого элемента, устанавливаем событие «ПередОткрытием» для всей формы, вставляем этот код и всё.

Благодарю за внимание!

 
перем ПредыдущаяПараПравил;


Процедура
КнопкаВыполнитьНажатие(Кнопка)
   
ТаблицаКонтрагенты = ПолучитьТаблицуЭлементовИзПоляФормы(«Контрагенты», Истина);
    Для каждого
СтрокаТаблицы Из ТаблицаКонтрагенты Цикл
       
Сообщить(СтрокаТаблицы.Ссылка.Наименование);
       
ОбработкаПрерыванияПользователя();
    КонецЦикла;
   
ТаблицаНоменклатура = ПолучитьТаблицуЭлементовИзПоляФормы(«Номенклатура»);
    Для каждого
СтрокаТаблицы Из ТаблицаНоменклатура Цикл
       
Сообщить(СтрокаТаблицы.Ссылка.Наименование);
       
ОбработкаПрерыванияПользователя();
    КонецЦикла;
КонецПроцедуры

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
   
УстановитьПравилоПодбораВПолеФормы(ЭлементыФормы.ПравилоКонтрагенты.Значение, «Контрагенты»);
   
УстановитьПравилоПодбораВПолеФормы(ЭлементыФормы.ПравилоНоменклатура.Значение, «Номенклатура»);
КонецПроцедуры

Процедура ПравилоКонтрагентыПриИзменении(Элемент)
   
УстановитьПравилоПодбораВПолеФормы(Элемент.Значение, «Контрагенты»);
КонецПроцедуры

Процедура ПравилоНоменклатураПриИзменении(Элемент)
   
УстановитьПравилоПодбораВПолеФормы(Элемент.Значение, «Номенклатура»);
КонецПроцедуры

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

//Возвращает таблицу выбранных элементов справочника с колонкой «Ссылка»
Функция ПолучитьТаблицуЭлементовИзПоляФормы(НазваниеСправочника, ВключатьГруппы = Ложь)
   
ИсходнаяТаблица = Новый ТаблицаЗначений();
   
ИсходнаяТаблица.Колонки.Добавить(«КолонкаЭлементов», Новый ОписаниеТипов(«СправочникСсылка.» + НазваниеСправочника));
   
ЗначениеПравила = ЭлементыФормы[«Правило» + НазваниеСправочника].Значение;
    Если
ЗначениеПравила = «Равно» ИЛИ ЗначениеПравила = «ВГруппе» Тогда
        Если
ЭлементыФормы[НазваниеСправочника].Значение = Справочники[НазваниеСправочника].ПустаяСсылка() Тогда
           
ВыборВключаетЭлементы = Ложь;
        Иначе
           
ВыборВключаетЭлементы = Истина;
        КонецЕсли;
    ИначеЕсли
ЗначениеПравила = «НеРавно» ИЛИ ЗначениеПравила = «НеВГруппе» Тогда
       
ВыборВключаетЭлементы = Ложь;
    ИначеЕсли
ЗначениеПравила = «ВСписке» Тогда
           
ВыборВключаетЭлементы = Истина;
    ИначеЕсли
ЗначениеПравила = «НеВСписке» Тогда
        Если
ЭтаФорма[НазваниеСправочника].Количество() = 0 Тогда
           
ВыборВключаетЭлементы = Истина;
        Иначе
           
ВыборВключаетЭлементы = Ложь;
        КонецЕсли;
    Иначе
       
ВыборВключаетЭлементы = Истина;
    КонецЕсли;
    Если
ТипЗнч(ЭлементыФормы[НазваниеСправочника].Значение) = Тип(«СписокЗначений») Тогда
        Для Каждого
текСтрока Из ЭлементыФормы[НазваниеСправочника].Значение Цикл
           
табСтрока = ИсходнаяТаблица.Добавить();
           
табСтрока.КолонкаЭлементов = текСтрока.Значение;
        КонецЦикла;
    Иначе
       
табСтрока = ИсходнаяТаблица.Добавить();
       
табСтрока.КолонкаЭлементов = ЭлементыФормы[НазваниеСправочника].Значение;
    КонецЕсли;
   
Запрос = Новый Запрос;
   
Запрос.Текст = «
    |ВЫБРАТЬ * ПОМЕСТИТЬ ИсходнаяТаблица ИЗ &ИсходнаяТаблица КАК ИсходнаяТаблица
    |;
    |ВЫБРАТЬ
    |   Ссылка
    |ИЗ
    |   Справочник.»
+ НазваниеСправочника + «
    |ГДЕ
    |   »
+ ?(ВключатьГруппы, «», » НЕ ЭтоГруппа И «) + «
    |   Ссылка »
+ ?(ВыборВключаетЭлементы, «», «НЕ») + » В ИЕРАРХИИ (ВЫБРАТЬ КолонкаЭлементов ИЗ ИсходнаяТаблица)
    |»
;
   
Запрос.УстановитьПараметр(«ИсходнаяТаблица», ИсходнаяТаблица);
    Возврат
Запрос.Выполнить().Выгрузить();
КонецФункции

4 Comments

  1. KonstB

    Это Вы называете «мини» ???

    Чем Вам типовой способ подбора, через построитель отчета/запроса не угодил????

    Вот весь код (с учетом выбора из любого справочника), сделал за 1 мин 26 сек (специально засек…):

    Процедура КнопкаВыполнитьНажатие(Кнопка)
    Результат = ПостроительОтчета.ПолучитьЗапрос().Выполнить().Выгрузить();
    ЭлементыФормы.Результат.СоздатьКолонки();
    КонецПроцедуры
    
    Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    Для каждого Спр Из Метаданные.Справочники Цикл
    ЭлементыФормы.ВидСправочника.СписокВыбора.Добавить(Спр.Имя, Спр.Синоним,, БиблиотекаКартинок.Справочник);
    КонецЦикла;
    КонецПроцедуры
    
    
    Процедура ВидСправочникаПриИзменении(Элемент)
    ОбъектМетаданных = Элемент.Значение;
    
    ПостроительОтчета.Текст = «ВЫБРАТЬ
    | » + ОбъектМетаданных + «.Ссылка КАК » + ОбъектМетаданных + »
    |ИЗ
    | Справочник.» + ОбъектМетаданных + » КАК » + ОбъектМетаданных;
    ПостроительОтчета.ЗаполнитьНастройки();
    
    КонецПроцедуры
    
    

    Показать

    В результате ТЗ со списком ссылок

    Reply
  2. KonstB

    Зачем изобретать велосипед, да еще и с квадратными колесами…

    Почитай, про: ОбработкаПрерыванияПользователя(); 🙂

    Reply
  3. leles

    (1) Да, спасибо, хороший пример. Когда я смотрел подбор номенклатуры в прайс, там с построителем было значительно больше кода, и честно сказать не захотел с этим разбираться и набросал свой вариант. Возможно колёса у него слегка угловатые, зато в спицы ленточки вплетены и трещотка стоит:

    Хотелось не нагружать пользователя разнообразием выбора. Есть один справочник — выбрал способ отбора, затем сами элементы и всё. Без таблицы, без возможности выбора реквизитов элементов.

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

    Замечания дельные, принимаю. Покручу ещё Вашу обработку, может, переделаю свою. Спасибо за опыт!

    Reply
  4. KonstB

    (3) leles, Пожалуйста 🙂

    Еще добавлю: Не хотите нагружать пользователя — не нагружайте:

     ПостроительОтчета.Текст = «ВЫБРАТЬ
    | » + ОбъектМетаданных + «.Ссылка КАК » + ОбъектМетаданных + »
    |ИЗ
    | Справочник.» + ОбъектМетаданных + » КАК » + ОбъектМетаданных + »
    |{ГДЕ
    | » + ОбъектМетаданных + «.Ссылка,
    | » + ОбъектМетаданных + «.Код,
    | » + ОбъектМетаданных + «.ИНН}»;
    ПостроительОтчета.ЗаполнитьНастройки();
    
    ПостроительОтчета.ДоступныеПоля.Удалить(ПостроительОтчета.ДоступныеПоля.Найти(ОбъектМетаданных));
    
    

    Показать

    В результате отбор только по полям: Ссылка, Код и ИНН.

    + само поле отбора возможно навесить «рюшечками», чтобы пользователю нельзя было удалять/изменять данные — в общем все как ВАМ угодно 🙂

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *