** laifik |
Отправлено: 27.10.2003, 15:26 |
|
Не зарегистрирован
|
Уже второй день не могу сформировать дерево. Вроде все понятно, а как нужно, не получается. Кто сможет, помогите, пожалуйста!
Задача такая. схематично орисую структуру дерева:
Год
2002
Январь
Февраль
2003
Март
Июнь
Август
Сентярь
Понятно, что ступенчатая структура базы данных. Таблица года и таблица месяца связаны по ключу.
Сначала формирую корневой узел:
//Создание дерева"
int PrCount = TestModule->ADOGod->RecordCount;
TreeView1->Items->Clear(); //Очистка списка
TreeView1->Items->Add(NULL, "Год");
//Доавление дочерних узлов"Год"
TestModule->ADOGod->First();
do
{
for(int ii=0; ii
AnsiString Pr=TestModule->ADOGod->FieldByName("God")->AsString;
TreeView1->Items->AddChild(TreeView1->Items->Item[0], Pr);
TestModule->ADOGod->Next();
}
}
while (TestModule->ADOGod->Eof!=TRUE);
Все работает правильно, создаются узлы 2002 и 2003.
Далее хотела сделать цикл в цикле.
int MesCount = TestModule->ADOMesaz->RecordCount;
Но MesCount меняется в зависимости от года. И вот в этом месте не могу додумать. Куда и как вставить этот цикл, чтоы работало правильно.
//Добавление дочерних узлов "Месяц"
TestModule->ADOMesaz->First();
do
{
for(int kk=0; kk
AnsiString Ms=TestModule->ADOMesaz->FieldByName("Mesaz")->AsString;
TreeView1->Items->AddChild(TreeView1->Items->Item[????], Ms);
TestModule->ADOMesaz->Next();
}
}
while (TestModule->ADOMesaz->Eof!=TRUE);
И что должно стоять вместо вопросов. Если цикл в цикле, то туда ставлю ii. Но это, видимо, неправильно. Отзовитесь, кто создавал такое дерево. Заранее брагодарю!
|
|
Nick |
Отправлено: 28.10.2003, 07:38 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
Я сделал так.
typedef struct { int kode; char RemarkText[255]; } tNodeData;
первый вызов процедуры
Parent_ID = 0;
item = NULL;
void __fastcall TFormMain::mLoadRepTree( int Parent_ID, TTreeNode *item )
{
TTreeNode *newItem = NULL;
char *RemarkText;
// IBQ_TempLoad — запрос выдает строки в порядке
// id parent_id Name
// 1 0 Год
// 2 1 2002
// 3 2 январь
// 4 2 февраль
// 5 2 ...
// 10 0 2003
// 11 10 январь
while ((IBQ_TempLoad->FieldByName("opParent_ID")->AsInteger == Parent_ID) &&
!IBQ_TempLoad->Eof )
{
tNodeData *NodeData = (tNodeData *)malloc(sizeof(tNodeData));
strcpy(NodeData->RemarkText, IBQ_TempLoad->FieldByName("opRemark")->AsString.c_str());
NodeData->kode = IBQ_TempLoad->FieldByName("opTree_ID")->AsInteger;
if ( item == NULL )
{
newItem = TV_Rep->Items->AddObject( newItem, IBQ_TempLoad->FieldByName("OPNAME")->AsString, NodeData );
}
else newItem = TV_Rep->Items->AddChildObject( item, IBQ_TempLoad->FieldByName("OPNAME")->AsString, NodeData );
int iParent_ID = IBQ_TempLoad->FieldByName("OPTREE_ID")->AsInteger;
IBQ_TempLoad->Next();
mLoadRepTree( iParent_ID, newItem ); // вызов этой же процедуры
// для листочков считанного узла
};
};
// набор данных создается процедурой
// тоже с рекурсивным вызовом FireBird
// в ADO придется писать записи по порядку
|
|
** laifik |
Отправлено: 28.10.2003, 11:23 |
|
Не зарегистрирован
|
К сожалению, мне трудно сейчас переключиться на совсем другую идею, тем более, я не представляю, что за задача была у Вас. Трудно понять из этого куска, что откуда берется. Я все мусолю свою идею. И вот что получается. Цикл в цикле, после формирования узла "2003" в корневом узле "Год" по ключу GodID в таблице месяцев ищутся соответствующие записи. Их количество подсчитывается и формируются новые дочерние узлы уже из перечня месяцев (TreeView1->Items->AddChild(TreeView1->Items->Item[ii+1], Ms). До этого момента все правильно.
Получается такая структура:
- Год
- 2003
+ Январь
Ноябрь
2004
Далее происходит непонятное. Когда делаю пошаговую отладку, все указатели идут правильно. А на деле при такой записи ii+1 месяцы, соответствующие 2004 прописались внутри Января. А нужно, чтобы "+" был около 2004 и внутри него были месяцы. Помогите, пожалуйста, добить этот вариант. Или на худой конец, хотелось бы почитать подробное объяснению по Вашему предложенному.
Код
//Добавление корневого узла"Год"
int PrCount = TestModule->ADOGod->RecordCount;
TestModule->ADOGod->First();
do
{
for(int ii=0; ii
AnsiString Pr=TestModule->ADOGod->FieldByName("God")->AsString;
int PrId=TestModule->ADOGod->FieldByName("GodID")->AsInteger;
TreeView1->Items->AddChild(TreeView1->Items->Item[0], Pr);
//Добавление дочернего узла "Месяц"
ffield = "GodID";
fvalue = PrId;
opts << loCaseInsensitive;
TestModule->ADOMesazShet->Locate(ffield, fvalue, opts);
int MesCount = TestModule->ADOMesaz->RecordCount;
Edit9->Text = MesCount;
do
{
for(int kk=0; kk
AnsiString Ms=TestModule->ADOMesaz->FieldByName("Mesaz")->AsString;
TreeView1->Items->AddChild(TreeView1->Items->Item[ii+1], Ms);
TestModule->ADOMesaz->Next();
}
}
while (TestModule->ADOMesaz->Eof!=TRUE);
TestModule->ADOGod->Next();
}
}
while (TestModule->ADOGod->Eof!=TRUE);
|
|
** laifik |
Отправлено: 28.10.2003, 15:44 |
|
Не зарегистрирован
|
Все-таки мне помогли добить мой вариант. Может кому пригодится.
Код
//Создание "дерева"
int PrCount = TestModule->ADOGod->RecordCount;
TreeView1->Items->BeginUpdate();
TreeView1->Items->Clear(); //Очистка списка
TTreeNode *root = TreeView1->Items->AddChild( NULL, "Год" ); //root — Год
//Добавление узла"Год"
TestModule->ADOGod->First();
do
{
for(int ii=0; ii
AnsiString Pr=TestModule->ADOGod->FieldByName("God")->AsString;
int PrId=TestModule->ADOGod->FieldByName("GodID")->AsInteger;
TTreeNode *cyear = TreeView1->Items->AddChild( root, Pr);
//Добавление дочернего узла "Месяц"
ffield = "GodID";
fvalue = PrId;
opts << loCaseInsensitive;
TestModule->ADOMesazShet->Locate(ffield, fvalue, opts);
int MesCount = TestModule->ADOMesaz->RecordCount;
Edit9->Text = MesCount;
do
{
for(int kk=0; kk
AnsiString Ms=TestModule->ADOMesaz->FieldByName("Mesaz")->AsString;
TreeView1->Items->AddChild( cyear, Ms); //root — ãîä
TestModule->ADOMesaz->Next();
}
}
while (TestModule->ADOMesaz->Eof!=TRUE);
TestModule->ADOGod->Next();
}
}
while (TestModule->ADOGod->Eof!=TRUE);
TreeView1->Items->EndUpdate(); |
|
laifik |
Отправлено: 29.10.2003, 09:13 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 70
|
При отправке сообщения в for произошел сбой и выпали куски. Я их восстанавливаю:
for(int ii=0; ii
AnsiString Pr=TestModule->ADOGod->FieldByName("God")->AsString;
и т.д.
и второй:
for(int kk=0; kk
AnsiString Ms=TestModule->ADOMesaz->FieldByName("Mesaz")->AsString;
и т.д.
Обратите на это внимание.
|
|
laifik |
Отправлено: 29.10.2003, 09:14 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 70
|
Какой-то заколдованный код. Попробую еще раз:
for(int kk=0; kk
AnsiString Ms=TestModule->ADOMesaz->FieldByName("Mesaz")->AsString; |
|
laifik |
Отправлено: 29.10.2003, 09:18 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 70
|
Короче, дурдом какой-то. Впервые с таким сталкиваюсь. При просмотре сообщения все выглыдит нормально.
Смотрите ссылку на другой форум, там все правильно, хотя были такие же казусы.
http://www.progz.ru/viewtopic.php?t=4240
|
|
Георгий |
Отправлено: 29.10.2003, 10:29 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
А ты тегом CODE попробуй воспользоваться |
|