Каталог решений - СКД не только для отчетов

СКД не только для отчетов

СКД не только для отчетов

В наличии

СКД позволяет получать данные из информационной базы не только для вывода в отчеты, но и для других целей. Пример такого использования рассматривается в настоящей статье.

Категория:

Описание

Отчеты это слишком просто!

Всем разработчикам, имеющим дело с платформой 1С:Предприятие 8.x, наверняка знаком хотя бы в общих чертах механизм системы компоновки данных (СКД). В большинстве ситуаций он используется для создания отчетов. Общую информацию о назначении и возможностях СКД Вы можете узнать здесь.

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

Однако, СКД может быть использована для решения иных задач, не только разработка отчетов. В настоящей статье это и будет продемонстрировано. Материал больше ориентирован на разработчиков, которые только начинают свой путь в мир СКД. Хотя, может и все разработчики найдут здесь что-то интересное.

Пример задачи

В справочнике "Товары" для группы "Группа — 1" и всех входящих в нее элементов необходимо вести историю изменения. Касаться вопроса почему для этого не подошел журнал регистрации не будем. Для решения задачи нужно создать отдельный регистр сведений с измерением "Товар", с типом ссылки на соответствующий справочник, и ресурсом "Ответственный" с типом "СправочникСсылка.Пользователи".

Самый простой путь решения подобной задачи — это создать подписку на событие "ПриЗаписи" справочника и выполнять запись для текущего элемента в описанный ранее регистр сведений. Так, например, выглядела бы добавленная подписка на события и программный код в обработчике подписки.

Процедура ПриЗаписиТовара(Источник, Отказ) Экспорт

	// Запрос на проверку вхождения номенклатуры в группу "Группа - 1"
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Товары.Ссылка
		|ИЗ
		|	Справочник.Товары КАК Товары
		|ГДЕ
		|	Товары.Ссылка В ИЕРАРХИИ (&Ссылка)
		|	И Товары.Ссылка = &ТекущийЭлемент";

	// Устанавливаем условие отбора в запросе по соответствующей группе
	Запрос.УстановитьПараметр("Ссылка",
	// TODO: НИКОГДА! НИКОГДА ТАК НЕ ДЕЛАЙТЕ!
	// Поиск по наименованию - последнее дело при разработке :)
	// Тут нужно либо брать значение из настроек (константы или другие таблицы),
	// либо на крайний случай использовать предопределенные элементы / поиск по GUID
		Справочники.Товары.НайтиПоНаименованию("Группа - 1", Истина));
	// Устанавливаем отбор по ссылке текущего элемента
	Запрос.УстановитьПараметр("ТекущийЭлемент", Источник.Ссылка);
	
	Результат = Запрос.Выполнить();

	// Если результат не пустой, тогда номенклатура входит в группу "Группа - 1"
	Если НЕ Результат.Пустой() Тогда

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

		Набор.Записать();

	КонецЕсли;

КонецПроцедуры

Однако у подобной реализации есть большие минусы:

  1. Мы жестко привязаны к имени группы "Группа — 1". Если пользователь изменит наименование группы, то алгоритм перестанет работать. В листинге есть раздел "TODO" по этому поводу.
  2. Если завтра пользователь захочет включить наблюдение не только для этой группы или наложить дополнительные условия на реквизиты товаров, то нужно будет снова подключать к работе программиста.

Вот тут то и вступает в бой СКД, предлагая более универсальное решение!

С нуля

В регистр сведений "ИзмененныеТовары" добавим макет с типом "СхемаКомпоновкиДанных". В нем нужно лишь написать запрос к справочнику "Товары" и настроить структуру схемы:

Схема готова! С ее помощью при каждой записи товара мы будем проверять удовлетворяет ли записываемый элемент условиям отбора, заданных пользователем. Настройки отбора задает сам пользователь в режиме 1С:Предприятия, которые сохраняются в константе "НастройкиОтборов" с типом "ХранилищеЗначения". 

Для начала рассмотрим как изменится программный код обработчика подписки на событие "ПриЗаписи" справочника "Товары":

Процедура ПриЗаписиТоваровСобытиеПриЗаписи(Источник, Отказ) Экспорт

	// Таблица результатов проверки
	РезультатПроверки = Новый ТаблицаЗначений;

	Настройки = Константы.НастройкиОтборов.Получить().Получить();
	Если Настройки = Неопределено Тогда
		Возврат;
	КонецЕсли;

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

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

	Если РезультатПроверки.Количеств() > 0 Тогда
	
		ПериодЗаписи = ТекущаяДатаСеанса();

		Набор = РегистрыСведений.ИзмененныеТовары.СоздатьНаборЗаписей();
		Набор.Отбор.Период.Установить(ПериодЗаписи);
		Набор.Отбор.Товар.Установить(Источник.Ссылка);
		
		Запись = Набор.Добавить();
		Запись.Период = ПериодЗаписи;		
		Запись.Товар = Источник.Ссылка;
		Запись.Ответственный = Пользователи.ТекущийПользователь();

		Набор.Записать();

	КонецЕсли;

КонецПроцедуры

Теперь проверку мы осуществляем не запросом, а получением данных через СКД. Условия выборки остались практически такими же, как и в первом предложенном варианте решения. Отбор устанавливается по ссылке на текущий элемент справочника "Товары", а также дополняется отборами, которые установил пользователь. Результат СКД выводится в таблицу значений. Если количество записей в ней больше 0, тогда текущий записываемый элемент справочника "Товары" удовлетворяет всем установленным отборам.

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

Пользовательские отборы хранятся в константе "НастройкиОтборов" в виде хранилища значения. Рассмотрим далее как эти настройки были настроены и установлены.

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

Настройки хранятся в константе, поэтому и редактировать их будем в форме констант. Создадим основную форму констант и в качестве реквизита формы добавим компоновщик настроек компоновки данных.

Чтобы компоновщик работал правильно необходимо:

  1. Инициализировать его для соответствующей схемы компоновки данных.
  2. Загрузить предыдущие настройки, если они были сохранены ранее.
 

has been added to your cart:
Оформление заказа