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