Дмитрий Малюгин где-то в 2001 Безусловно, поддержка иерархии элементов справочников в V7 относится к одному из ее основных
достоинств. Особенно в свете того, что запросы к регистрам позволяют получать итоги не только
по группировкам запроса, но и по группам элементов справочников (здесь и далее обращаем
внимание на отличие понятий групп/группирования и группировка).
Как органично включить иерархию справочников в платформу? Возможно ли это без нарушения
основополагающего принципа, что все агрегатные объекты являются наследниками объекта ТД?
Или все же иерархия и таблицы две вещи несовместные?
Начнем с того, что разумным и несложным в реализации является допущение наличия нескольких
иерархий у одного справочника. Например, если пользователь желает иметь возможность
поддерживать иерархию товаров с одной стороны по поставщикам, а с другой по видам
товаров, то почему бы не позволить ему сделать это? Естественно, при этом становится очевидным,
что хранение элементов-групп справочников должно быть организовано в отдельной таблице
для каждой иерархии своя таблица (отдельный класс Таблица
Поддержки Иерархии) и свои "групповые" реквизиты. Также становится очевидным, что
редактирование элемента иерархического справочника удобнее вести в диалоговой форме элемента,
а не в списке.
В этой диалоговой форме должно быть доступен реквизит для выбора группы-родителя, которой
принадлежит данный элемент. Если иерархий две, то и родителей должно быть два, по одному из
каждой иерархии и т.д. В форме списка справочника должна быть добавлена возможность выбора,
какую из иерархий использовать для отражения элементов. Кроме того, ведение иерархий в
отдельной таблице снимет проблему искусственного ограничения уровней иерархии. Поскольку
элементы-группы в иерархии могут ссылаться только на элементы из этой же иерархии, то
какая разница, сколько будет ступенек до верхнего уровня?
Кстати, пригодилась бы и поддержка иерархий (групп) для документов. Для некоторых типов
документов возможность их "раскладки по папкам" была бы полезной.
Теперь о том, как проецировать группы кортежей в ТД. Предположим, что имеем ТД, где
значениями одной из колонок являются ссылки на кортежи какого-либо типа. В эту ТД необходимо
добавить учет определенной иерархии данных кортежей. В V7, как известно, элементы-группы в
таблице значений помещаются в той же колонке, что и обычные элементы справочника.
Является ли данное решение приемлемым? На наш взгляд, нет.
Таким "группированием" неудобно пользоваться прежде всего потому, что
в одной колонке смешаны значения разных типов. Но отводить под каждый уровень иерархии
отдельную колонку тоже неразумно тем более что количество таких уровней
заранее неизвестно. Следовательно, остается единственный вариант: все элементы-группы
помещаются в одной, но отдельной от простых элементов колонке. Причем ТД сгруппирована по
данной колонке.
Алгоритм формирования такой колонки будет следующим:
- На первом шаге исходная ТД
группируется "вверх" по реквизиту элементов "Родитель". Это обычная группировка, при
определении которой могут быть указаны также колонки с какими-либо итогами.
- На втором шаге перебираются кортежи получившейся таблицы-владельца, и для каждого
элемента-группы в таблицу добавляются кортежи со значениями всех его родителей (значения
итоговых колонок копируются).
- На третьем шаге производится свертка кортежей-групп и их упорядочивание обычным
последовательным обходом (разворотом) всех ветвей дерева, начиная с верхнего.
Итак, все кортежи ТД с обычными элементами становятся подчиненными по отношению ТД с
группами. Таким образом, перебирая группы в таблице-владельце, в подчиненной таблице
получаем элементы, принадлежащие только данной группе. Отметим, что при данном способе
представления иерархии в ТД (а он представляется нам наиболее логичным) обход элементов
иерархии отличается от аналогичного обхода групп и элементов объекта
Запрос в V7.
В запросе, как известно, обход начинается с групп самого верхнего уровня и спускается к
группам нижнего уровня, в результате чего первыми перебираются простые элементы самого
нижнего уровня иерархии, а последними самого верхнего.
В нашей же модели после позиционирования на самой верхней группе можно перебирать
элементы, принадлежащие именно данной группе. Вернувшись из цикла обхода элементов,
перейти к следующей группе и т.д.
Поясним сказанное на примере. Пусть мы имеем некий набор элементов класса ABCD
с определенной иерархией Hier1 и некую ТД с итогами для элементов
ABCD:
ABCD |
Элемент |
Родитель |
a |
p |
b |
p |
c |
r |
d |
s |
|
Hier1 |
Элемент |
Родитель |
s |
- |
p |
- |
r |
s |
|
ТД2 |
Элемент |
Родитель |
a |
1 |
b |
3 |
c |
2 |
d |
3 |
|
Элементы ABCD с иерархией и таблица данных.
|
Сгруппируем последовательно ТД2 по группам Hier1 элементов
ABCD с учетом итогов по NUM:
Шаг 1 |
Hier1 |
NUM |
p |
4 |
r |
2 |
s |
3 |
|
Шаг 2 |
Hier1 |
NUM |
p |
4 |
r |
2 |
s |
3 |
s |
2 |
|
Шаг 3 |
Hier1 |
NUM |
p |
4 |
s |
5 |
r |
2 |
|
Последовательное добавление "группировки по группам" ТД2.
|
Исходная ТД2 получает идентификатор ТД2.Hier1 (или подобный) и становится
подчиненной ТД2. Отметим, что для элементов-групп итоги по суммируемым колонкам подчиненных
им таблиц могут не совпадать (быть меньше) с итогами, записанными в таблице-владельце
(элемент s в ТД2).
Таким образом, мы кратко обсудили "разумные" подходы к организации поддержки иерархий
кортежей в платформе, рассмотрели взаимодействие понятий Иерархия
и Группировка ТД. Следующий интересный момент в V7
это поддержка динамичности кортежей, хранение истории атрибутов справочников, состояния
регистров.
Попытаемся нащупать общий подход к проблемам на основе понятия
Функциональная зависимость (ФЗ).
Резюме.
- Поддержка групп кортежей должна осуществляться в отдельной ТД.
- Допускается поддержка нескольких иерархий элементов одного и того же типа.
- Операция группировки ТД по группам элементов выполняется в три этапа.
Элементы-группы и просто элементы не смешиваются в одной колонке.
- Нет причин, препятствующих организации поддержки иерархий документов.
|