Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Древовидный вывод данных из базы ?


Автор: NAS 5.5.2007, 15:31
smile  Привет всем!!! есть программа с базой данных нужно выводить данные в виде дерева 
(типа Explorer in Windows)

Помогите пожалуста smile 

Автор: Klin 5.5.2007, 22:09
Исчерпывающая информация smile Можно использовать компонент TreeView (из вкладки Win32).

Автор: Anikmar 6.5.2007, 12:20
Я это достаточно давно сделал, может быть по-топорному, но не стал ничего менять - работает устойчиво и ладно.
Делал так:
Код

//---------------------------------------------------------------------------
// Метод: BuildTree
// Построение дерева каталогов
// Список записей, поддерживающих метод GetMasterUni и GetNodeName находитя
// в списке pList      
// pTr - Дерево
bool TMAN_ADODBTree::BuildTree(TTreeView *pTr,TList * pList)
{
    int i,Master,cM;
    TMAN_ADOVrec *CurRec;
    TTreeNode *CurNode,*RootNode;
    TStack *pStack;
    AnsiString aN;

    // Стек нужен для временного хранения перебираемых узлов
    pStack = new TStack;
    CurRec = NULL;

    // Шаг 1 - очищаю дерево
    // и помечаю во всех записях списка узлы как неразмеченные
    pTr->Items->Clear();
    for (i=0;i<pList->Count;i++)
    {
        CurRec = (TMAN_ADOVrec*)pList->Items[i];
        CurRec->Node = NULL;
    }

    // Шаг 2 - Создаю корневой узел дерева
    RootNode = pTree->Items->AddChildObject(NULL,RootName,NULL);
    Master = 0; // Для начала - нужен мастер - корневой уровень
    CurNode = RootNode;
    if (MainImageIndex != -1) RootNode->StateIndex = MainImageIndex;

    // Шаг 3 - бегу по списку и добавляю в дерево узлы
    // Бегу пока в стеке есть записи
    //    while(pStack->Count()>0)
    do
    {
        for (i=0;i<pList->Count;i++)
        {
            CurRec = (TMAN_ADOVrec*)pList->Items[i];

            // Если запись уже есть в дереве - пропускаем
            if (CurRec->Node != NULL) continue;

            // Если мастер нас не устраивает - пропускаем
            cM = CurRec->GetMasterUni();
            if (cM != Master) continue;

            // Нашли запись для добавления
            // Запоминаем ее в стеке и помещаем в дерево
            aN = CurRec->GetNodeName();
            CurRec->Node =
                pTree->Items->AddChildObject(
                    CurNode,
                    aN,
                    CurRec);
            if (MainImageIndex != -1)
            {
                CurRec->Node->StateIndex = MainImageIndex;
                CurRec->Node->SelectedIndex = MainImageIndex;
                CurRec->Node->ImageIndex = MainImageIndex;
            }
            CurRec->FType = 1;      // Признак каталога
            // Запоминаем этот узел
            pStack->Push(CurRec);
        } // for (i=0;i<pList->Count;i++)
        // Все записи помещены в текущий уровень. Извлекаю из стека
        // последнюю записанную запись

        // Если стек пуст (ни одной записи не осталось) - выхожу
        if (pStack->Count() == 0) break;

        CurRec = (TMAN_ADOVrec*)pStack->Pop();
        CurNode = CurRec->Node;
        Master = CurRec->Uni;

    } while(true);

    pTree->Selected = RootNode;
    return true;
}



Пояснения к коду:
В pList у меня полный список записей из БД.  Записи БД загнаны в мой собственный класс, поэтому из кода нужно взять только алгоритм заполнения.

В списке pList объекты моего собственного класса, от них требуются следующие вещи:
Поле Node - предназначено для хранения узла дерева (изначально обнуляется)
Поле Uni содержит ключ текущей записи.
Метод GetNodeName Возвращает строку, которую отобразить в качестве названия узла
Метод GetMasterUni Возвращает ключ записи, к которой привязана текущая
Если подменить эти участки на собственные - то можно пользоваться, в общем то. Правда там еще пиктограммки ставятся, но это просто можно убрать.

Моя схема при зацикливании дерева просто обрезает зацикленные ветви. Я проверяю на зацикленность не при каждом построении дерева, а из служебной части - чтобы при зацикленном дереве сохранять более-менее работоспособность. Если после построения дерева останутся записи, в которых узел дерева нулевой - значит было зацикливание.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)