gifts2017

СКД-отборы списков на обычных и управляемых формах

Опубликовал Осипов Сергей (fixin) в раздел Программирование - Практика программирования

Иногда требуется вывести на форму отбор списка элементов с произвольными СКД-подобными отборами. В статье рассматривается, как это сделать в управляемых и обычных формах.

Образец такого отбора:

 

Реализация в управляемых формах

Рассмотрим на примере отбора списка контрагентов в управляемой форме внешней обработки.

В форму добавляем реквизит "ОтборКонтрагентов" типа "КомпоновщикНастроекКомпоновкиДанных".

Размещаем созданный реквизит на форме перетаскиванием поля КомпоновщикНастроекКомпоновкиДанных.Отбор на форму:

Для красоты дополнительно:

  1. Указываем заголовок "Контрагенты"
  2. Указываем положение заголовка "Верх"
  3. Указываем положение командной панели "Нет"

В конструкторе поле выглядит так:

Добавляем в макеты внешней обработки новый макет с типом схема компоновки данных "СКД_Контрагенты":

Источником данных будет запрос:

 

ВЫБРАТЬ
       Контрагенты.Ссылка,
       Контрагенты.Наименование
ИЗ
       Справочник.Контрагенты КАК Контрагенты

 

Отборов на форме может быть несколько, поэтому для удобства программиста все они называются Ссылка, а вот для удобства пользователя нужно назначить для ссылки представление, для этого ставим галочку и вводим название поля для пользователя "Контрагент":

Больше ничего в схеме компоновки не заполняем.

Теперь нужно привязать компоновщик настроек к схеме компоновки:

 

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
       ОО = РеквизитФормыВЗначение("Объект"); //Для внешних обработок реквизиты получаем так
       СКД = ОО.ПолучитьМакет("СКД_Контрагенты");
       URLСКД = ПоместитьВоВременноеХранилище(СКД, Новый УникальныйИдентификатор());
       ОО.ОтборКонтрагентов.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(URLСКД));
       НастройкиПоУмолчанию = СКД.НастройкиПоУмолчанию;
       ОО.ОтборКонтрагентов.ЗагрузитьНастройки(НастройкиПоУмолчанию);
       ЗначениеВРеквизитФормы(ОО, "Объект"); //Для внешних обработок реквизиты сохраняем так
КонецПроцедуры

 

После этого настройки отображаются на форме в требуемом виде:

 

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

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

 

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

В итоге в МассивКонтрагентов будет искомый перечень контрагентов.

 

Код используемых функций:

Функция УстановитьСтруктуруНастроекДляВыводаВТаблицуСКолонкойСсылка(Настройки)  Экспорт
       Настройки.Структура.Очистить();
       ТекГруппировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
       ТекГруппировка.Использование = Истина;
       ТекПолеГруппировки = ТекГруппировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
       ТекПолеГруппировки.Поле = Новый ПолеКомпоновкиДанных("Ссылка");
       ТекПолеГруппировки.Использование = истина;
       АвтоВыбор = ТекГруппировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
    АвтоВыбор.Использование = Истина;
      
      
КонецФункции
Функция СкомпоноватьВТаблицуЗначений(СхемаКомпоновкиДанных, КомпоновщикНастроек) Экспорт
       //Запускаем компоновку
       КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
       МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки,,,Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
       //Создаем процессор компоновки
       ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
       ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
      
       //Выводим в таблицу значений
       ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
       ТЗ = ПроцессорВывода.Вывести(ПроцессорКомпоновки, истина);
      
       Возврат ТЗ;
КонецФункции

Реализация в обычных формах

Рассмотрим на примере отбора магазинов.

Добавляем в реквизиты реквизит "Компоновщик_Магазины" с типом " КомпоновщикНастроекКомпоновкиДанных".

Аналогично УФ заполняем макет "СКД_Магазины" с запросом:

 

ВЫБРАТЬ
       Т.Ссылка
ИЗ
       Справочник.Магазины КАК Т

 

Размещаем на форме табличное поле с данными "Компоновщик_Магазины.Настройки.Отбор".

В модуле объекта добавляем глобальную переменную мСКД_Магазины.

В процедуру " ПередОткрытием" добавляем код:

 

       мСКД_Магазины = ПолучитьМакет("СКД_Магазины");
       Компоновщик_Магазины.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(мСКД_Магазины));
       Компоновщик_Магазины.ЗагрузитьНастройки(мСКД_Магазины.НастройкиПоУмолчанию);

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

 

       УстановитьСтруктуруНастроекДляВыводаВТаблицуСКолонкойСсылка(ОО.ОтборКонтрагентов.Настройки); 
       МассивМагазинов = СкомпоноватьВТаблицуЗначений(мСКД_Магазины, Компоновщик_Магазины).ВыгрузитьКолонку("Ссылка")

 

В итоге в МассивМагазинов будет искомый перечень магазинов.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Fomix (fomix) 28.04.16 14:49
Описания явно не хватает! Рассчитано на подготовленного пользователя, уже умеющего работать с управляемыми формами.
Только сегодня на сайте "курсы-по-1с.рф" вышли видеоуроки по применению СКД для реализация универсальных отборов . Привожу ссылку на страницу http://курсы-по-1с.рф/news/2016-04-28-skd-free-video/. Привожу здесь не в качестве рекламы, а для изучения...
2. Осипов Сергей (fixin) 28.04.16 14:58
(1) ну батенька это мастер-класс, для тех, кто уже знает СКД и хочет на ее основе крутить фортеля. Не для новисов, да.
Выстрадано на своей шкуре. В свое время делал на обычных формах, на СКД пришлось повозиться.
3. Fomix (fomix) 28.04.16 16:02
(2) fixin, Аналогично, дружище!
4. tixis1c tixis1c (qwed557) 01.05.16 14:19
По сути, это перенесенная в печатный вид статья из видео, которое рассылает проект курсы-по-1с.рф. давали бы ссылку на первоисточник. Вот ссылка а видео http://xn----1-bedvffifm4g.xn--p1ai/news/2016-04-28-skd-free-video/ , где с коментами объясняется, что для чего делается.
5. Трактор Трактор (Трактор) 05.05.16 12:17
Ничего исправлять ненадо. Кратко, только суть. Видео, которое тут рекламируют занимает гораздо больше времени на просмотр, чем чтение этой статьи и обрывается на самом интересном месте.
fixin, если курсы-по-1с.рф придут тебя бить - зови, помогу :-) Тебе помогу, не им.
6. Two World (Prometeus2011) 15.05.16 14:37
Взял на вооружение. Есть и другие способы, как использовать 1совские классы не очевидными и малоизвестными способами. Вот, например, иногда, использую построитель запросов:

ОтборСтрок = <ТабличнаяЧастьИсточник.ОтборСтрок>; 
ПостроительЗапроса = Новый ПостроительЗапроса; 
ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличнаяЧастьИсточник); 
// Добавляются необходимые отборы, такие же как в отборы в табличной части. 
Для Каждого ЭлементОтбора Из ОтборСтрок Цикл 
    Если ЭлементОтбора.Использование Тогда 
        НовыйОтбор = ПостроительЗапроса.Отбор.Добавить(ЭлементОтбора.Имя); 
        НовыйОтбор.Использование = Истина; 
        НовыйОтбор.ВидСравнения = ЭлементОтбора.ВидСравнения; // нужный вид сравнения 
        НовыйОтбор.ЗначениеС = ЭлементОтбора.ЗначениеС; 
        НовыйОтбор.ЗначениеПо = ЭлементОтбора.ЗначениеПо; 
        НовыйОтбор.Значение = ЭлементОтбора.Значение; 
    КонецЕсли; 
КонецЦикла; 

ПостроительЗапроса.Выполнить ();

Результат = ПостроительЗапроса.Результат; // отобранные строки типа РезультатЗапроса
...Показать Скрыть


Источник - не помню.
yurii_host; +1 Ответить
7. Two World (Prometeus2011) 15.05.16 16:54
Да, вот то-же самое с построителем отчета.

1. Добавляем на форму реквизит с типом "ПостроительОтчета" и назовем его так-же "ПостроительОтчета".

2. На форму кладем ЭУ типа "Табличное поле", звать - как хотите. Источником данных у элемента управления назначаем наш реквизит формы "ПостроительОтчета".

В модуль формы:

Процедура КнопкаВыполнитьНажатие(Кнопка)
	ЭтаФорма.ПостроительОтчета.Выполнить();
	тз = ЭтаФорма.ПостроительОтчета.Результат.Выгрузить();
КонецПроцедуры

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

	
	
КонецПроцедуры
...Показать Скрыть


Такое кунг-фу в групповой обработке на обычных формах юзалось эффективно достаточно.

Понятно, что работать будет только на обычном приложении.

p.s. Процедурку УстановитьСтруктуруНастроекДляВыводаВТаблицуСКолонкойСсылка(Настройки) можно не вызывать, а структуру вывода в ТЗ запаять прямо в схему макета СКД (это я про вариант автора).
8. Роман Озеряный (rozer) 09.06.16 15:23
(2) fixin, небольшое замечание:

Судя по описанию "ОтборКонтрагентов" это "реквизит формы"


В форму добавляем реквизит "ОтборКонтрагентов" типа "КомпоновщикНастроекКомпоновкиДанных".


А не объекта. И тогда так не сработает ...

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
....
ОО.ОтборКонтрагентов.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(URLСКД));
НастройкиПоУмолчанию = СКД.НастройкиПоУмолчанию;
ОО.ОтборКонтрагентов.ЗагрузитьНастройки(НастройкиПоУмолчанию);
...
КонецПроцедуры



Но так будет работать...
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ОО = РеквизитФормыВЗначение("Объект"); //Для внешних обработок реквизиты получаем так
	СКД = ОО.ПолучитьМакет("СКД");
	URLСКД = ПоместитьВоВременноеХранилище(СКД, Новый УникальныйИдентификатор());
	ЭтотОбъект.ОтборКонтрагентов.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(URLСКД));
	НастройкиПоУмолчанию = СКД.НастройкиПоУмолчанию;
	ЭтотОбъект.ОтборКонтрагентов.ЗагрузитьНастройки(НастройкиПоУмолчанию);
	//ЗначениеВРеквизитФормы(ОО, "Объект"); //Для внешних обработок реквизиты сохраняем так
КонецПроцедуры

...Показать Скрыть
9. Andrey Smirnov (dusha0020) 07.07.16 09:15
Проделывал такое не раз, но вот заняться и построить универсальные процедуры "на каждый день" для всяких типов форм не сподобился. Спасибо автору! +
10. Осипов Сергей (fixin) 07.07.16 11:51
(9) я недавно делал клиенту задачку с отбором по сотрудникам, сам нашел в интернете эту свою статью и заюзал. крутой отбор получился, а то бы пришлось делать убожество со списком сотрудников, например.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа