Top.Mail.Ru

Если «Гвозди», то правильные. Продолжение

Введение

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

Поэтому хотелось бы предложить альтернативный вариант на базе регистра сведений.

Структура регистра:

Создаем в конфигурации периодический независимый регистр сведений «СоответствиеОбъектов» со следующей структурой:

Измерения:

ПервичныйКлюч — Строка(50)

ВторичныйКлюч — Строка, Число, ЛюбаяСсылка

Ресурсы:

Значение — ЛюбаяСсылка, Строка, Число, Булево, Дата (любой тип значения, которое мы собираемся хранить)

Реквизиты:

Описание — Строка(200) — описание значения, где используется, зачем и т.д.

Вкратце о назначении вторичного ключа:

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

Вы ведете разработку в «глубоко отраслевой» (читай, самописной «нетленке») конфигурации. И вам внезапно в рамках какой-либо задачи понадобилось хранить данные о ключевых должностях организаций. Типовой регистр ОтветственныеЛицаОрганизаций по понятным причинам отсутствует.

Если органзаций и/или должностей много, то при использовании одного строкового ключа, вам придется создать записи ДиректорРогаИКопыта, ДиректорРомашка, ДиректорКупиПродай, ГлБухРогаИКопыта, ГлБухРомашка и т.д. и т.п. Так же при разработке придется явно перечислять все эти ключи.

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

Методы для работы с регистром

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

// Функция возвращает значение и описание по первичному и вторичному(опционально) ключам
// Параметры:
//  ПервичныйКлюч - Строка - Основной ключ искомого значения
//  ВторичныйКлюч - ЛюбойТип - Дополнительный ключ искомого значения
//  Дата - Дата - Дата среза
//	
// Возвращаемое значение:
//	Структура - Структура с ключами Значение и Описание 
Функция ПолучитьЗначениеПоКлючу(ПервичныйКлюч, ВторичныйКлюч = Неопределено, Дата = Неопределено) Экспорт
	
	//если дата не указана, срез делаем на текущую дату
	ДатаСреза = ?(ЗначениеЗаполнено(Дата),Дата,ТекущаяДата());
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
	               |	СоответствияОбъектовСрезПоследних.Значение,
	               |	СоответствияОбъектовСрезПоследних.Описание
	               |ИЗ
	               |	РегистрСведений.СоответствияОбъектов.СрезПоследних(
	               |			&ДатаСреза,
	               |			ПервичныйКлюч = &ПервичныйКлюч
	               |				И (ВторичныйКлюч = &ВторичныйКлюч
	               |					ИЛИ &ВторичныйКлюч = НЕОПРЕДЕЛЕНО)) КАК СоответствияОбъектовСрезПоследних";
	Запрос.УстановитьПараметр("ПервичныйКлюч",ПервичныйКлюч);
	Запрос.УстановитьПараметр("ВторичныйКлюч",ВторичныйКлюч);
	Запрос.УстановитьПараметр("ДатаСреза",ДатаСреза);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	СтруктураКлючи = Новый Структура("Значение, Описание");
	Если Выборка.Количество() > 1 Тогда
		//существуют более одного набора по данному отбору
	Иначе
		Если Выборка.Следующий() Тогда
			ЗаполнитьЗначенияСвойств(СтруктураКлючи, Выборка);
		КонецЕсли;
	КонецЕсли;
	
	Возврат СтруктураКлючи;		
КонецФункции

// Функция возвращает ключи по значению, если такая запись существует
// Параметры:
//  Значение - ЛюбойТип - Дополнительный ключ искомого значения
//  Дата - Дата - Дата среза
//	
// Возвращаемое значение:
//	Структура - Структура с ключами ПервичныйКлюч и ВторичныйКлюч
Функция ПолучитьКлючиПоЗначению(Значение, Дата = Неопределено) Экспорт
	
	//если дата не указана, срез делаем на текущую дату
	ДатаСреза = ?(ЗначениеЗаполнено(Дата),Дата,ТекущаяДата());
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	               |	СоответствияОбъектовСрезПоследних.ПервичныйКлюч,
	               |	СоответствияОбъектовСрезПоследних.ВторичныйКлюч
	               |ИЗ
	               |	РегистрСведений.СоответствияОбъектов.СрезПоследних(&ДатаСреза, Значение = &Значение) КАК СоответствияОбъектовСрезПоследних";
	Запрос.УстановитьПараметр("Значение",Значение);
	Запрос.УстановитьПараметр("ДатаСреза",ДатаСреза);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	СтруктураКлючи = Новый Структура("ПервичныйКлюч, ВторичныйКлюч");;
	Если Выборка.Количество() > 1 Тогда
		//существуют более одного набора по данному отбору
	Иначе
		Если Выборка.Следующий() Тогда
			ЗаполнитьЗначенияСвойств(СтруктураКлючи, Выборка);
		КонецЕсли;
	КонецЕсли;
	
	Возврат СтруктураКлючи;
		
КонецФункции

// Функция проверяет наличие записей в регистре на все указанные ключи
// Параметры:
//  СтрокаКлючей - Строка - Ключи, перечисленные через запятую
//  Дата - Дата - Дата среза
//
// Возвращаемое значение:
//	Булево - результат проверки
Функция КлючиЗаполнены(СтрокаКлючей = "", Дата = Неопределено) Экспорт
	
	МассивКлючей = Новый Массив;
	ОбщегоНазначения.ЗаполнитьМассивУникальнымиЗначениями(МассивКлючей,СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(СтрокаКлючей)); 
	//если дата не указана, срез делаем на текущую дату
	ДатаСреза = ?(ЗначениеЗаполнено(Дата),Дата,ТекущаяДата());
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
	               |	СоответствияОбъектовСрезПоследних.ПервичныйКлюч
	               |ИЗ
	               |	РегистрСведений.СоответствияОбъектов.СрезПоследних(&ДатаСреза, Значение В (&МассивКлючей)) КАК СоответствияОбъектовСрезПоследних";
	Запрос.УстановитьПараметр("МассивКлючей",МассивКлючей);
	Запрос.УстановитьПараметр("ДатаСреза",ДатаСреза);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	СтруктураКлючи = Новый Структура("ПервичныйКлюч, ВторичныйКлюч");;
	
	Возврат Выборка.Количество() <> МассивКлючей.Количество();
		
КонецФункции

Применение

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

Перед выполнением самого алгоритма, использующего «гвозди» имеет смысл проверить их заполненность через метод КлючиЗаполнены(), чтобы не нагружать алгоритм лишними проверками.

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

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

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar