Inga |
Отправлено: 27.12.2005, 14:46 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
Есть код заполняющий ClientDataSet:
CODE |
TFieldDefs *pDefs = Form1->ClientDataSet4->FieldDefs;
TFieldDef *pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 25;
pDef->Name = "ID";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "Collector";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "REC";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "Complex";
TIndexDef *pIDef = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef->Fields = "Collector";
pIDef->Name = "MyIndex";
TIndexDef *pIDef2 = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef2->Fields = "REC";
pIDef2->Name = "MyIndex2";
TIndexDef *pIDef3 = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef3->Fields = "Complex";
pIDef3->Name = "MyIndex4";
Form1->ClientDataSet4->CreateDataSet();
//далее заполнение данными
****************
//затем отображение в гриде через DataSource:
Form1->DataSource5->DataSet = Form1->ClientDataSet4;
|
Как теперь очисть ClientDataSet4 от индексов и полей, т.е. привести его в состояние, как будто его только положили на форму? Это нужно для формирования новой структуры ClientDataSet4. Динамически создавать ClientDataSet4 мне не подходит. Формируется в одной форме, используется в другой.
Пробовала чистить так:
CODE |
if(Form1->ClientDataSet4->FieldDefs->Count)
{
Form1->ClientDataSet4->Edit();
Form1->ClientDataSet4->FieldDefs->Clear();
Form1->ClientDataSet4->Fields->Clear();
Form1->ClientDataSet4->FieldDefs->Update();
Form1->ClientDataSet4->IndexDefs->Clear();
Form1->ClientDataSet4->IndexDefs->Update();
Form1->ClientDataSet4->Close();
}
//или так
if(Form1->ClientDataSet4->FieldDefs->Count)
{
Form1->DataSource5->DataSet->Close();
}
//или так
if(Form1->ClientDataSet4->FieldDefs->Count)
{
Form1->DataSource5->DataSet->Close();
}
|
Если написать так:
CODE |
if(Form1->ClientDataSet4->FieldDefs->Count)
{
Form1->ClientDataSet4->Edit();
Form1->ClientDataSet4->IndexDefs->Clear();
Form1->ClientDataSet4->IndexDefs->Update();
Form1->ClientDataSet4->FieldDefs->Clear();
Form1->ClientDataSet4->FieldDefs->Update();
Form1->ClientDataSet4->Close();
}
|
Исключение пишет поле ID уже существует.
Если добавить Form1->ClientDataSet4->Fields->Clear(); пишет Field not found
Как привести ClientDataSet4 в состояние полной очистки?
|
|
olegenty |
Отправлено: 27.12.2005, 15:02 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
а вообще, надо ли это? если всё такое динамическое, то можно и экземпляр TClientDataSet удалять и создавать по мере необходимости...
|
|
Inga |
Отправлено: 27.12.2005, 15:14 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
У меня формируется ClientDataset в одной форме, затем все, что он содержит отображается в другой форме. Придется много кода переделывать если создавать ClientDataset динамически.
Если понять, как очисть структуру ClientDataset, то ничего переделывать не надо.
|
|
Inga |
Отправлено: 27.12.2005, 15:23 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
Может надо добавить удаление объектов pDef и pIDef?
Объекты pDef и pIDef не глобальные, создаются в обработчике. Я предполагала, что они наполняют ClientDataSet4 и потом сами перестают существовать.
Как их удалять? Делать проверку
if(pDef)
pDef = NULL ?
|
|
olegenty |
Отправлено: 27.12.2005, 15:23 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
тогда наверное не стоит оперировать и FieldDefs и Fields. точно помню, что пользовался только Fields, и всё работало корректно. и не надо переводить ClientDataset в режим редактирования перед удалением полей и индексов. вместо этого его надо закрыть.
|
|
Inga |
Отправлено: 27.12.2005, 15:47 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
>тогда наверное не стоит оперировать и FieldDefs
Подскажите, пожалуйста, как все тогда создовать в ClientDataset? |
|
olegenty |
Отправлено: 27.12.2005, 16:24 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
с перманентными полями
но и так должно работать:
CODE |
Form1->ClientDataSet4->Close();
Form1->ClientDataSet4->FieldDefs->Clear();
Form1->ClientDataSet4->FieldDefs->Update();
Form1->ClientDataSet4->IndexDefs->Clear();
Form1->ClientDataSet4->IndexDefs->Update();
|
после этого Form1->ClientDataSet4 чист.
|
|
Inga |
Отправлено: 27.12.2005, 16:57 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
>но и так должно работать:
Не работает.
Привожу полный код, может так легче будет понять:
CODE |
//в начале обработчика
if(Form1->ClientDataSet4->FieldDefs->Count)
{
Form1->ClientDataSet4->Close();
Form1->ClientDataSet4->FieldDefs->Clear();
Form1->ClientDataSet4->FieldDefs->Update();
Form1->ClientDataSet4->IndexDefs->Clear();
Form1->ClientDataSet4->IndexDefs->Update();
}
//далее в этом же обработчике:
If(первое условие формирования ClientDataSet4)
{
TFieldDefs *pDefs = Form1->ClientDataSet4->FieldDefs;
TFieldDef *pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 25;
pDef->Name = "ID";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "Collector";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "REC";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "Complex";
TIndexDef *pIDef = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef->Fields = "Collector";
pIDef->Name = "MyIndex";
TIndexDef *pIDef2 = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef2->Fields = "REC";
pIDef2->Name = "MyIndex2";
TIndexDef *pIDef3 = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef3->Fields = "Complex";
pIDef3->Name = "MyIndex4";
Form1->ClientDataSet4->CreateDataSet();
// в цикле заполнение строк данными далее:
Form1->ClientDataSet4->IndexName = "MyIndex";
Form1->ClientDataSet4->First();
Form1->DataSource5->DataSet = Form1->ClientDataSet4;
ST->ShowModal();
}
If(второе условие формирования ClientDataSet4)
{
TFieldDefs *pDefs = Form1->ClientDataSet4->FieldDefs;
TFieldDef *pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 25;
pDef->Name = "ID";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "Collector";
pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = 40;
pDef->Name = "REC";
TIndexDef *pIDef = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef->Fields = "Collector";
pIDef->Name = "MyIndex";
TIndexDef *pIDef2 = Form1->ClientDataSet4->IndexDefs->AddIndexDef();
pIDef2->Fields = "REC";
pIDef2->Name = "MyIndex2";
Form1->ClientDataSet4->CreateDataSet();
//далее код опущен
}
|
Приложение выполняется: cоздала условия, что бы выполнился первый if по формированию ClientDataSet4, затем создаю условия, чтобы попасть во второй if обработчика.
Получаю рисунок при вхождении во второй if на строке pDef->Name = "ID"; , причем точки останова показали, что код по очистке перед входом во второй if выполнился.
Присоединить изображение
|
|
Inga |
Отправлено: 27.12.2005, 17:06 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
Добавила в код очистки строку Form1->ClientDataSet4-Fields->Clear();
не помогло, та же ошибка. |
|
Inga |
Отправлено: 27.12.2005, 19:57 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
Наиболее правильный код получился такой:
CODE |
if(Form1->ClientDataSet4->FieldDefs->Count)
{
Form1->ClientDataSet4->Edit();
Form1->ClientDataSet4->IndexDefs->Clear();
Form1->ClientDataSet4->FieldDefs->Clear();
Form1->ClientDataSet4->FieldDefs->Count;
Form1->ClientDataSet4->Close();
}
|
Этот код делает равным нулю Form1->ClientDataSet4->FieldDefs->Count; Другие варианты не обнуляют FieldDefs.
Теперь проблема осталась такая:
Я в коде выше создаю три индекса, затем использую, например индекс под именем MyIndex4.
После очистки я создаю в ClientDataSet4 два индекса и получаю исключение (см.рисунок). Что ему не нравиться? Ведь я заново создаю индексы, поэтому MyIndex4 и не должно быть. Почему исключение?
Присоединить изображение
|
|
olegenty |
Отправлено: 28.12.2005, 07:46 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
возможно, какоее-то из свойств на него указывает.
|
|
Inga |
Отправлено: 29.12.2005, 11:47 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
Научите, как правильно сделать с помощью динамического распределения памяти?
Написала в классе формы в разделе public: TClientDataSet * ClientDataSet4;
Перед использование пишу: Form1->ClientDataSet4 = new TClientDataSet(Form1);
Затем открываю другую форму и использую в ней ClientDataSet4 (сортировка по индексу). После закрытия формы пишу delete Form1->ClientDataSet4;
При попытке снова создать новый ClientDataSet4; опять пишет, что прошлый индекс MyIndex4 не найден.
Использование индекса в другой форме выглядит так:
CODE |
Form1->ClientDataSet4->IndexName = "MyIndex4";
TFilterOptions FO;
FO << foCaseInsensitive;
Form1->ClientDataSet4->FilterOptions=FO;
AnsiString IDE = DBGrid1->Columns->Items[2]->FieldName;
Form1->ClientDataSet4->Filter = IDE +"=" +"'" + AnsiString(sEdit3->Text)+AnsiString("*") +"'";
if(sEdit3->Text=="")
{
Form1->ClientDataSet4->Filtered = false;
}
else
{
Form1->ClientDataSet4->Filtered = true;
}
|
Если индекс не использовать, то есть не сортировать данные, то никаких ошибок при повторном заполнении ClientDataSet4 не возникает. Подскажите куда смотреть? |
|
olegenty |
Отправлено: 29.12.2005, 11:59 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
а если не создавать индекса, а вместо этого воспользоваться св-вом IndexFieldNames?
|
|
Inga |
Отправлено: 29.12.2005, 12:50 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 12
|
Все, спасибо, разобралась! |
|