Отобразить данные справочника 1с в виде дерева. Представление данных в форме дерева. Добавление узлов в дерево
Граф - совокупность точек, соединённых между собой линиями. Точки называют вершинами графа. Они могут изображаться точками, кружочками, прямоугольниками и пр. Линии, соединяющие вершины, называются дугами (если задано направление от одной вершины к другой) или рёбрами (если направленность двусторонняя, то есть направления равноправны).
Две вершины, соединенные ребром (дугой) называются смежными . Вершины и рёбра графа могут характеризоваться некоторыми числовыми величинами. Например, может быть известна длина ребра или «стоимость прохождения» по нему. Такие характеристики называют весом, а граф называется взвешенным.
Граф однозначно задан, если заданы множество его вершин, множество рёбер (дуг) и указано, какие вершины какими рёбрами (дугами) соединены и, возможно, указаны веса вершин и рёбер (дуг). Определение всех этих элементов и составляет суть формализации в этом случае.
Информационную модель в форме графа можно использовать для наглядного представления взаимосвязей, существующих между элементами объекта моделирования. Таким образом, граф - наиболее удобная форма для моделирования структуры объекта, хотя в такой форме можно моделировать и внешний вид, и поведение объекта.
В форме графа удобно отображать взаимосвязи понятий, относящихся к одной области деятельности или познания .
Особым видом графа является дерево . Данная форма модели применяется тогда, когда элементы моделируемого объекта находятся в состоянии какого-либо подчинения и соподчинения, когда есть отношение иерархичности.
Пример .
Модель управления предприятием (школой, театральным коллективом и т. д.) очень удобно представлять в виде дерева.
Пример .
Вам хорошо известно понятие «родословное дерево» и вы можете изобразить в такой форме ваши родственные отношения.
Пример .
Каталог файлов на диске, также как и библиотечный каталог - примеры информационных моделей в форме дерева.
Дерево - это граф, предназначенный для отображения таких связей между объектами, как вложенность, подчиненность, наследование и т. п.
Строится он следующим образом .
Сначала рисуем «главную» вершину, которая не зависит ни от одной другой вершины. Эта вершина называется корнем дерева и является единственной вершиной 1-го уровня. Далее добавляем вершины 2-го уровня . Их может быть сколько угодно, и все они обязательно связаны с корнем - вершиной 1-го уровня, но не связаны между собой. На следующем шаге добавим вершины 3-го уровня. Каждая из них будет связана ровно с одной вершиной 2-го уровня (больше ни с одной другой вершиной). К любой вершине 2-го уровня может быть подсоединено сколько угодно вершин 3-го уровня (в том числе, ни одной). Следующий шаг - добавка вершин 4-го уровня , каждая из которых будет связана ровно с одной вершиной 3-го уровня (и не связана больше ни с чем). И так далее. На каждом шаге добавляем вершины очередного уровня, каждая из которых будет связана ровно с одной вершиной предыдущего уровня и не будет иметь никаких иных связей.
Полученный граф напоминает ветвящийся куст, который «растет сверху вниз»: верхние уровни имеют меньшие номера, нижние - большие.
Вообще говоря, дерево может быть и неориентированным графом, но чаще дерево ориентировано, причем дуги направлены от верхних вершин к нижним. Верхняя вершина называется предком для связанных с ней нижних вершин, а нижние вершины - потомками соответствующей верхней вершины. На любом дереве существует единственная вершина, не имеющая предка, - корень - и может быть сколько угодно вершин, не имеющих потомков, - листьев . Все остальные вершины имеют ровно одного предка и сколько угодно потомков.
Если не принимать во внимание направленность связей, то в дереве из любой вершины можно по линиям дойти до любой другой вершины, причем по одному единственному пути.
В виде дерева удобно изображать системы, в которых нижние вершины в каком-то смысле «подчинены» верхним. Верхняя вершина может изображать начальника, нижние - подчиненных; верхняя - систему, нижние - ее компоненты; верхняя - множество объектов, нижние - входящие в него подмножества; верхняя вершина - предка, нижние - потомков и т. д.
Формализация в случае построения дерева (иерархического графа) сводится к выявлению основного (главного, центрального) элемента рассматриваемого объекта (вершина нулевого уровня, которую часто называют корнем), элементов, которые находятся в непосредственном подчинении от основного (вершины 1-го уровня). Затем определяются вершины, находящиеся в непосредственном «подчинении» от вершин 1-го уровня (вершины 2-го уровня) и так далее.
Изображать построенное дерево отношений можно в любом направлении - это уже дело эстетического вкуса разработчика модели.
В научной и учебной деятельности с помощью деревьев часто представляют классификацию изучаемых объектов.
– структура данных, представляющая собой древовидную структуру в виде набора связанных узлов.
Это конечное множество элементов, которое либо пусто, либо содержит элемент (корень ), связанный с двумя различными бинарными деревьями, называемыми левым и правым поддеревьями . Каждый элемент бинарного дерева называется узлом . Связи между узлами дерева называются его ветвями .
Способ представления бинарного дерева:
- A — корень дерева
- В — корень левого поддерева
- С — корень правого поддерева
Корень дерева расположен на уровне с минимальным значением.
Узел D , который находится непосредственно под узлом B , называется потомком B . Если D находится на уровне i , то B – на уровне i-1 . Узел B называется предком D .
Максимальный уровень какого-либо элемента дерева называется его глубиной или высотой .
Если элемент не имеет потомков, он называется листом или терминальным узлом дерева.
Остальные элементы – внутренние узлы (узлы ветвления).
Число потомков внутреннего узла называется его степенью . Максимальная степень всех узлов есть степень дерева.
Число ветвей, которое нужно пройти от корня к узлу x , называется длиной пути к x . Корень имеет длину пути равную 0 ; узел на уровне i имеет длину пути равную i .
Бинарное дерево применяется в тех случаях, когда в каждой точке вычислительного процесса должно быть принято одно из двух возможных решений.
Имеется много задач, которые можно выполнять на дереве.
Распространенная задача - выполнение заданной операции p с каждым элементом дерева. Здесь p рассматривается как параметр более общей задачи посещения всех узлов или задачи обхода дерева.
Если рассматривать задачу как единый последовательный процесс, то отдельные узлы посещаются в определенном порядке и могут считаться расположенными линейно.
Способы обхода дерева
Пусть имеем дерево, где A - корень, B и C - левое и правое поддеревья.
Существует три способа обхода дерева:
- Обход дерева сверху вниз (в прямом порядке): A, B, C — префиксная форма.
- Обход дерева в симметричном порядке (слева направо): B, A, C — инфиксная форма.
- Обход дерева в обратном порядке (снизу вверх): B, C, A — постфиксная форма.
Реализация дерева
Узел дерева можно описать как структуру:
struct tnode {
Int field; // поле данных
Struct
tnode *right; // правый потомок
};
При этом обход дерева в префиксной форме будет иметь вид
if (tree!=NULL) {
cout << tree->field; //Отображаем корень дерева
Обход дерева в инфиксной форме будет иметь вид
void treeprint(tnode *tree) {
if (tree!=NULL) { //Пока не встретится пустой узел
cout << tree->field; //Отображаем корень дерева
Обход дерева в постфиксной форме будет иметь вид
void treeprint(tnode *tree) {
if (tree!=NULL) { //Пока не встретится пустой узел
cout << tree->field; //Отображаем корень дерева
Бинарное (двоичное) дерево поиска – это бинарное дерево, для которого выполняются следующие дополнительные условия (свойства дерева поиска):
- оба поддерева – левое и правое, являются двоичными деревьями поиска;
- у всех узлов левого поддерева произвольного узла X значения ключей данных меньше, чем значение ключа данных самого узла X ;
- у всех узлов правого поддерева произвольного узла X значения ключей данных не меньше, чем значение ключа данных узла X .
Данные в каждом узле должны обладать ключами, на которых определена операция сравнения меньше.
Как правило, информация, представляющая каждый узел, является записью, а не единственным полем данных.
Для составления бинарного дерева поиска рассмотрим функцию добавления узла в дерево.
Добавление узлов в дерево
struct tnode * addnode(int x, tnode *tree) {
If (tree == NULL) { // Если дерева нет, то формируем корень
tree =new tnode; // память под узел
tree->field = x; // поле данных
tree->left = NULL;
tree->right = NULL; // ветви инициализируем пустотой
}else if (x < tree->field) // условие добавление левого потомка
tree->left = addnode(x,tree->left);
Else // условие добавление правого потомка
tree->right = addnode(x,tree->right);
Return
(tree);
}
Удаление поддерева
void freemem(tnode *tree) {
If (tree!=NULL) {
freemem(tree->left);
freemem(tree->right);
Delete tree;
Пример Написать программу, подсчитывающую частоту встречаемости слов входного потока.
Поскольку список слов заранее не известен, мы не можем предварительно упорядочить его. Неразумно пользоваться линейным поиском каждого полученного слова, чтобы определять, встречалось оно ранее или нет, т.к. в этом случае программа работает слишком медленно.
Один из способов - постоянно поддерживать упорядоченность уже полученных слов, помещая каждое новое слово в такое место, чтобы не нарушалась имеющаяся упорядоченность. Воспользуемся бинарным деревом.
В дереве каждый узел содержит:
- указатель на текст слова;
- счетчик числа встречаемости;
- указатель на левого потомка;
- указатель на правого потомка.
Рассмотрим выполнение программы на примере фразы
При этом дерево будет иметь следующий вид
Пример реализации
#include
#include
#include
#include
#define
MAXWORD 100
struct
tnode { // узел дерева
Char *word; // указатель на строку (слово)
Int count; // число вхождений
Struct tnode *left; // левый потомок
Struct
tnode *right; // правый потомок
};
// Функция добавления узла к дереву
struct
tnode *addtree(struct
tnode *p, char
*w) {
Особым видом графа является дерево . Данная форма модели применяется тогда, когда элементы моделируемого объекта находятся в состоянии какого-либо подчинения и соподчинения, когда есть отношение иерархичности.
Пример.
Модель управления предприятием (школой, театральным коллективом и т. д.) очень удобно представлять в виде дерева.
Пример.
Вам хорошо известно понятие «родословное дерево» и вы можете изобразить в такой форме ваши родственные отношения.
Пример.
Каталог файлов на диске, также как и библиотечный каталог - примеры информационных моделей в форме дерева.
Дерево - это граф, предназначенный для отображения таких связей между объектами, как вложенность, подчиненность, наследование и т. п.
Строится он следующим образом.
Сначала рисуем «главную» вершину, которая не зависит ни от одной другой вершины. Эта вершина называется корнем дерева и является единственной вершиной 1-го уровня. Далее добавляем вершины 2-го уровня . Их может быть сколько угодно, и все они обязательно связаны с корнем - вершиной 1-го уровня, но не связаны между собой. На следующем шаге добавим вершины 3-го уровня. Каждая из них будет связана ровно с одной вершиной 2-го уровня (больше ни с одной другой вершиной). К любой вершине 2-го уровня может быть подсоединено сколько угодно вершин 3-го уровня (в том числе, ни одной). Следующий шаг - добавка вершин 4-го уровня , каждая из которых будет связана ровно с одной вершиной 3-го уровня (и не связана больше ни с чем). И так далее. На каждом шаге добавляем вершины очередного уровня, каждая из которых будет связана ровно с одной вершиной предыдущего уровня и не будет иметь никаких иных связей.
Полученный граф напоминает ветвящийся куст, который «растет сверху вниз»: верхние уровни имеют меньшие номера, нижние - большие.
Вообще говоря, дерево может быть и неориентированным графом, но чаще дерево ориентировано, причем дуги направлены от верхних вершин к нижним. Верхняя вершина называется предком для связанных с ней нижних вершин, а нижние вершины - потомками соответствующей верхней вершины. На любом дереве существует единственная вершина, не имеющая предка, - корень - и может быть сколько угодно вершин, не имеющих потомков, - листьев . Все остальные вершины имеют ровно одного предка и сколько угодно потомков.
Если не принимать во внимание направленность связей, то в дереве из любой вершины можно по линиям дойти до любой другой вершины, причем по одному единственному пути.
В виде дерева удобно изображать системы, в которых нижние вершины в каком-то смысле «подчинены» верхним. Верхняя вершина может изображать начальника, нижние - подчиненных; верхняя - систему, нижние - ее компоненты; верхняя - множество объектов, нижние - входящие в него подмножества; верхняя вершина - предка, нижние - потомков и т. д.
Формализация в случае построения дерева (иерархического графа) сводится к выявлению основного (главного, центрального) элемента рассматриваемого объекта (вершина нулевого уровня, которую часто называют корнем), элементов, которые находятся в непосредственном подчинении от основного (вершины 1-го уровня). Затем определяются вершины, находящиеся в непосредственном «подчинении» от вершин 1-го уровня (вершины 2-го уровня) и так далее.
Изображать построенное дерево отношений можно в любом направлении - это уже дело эстетического вкуса разработчика модели.
В научной и учебной деятельности с помощью деревьев часто представляют классификацию изучаемых объектов.
Классифицирование - распределение объектов по классам в зависимости от их общих признаков, фиксирующее закономерные связи между классами объектов в единой системе данной отрасли знания. |
Классификация(от лат. classis - разряд + facere - делать) - система соподчиненных понятий (классов объектов, явлений) в какой-либо отрасли знания, составленная на основе учёта общих признаков объектов и закономерных связей между ними. |
Классификация позволяет ориентироваться в многообразии объектов и является источником знания о них. Очень важен выбор основания классификации - то есть признака, на основании которого объекты разбиваются на классы. Выбор разных оснований приводит к разным классификациям. |
Пример.
На рис.8 вы видите классификацию, предложенную Григорием Великим, которая призвана была показать, что человек имеет что-то общее со всеми видами существующих в мире вещей, и поэтому его справедливо называют «вселенной в миниатюре». Обратите внимание, что объекты здесь разбиваются всегда на два класса. Такая классификация носит название дихотомической .
Рис.8. Классификация «того, что есть» Григория Великого
Пример.
Представленная на рис.9 классификация принтеров построена с использованием различных оснований деления
Рис.9 Классификация принтеров
Пример.
Важным видом исторических классификаций является построение родословных или генеалогических деревьев. Онибывают самого разного вида: с указанием только прямых потомков (рис.10); с включением жён (мужей) и их родственников и др.
Рис.10 Родословное дерево великих и удельных князей Владимирских и Московских,
XIII-XIV века (фрагмент)
В скобках приведены известные даты жизни; крест указывает на год смерти; двойным контуром обведены имена князей, занимавших московский престол.
Рассмотренные выше реляционная (табличная), сетевая (графовая) и иерархическая (древовидная) модели являются основными для представления данных в базах данных, а программные комплексы, которые позволяют создавать, обновлять, сохранять базы данных и обслуживать запросы пользователей к ним, называются соответственно реляционной, сетевой, иерархической системами управления базами данных (СУБД). При описании сложных объектов, как правило, используется комбинация различных моделей данных.
ЗНАТЬ
Формализация текстовой информации:
Облегчает и ускоряет процесс её обработки;
Позволяет получить количественные оценки;
Обеспечивает однозначность понимания текста;
Способствует лучшему восприятию сведений, содержащихся в тексте;
Помогает сравнить по формальным критериям ситуацию, описанную в тексте, с реальной и принять правильное решение.
Формализовать можно как оформление текста, так и его содержание.
Формализация оформления сводится к использованию бланков, формуляров, шаблонов заранее определённой и часто законодательно утверждённой стандартной формы.
Шаблон документа - стандартная форма документа, встречающегося в сфере делопроизводства.
Реквизитами документа называются обязательные данные, которые необходимо отразить в документе.
Целью формализации содержания текста является его однозначное понимание. Это очень важно в юридической практике, в научной и управленческой деятельности, например, при формулировании определений, составлении законов, договоров, приказов, распоряжений и т.п.
Таблицы - удобная для анализа и обработки и наглядная форма представления информации.
Таблицы, в которых отражается одно свойство, характеризующее два или более объектов, называются таблицами типа «объект-объект».
Таблицы, в которых отражаются несколько свойств объекта, а все объекты принадлежат одному множеству, называются таблицами вида «объект-свойство».
Комбинирование в одной таблице нескольких таблиц вида «объект-объект» и «объект-свойство» позволяет построить таблицы более сложного вида, например, «объекты-свойства-объекты» .
Таблица характеризуется :
Названием (а если таблиц несколько, то ещё и номером),
Количеством столбцов и их названиями (заголовками столбцов),
Количеством строк и их названиями (заголовками строк),
Содержимым ячеек, находящихся на пересечении строк и столбцов.
В случае многоуровневых заголовков строк и столбцов уровни заголовков столбцов называются ярусами, уровни заголовков строк - ступенями.
Основными элементами таблицы являются:
записи - строки таблицы, которые могут содержать данные разного типа, но относящиеся чаще всего к одному объекту;
поля - столбцы таблицы, содержащие, как правило, данные одного типа;
реквизиты - конкретные значения, находящиеся в ячейках таблицы на пересечении строк и столбцов.
Этапы приведения к табличному виду:
1. анализ информации и выделение объектов, о которых идет речь;
2. выделение свойств объектов и/или отношений между ними;
3. определение того, можно ли объекты объединить в некоторые подмножества, и в зависимости от этого определение количества уровней и ступеней в заголовках;
4. определение общего количества столбцов и порядка их расположения;
5. определение наименований столбцов и типа данных, которые там будут располагаться;
6. выбор порядка размещения строк и определение названия каждой строки таблицы;
7. занесение в ячейки таблицы реквизитов-данных (построчно или по столбцам).
Граф - совокупность точек, соединённых между собой линиями. Эти точки называют вершинами графа.
Линии, соединяющие вершины, называются дугами , если задано направление от одной вершины к другой, или рёбрами , если направленность двусторонняя.
Граф называется взвешенным , если вершины или рёбра (дуги) характеризуются некоторой дополнительной информацией - весом вершины или ребра (дуги).
Граф однозначно задан, если заданы множество его вершин, множество рёбер (дуг) и указано, какие вершины какими рёбрами соединены.
Формализация при построении графа включает в себя следующие этапы:
Выявление всех элементов объекта;
Определение характеристик элементов (названий, номеров, весов и т. п.);
Установление наличия и вида связей (односторонняя или двухсторонняя) между элементами;
Определение характеристик связей - весов рёбер и дуг;
Выбор формы изображения вершин и рёбер, ввод условных обозначений в случае необходимости;
Представление выделенных элементов и связей в графическом виде.
Для компьютерного моделирования более удобным является символическое и/или табличное задание графа.
Символическое задание графа - перечисление всех его рёбер с указанием вершин, которые они соединяют, либо перечисление всех вершин с указанием исходящих из них рёбер.
Дерево - особый вид графа, применяемый при моделировании объекта, элементы которого находятся в отношении иерархии (подчинения и соподчинения).
Корнем дерева называется вершина, соответствующая основному (центральному, главному, родовому) элементу моделируемого объекта. Листьями дерева называют вершины графа, у которых нет «подчинённых» вершин.
Формализация при построении дерева сводится к выявлению основного элемента рассматриваемого объекта (вершина нулевого уровня - корень дерева), элементов, которые находятся в непосредственном подчинении у основного элемента (вершины 1-го уровня), элементов, находящихся в непосредственном подчинении у вершин 1-го уровня (вершины 2-го уровня) и т. д.
Классификация - система соподчинённых понятий (классов объектов, явлений) в какой-либо отрасли знания, составленная на основе учёта общих признаков объектов и закономерных связей между ними. Представляется чаще всего в виде иерархического графа (дерева) или таблицы.
Реляционная (табличная), сетевая (графовая) и иерархическая (древовидная) модели являются основными для представления данных в базах данных.
Программные комплексы, которые позволяют создавать, обновлять, сохранять базы данных и обслуживать запросы пользователей к ним, называются соответственно реляционной, сетевой, иерархической системой управления базами данных (СУБД).
Большинство существующих автоматизированных баз данных являются базами данных реляционного типа.
Контрольные вопросы и задания
1. Что называется графом? Ориентированным графом?
2. Что называется вершинами графа? Рёбрами?
3. Какие рёбра и какие вершины графа называются смежными?
4. Какой граф называется деревом?
5. Какие системы объектов целесообразно и возможно представлять с помощью табличных моделей?
Доброго времени суток.
Вот список того, что тут можно будет почерпнуть:
- Отображение табличной части документа в виде дерева и обратное преобразование в табличную часть.
- Работа с условным оформлением и его программное использование.
- Динамическое изменение состава реквизитов формы
- Удобный интерфейс по редактированию дерева
А теперь вот исходные данные решаемой задачи:
Речь пойдет о сметах на строительство чего-либо. Есть справочник видов работ (далее просто работ) и материалов. Есть норма расхода материала на единицу работы. Нужно разработать документ, в котором пользователь мог бы задавать для каждой работы список материалов в количестве, необходимом для выполнения определенного объема этой работы на каждом этаже здания (собственно иногда это и не этаж вовсе, а помещение, секция,... да что угодна на что можно разбить строящийся объект).
Т.е. у нас вырисовывается следующая структура табличной части документа:
этаж - пока не понятно что это такое
объем работ - число 15.3
количество материалов - число 15.3
Вроде бы просто, но на практике мы получаем много повторяющейся информации. Например у нас две работы, в каждой 10 материалов, и 9 этажей. Это будет 180 строк в документе, в которых колонка "работа" везде почти одинаковая, каждый материал повторяется по 9 раз.
Ниже на рисунке два представления одной и той же информации. 1 - Линейно, 2 - в виде дерева с динамическими колонками количества. Для наглядности разные данные выделил цветами: красный - работа, синий - материал, этаж - сиреневый, зеленый - объем работы, орнажевый - к.расхода, черный - количество материалов.
Второй вариант явно экономит место на экране. В первом у нас 150 ячеек с информацией, во втором - 52. Причем, чем больше этажей, материалов в работе, тем экономия сильнее.
Вот второй вариант мы с Вами в этом уроке и реализуем.
Итак, открываем конфигуратор. Думаю набросать структуру данных из двух справочников,документа и регистра сведений вы сможете сами. Поэтому начну рассказ с момента, когда у нас есть уже вот так:
- Справочник "Работы"
- Справочник "Материалы" (или номенклатура - не важно)
- Документ "..." (можете назвать его "Смета" или еще как)
- Регистр сведений, периодический, в котором измерения: работа, материал; ресурс: к.расхода (можете для него сбацать регистратор, можете оставить непосредственное редактирование)
Первое, это надо определиться со способом преобразования табличной части в дерево. Первый (самый простой) - это запросом сделать итоги по полю работа. Минус тут в том, что мы не можем в таб.часть добавить две одинаковых работы с разным составом материалов, т.к. работа будет ключевым полем. Работа у нас объединится в один узел дерева, а материалы в нем сложатся. Второй способ - добавить ключевое поле, которое будет определять принадлежность строк к одному узлу.
Мне больше нарвится второй способ, в нем у документа появляются лишние реквизиты, но код становится прозрачным, понятным и надежным. В качестве ключа будем использовать номер. Добавим поля номер работы и номер материала в работе.
Тут у нас не хватает третьей аналитики - этаж. В нашем случае это будет целое положительно число. Для удобства, добавим в шапку поле "Количество этажей". Это поле нам сильно упростит жизнь. Случай, когда в таб.части есть этаж №9, а максимум этажей - 8, считаем не допустимым, эти строки будут пропавшими безвести.
Следующим шагом избавимся от поля "ОбъемРабот" и оставим только количество. В строках, где НомерМатериалаВРаботе = 0 будем считать количество - объемом работ.
Со структурой - все, идем в форму. Создадим форму по умолчанию, в которой разместим все, что есть.
Первое - номер и дату сделаем в одну строку, это действие надо делать на автомате всегда, это уже как лесенка в коде.
Далее рисуем реквизит формы "ДеревоРабот" с типом значения "Дерево значений". Добавим в него колонки: Номер, РаботаМатериал, кРасхода, ЭтоРабота. Среди элементов создадим две страницы: служебная, туда отправим реальную таб.часть, и дерево, туда отправим дерево. У дерева отобразим все колонки, кроме флажка "ЭтоРабота".
Теперь лезем в код. Нам понадобится процедура, которая рисует колонки с количеством по количеству этажей. Назовем её "ОбновитьСоставКолонок()". В ней мы будем динамически создавать/удалять реквизиты формы и элементы формы. Эта процедура будет вызываться при создании формы и при изменении количества этажей. Т.е. чать колонок в момент вызова процедуры у нас уже могут быть и нам надо их оставить, чтобы не потерять данные.
Вот её синтаксис:
&НаСервере
Процедура ОбновитьСоставКолонок()
//1. Правим ревизит формы, добавляем в дерево колонки
дерево = РеквизитФормыВЗначение("ДеревоРабот");
мКУдалению = Новый Массив;
МаксНомерКолонки = 0;
Для каждого Колонка Из Дерево.Колонки Цикл
Если Лев(Колонка.Имя, 3) = "Кол" тогда
НомерКоличества = число(сред(Колонка.Имя,4));
Если НомерКоличества>Объект.КоличествоЭтажей Тогда
мКУдалению.Добавить(Колонка);
КонецЕсли;
Если НомерКоличества>МаксНомерКолонки Тогда
МаксНомерКолонки = НомерКоличества;
КонецЕсли;
КонецЕсли;
КонецЦикла;
//2.
РеквизитыКУдалению = Новый Массив;
Для Каждого элементМКУдалению Из мКУдалению Цикл
РеквизитыКУдалению.Добавить("ДеревоРабот." + элементМКУдалению.Имя);
//элемент формы надо грохнуть раньше, чем реквизит
Элементы.Удалить(Элементы["ДеревоРабот" + элементМКУдалению.Имя])
КонецЦикла;
//3.
РеквизитыКДобавлению = Новый Массив;
НовыйРеквизитФормы = Новый РеквизитФормы("Кол"+НовыйНомер, Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,3)), "ДеревоРабот", "к "+НовыйНомер);
РеквизитыКДобавлению.Добавить(НовыйРеквизитФормы);
КонецЦикла;
//4.
ИзменитьРеквизиты(РеквизитыКДобавлению,РеквизитыКУдалению);
//5. Рисуем новые элементы формы, добавлять их надо после создания ревизитов
Для ж=1 По объект.КоличествоЭтажей - МаксНомерКолонки Цикл
НовыйНомер = МаксНомерКолонки + ж;
НоваяКолонка = Элементы.Добавить("ДеревоРаботКол"+НовыйНомер, Тип("ПолеФормы"), Элементы.ДеревоРабот);
НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
НоваяКолонка.ПутьКДанным = "ДеревоРабот.Кол"+НовыйНомер;
НоваяКолонка.Ширина = 7;
НоваяКолонка.УстановитьДействие("ПриИзменении", "КоличествоПриИзменении");
НоваяКолонка.Заголовок = "к " + ж;
КонецЦикла;
КонецПроцедуры
Прокомментируем этапы её работы:
1. Перебираем все колонки дерева, чтобы узнать сколько у нас уже есть. Тут мы по имени колонки определяем её номер и, если он больше нужного количества, добавляем в список к удалению. Так же находим максимальный номер существующей колонки. (это мы работаем с реквизитами формы!!!)
2. Преобразуем список колонок к удалению к списку строк с именами данных. За одно, сразу грохаем элементы формы, т.к. нельзя удалить реквизит, который отображен на форме.
3. Создаем список колонок, которые надо создать.
4. Вызываем встроенную процедуру ИзменитьРеквизиты, после этого у нас уже нет лишних колонок и появились недостающие.
Собственно, в этой процедуре мы увидели, как правильно динамически рисовать реквизиты формы и элементы формы. Из важных нюансов:
-нельзя удалять реквизиты, созданные не программно
-нельзя удалять реквизиты, используемые в элементах формы
Сохранившись и запустив предприятие, мы увидим, что при открытии существующего документа у нас сразу рисуется нужное количество колонок, при изменении кол-ва этажей все сразу динамически перерисовывается.
Теперь напишем процедуру преобразования таблицы в дерево. Для теста заполним в документе табличную часть как на рисунке:
Для этого мы и оставили реальную таб.часть на форме, чтобы можно было отлаживаться и проверять результат.
&НаСервере
Процедура ТабЧастьВДерево()
Дерево = РеквизитФормыВЗначение("ДеревоРабот");
Дерево.Строки.Очистить();
строкаРаботы = "";
НомерРаботы = "";
НомерМатериала = "";
Объект.ТабличнаяЧасть1.Сортировать("НомерРаботы,НомерМатериалаВРаботе");
Для Каждого Выб Из Объект.ТабличнаяЧасть1 Цикл
//Контроль количества этажей
Этаж = Выб.Этаж;
Если Этаж > Объект.КоличествоЭтажей Тогда
Продолжить;
КонецЕсли;
Если Этаж = 0 Тогда
Продолжить;
КонецЕсли;
Если НомерРаботы<>Выб.НомерРаботы Тогда
строкаРаботы = Дерево.Строки.Добавить();
строкаРаботы.Номер = Выб.НомерРаботы;
строкаРаботы.РаботаМатериал = Выб.Работа;
строкаРаботы.ЭтоРабота = Истина;
//началась следующая работа, отсчет материалов начнем с начала
НомерМатериала = "";
НомерРаботы = Выб.НомерРаботы;
КонецЕсли;
Если Выб.НомерМатериалаВРаботе = 0 тогда//это строка работы
строкаРаботы["Кол"+Этаж] = Выб.Количество;
Иначе//это строка с материалом
Если НомерМатериала<>Выб.НомерМатериалаВРаботе тогда
строкаМатериала = строкаРаботы.Строки.Добавить();
строкаМатериала.Номер = Выб.НомерМатериалаВРаботе;
строкаМатериала.РаботаМатериал = Выб.Материал;
строкаМатериала.КРасхода = Выб.КРасхода;
строкаМатериала.ЭтоРабота = Ложь;
НомерМатериала=Выб.НомерМатериалаВРаботе;
КонецЕсли;
строкаМатериала["Кол"+Этаж] = Выб.Количество;
КонецЕсли;
КонецЦикла;
ЗначениеВРеквизитФормы(Дерево,"ДеревоРабот");
КонецПроцедуры
Комментировать тут особо нечего. С помощью полей "номерРаботы" и "НомерМатериалаВРаботе" определяю, что перед нами, строка с работой или материалом, соответственно добавляем строку в корень или в работу. Если сменился только этаж, то берем только количество. Лишние этажи обрубаются, пропущенные этажи - не испортят структуру дерева.
Вызываем эту процедуру при создании на сервере после "ОбновитьСоставКолонок()".
Теперь можно её протестировать запустив предприятие и открыв созданный ранее документ.
Теперь нам надо перед записью документа сделать наоборот, дерево сохранить в табличную часть. Пишем процедуру:
&НаКлиенте
Процедура ПоместитьДеревоВТабЧасть()
Объект.Материалы.Очистить();
Для Каждого стрРаботы Из ДеревоРабот.ПолучитьЭлементы() Цикл
стр.Этаж = ж;
стр.Количество = стрРаботы["Кол"+ж];
КонецЦикла;
Для Каждого стрМатериала Из стрРаботы.ПолучитьЭлементы() Цикл
Для ж=1 По Объект.КоличествоЭтажей Цикл
стр = Объект.Материалы.Добавить();
стр.НомерРаботы = стрРаботы.Номер;
стр.НомерМатериалаВРаботе = стрМатериала.Номер;
стр.Работа = стрРаботы.РаботаМатериал;
стр.Материал = стрМатериала.РаботаМатериал;
стр.КРасхода = стрМатериала.КРасхода;
стр.Этаж = ж;
стр.Количество = стрМатериала["Кол"+ж];
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецПроцедуры