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


Автор: Лена 21.9.2006, 14:51
Нажимаю на кнопку стандартного компонета навигатора удалить запись (набор ClientDataSet). Пытаюсь обработать нажатие показом диалогово окна:
Код

void __fastcall TDataModule2::ClientDataSetKeyBeforeDelete(
      TDataSet *DataSet)
{
 if (Application->MessageBox("Удалить?", "Подтвердите удаление", MB_YESNO +
    MB_ICONQUESTION) == IDYES) {
     ClientDataSetKey->ApplyUpdates(-1);
}
else {
   ClientDataSetKey->CancelUpdates(); //вижу что эта строка отрабатывается в точке остона, но запись удаляется
    
}

Запись удаляется и при нажатии Да и при нажатии Нет. Почему удаляется при нажатии Нет?

Автор: Vyacheslav 21.9.2006, 14:59
Вы же это этот код поставили на обработчик BeforeDelete
Он выполняется, а дальше идет удаление smile
Попробуйте это перенести на AfterDelete

Добавлено @ 15:07 
Я бы кстати сделал проще
Код

void __fastcall TDataModule2::ClientDataSetKeyBeforeDelete(
      TDataSet *DataSet)
 if (Application->MessageBox("Удалить?", "Подтвердите удаление", MB_YESNO +
    MB_ICONQUESTION) != IDYES) {
         Abort();
    }  
}

void __fastcall TDataModule2::ClientDataSetKeyAfterDelete(
      TDataSet *DataSet)
{
  ClientDataSetKey->ApplyUpdates(-1);
}



Автор: Лена 21.9.2006, 15:13
Спасибо! 
Но есть вопросы  smile 
Мне пока не понятно логика работы ClientDataSet я удалила записи используя навигатор. Затем нажала кнопку refresh навигатора и все записи вернулись. Что дописать? 

P.S. Пока писала получила от вас код. Наверное решение это событие AfterDelete?

Автор: Vyacheslav 21.9.2006, 15:25
Точно.

Автор: Лена 21.9.2006, 15:30
Нет не понятно.  smile 
Как сделать так (какие события написать), чтобы записи удалясь и не появлялись после нажатия refresh в навигаторе?  
Если запись удалена навигатором, то сразу должна быть удалена из базы с которой связан ClientDataSet. Например, я удаляю запись. Нажимаю в навигаторе Утвердить. Затем нажимаю рефреш и запись снова появляется. Получается кнопка навигатора Утвердить не отрабатывает?  smile


P.S.
Код добавила, но записи появляются:
Код

void __fastcall TDataModule2::ClientDataSetKeyBeforeDelete(
      TDataSet *DataSet)
 if (Application->MessageBox("Удалить?", "Подтвердите удаление", MB_YESNO +
    MB_ICONQUESTION) != IDYES) {
         Abort();
    }  
}

void __fastcall TDataModule2::ClientDataSetKeyAfterDelete(
      TDataSet *DataSet)
{
  ClientDataSetKey->ApplyUpdates(-1);
}

Автор: Vyacheslav 21.9.2006, 15:57
Кнопки "Утвердить" - нет. Естб кнока Post - завершить вставку или редактирование записи с сохранением результата редактирования.
Основная проблем, как  я понимаю, не дейсвует ClientDataSetKey->ApplyUpdates(-1)?


Автор: Лена 21.9.2006, 16:12
>кнока Post 

Да Post.  Моя задача такая:
в гриде данные идущее из базы через связку ADOQuery -> TDatasetProvider -> TClientDataset -> TDatasource. Я хочу, чтобы навигатор не посредственно воздействовал на отображаемые данные и на саму базу данных. Если пользователь добавил строку, то при переходе на другую строку или при нажатии кнопки Post все это закреплялось и в гриде и в самой базе данных. т.е. если пользователь нажмет refresh то ничего не произойдет, потому что каждое действие навигатора он воздействует и на грид и на базу.  Так же и при редактировании: пользователь отредактировал запись, перешел на другую все закрепилось и в гриде и в базе, также и при удалении строк ( в общем все кнопки редактирования у навигатора). Хочется чтобы все кнопки навигатора воздействовали и на грид и на базу. Я просто запуталась с многочисленными событиями Before/After... помогите smile 


Автор: Vyacheslav 21.9.2006, 17:05
Ну если c ApplyUpdates все в порядке,
то  достаточно поставить два обработчика 
Код

void __fastcall TForm1::ClientDataSet1AfterPost(TDataSet *DataSet)
{
     ClientDataSet1->ApplyUpdates(-1);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ClientDataSet1AfterDelete(TDataSet *DataSet)
{
      ClientDataSet1->ApplyUpdates(-1);
}
//---------------------------------------------------------------------------


Автор: Лена 21.9.2006, 17:21
Cейчас у меня такой код:
Код


void __fastcall TDataModule2::ClientDataSetKeyBeforeDelete(
      TDataSet *DataSet)
{

 if (Application->MessageBox("Óäàëèòü?", "Ïîäòâåðäèòå óäàëåíèå", MB_YESNO +
    MB_ICONQUESTION) != IDYES) {
         Abort();
    }
}
//---------------------------------------------------------------------------

void __fastcall TDataModule2::ClientDataSetKeyAfterDelete(
      TDataSet *DataSet)
{
   ClientDataSetKey->ApplyUpdates(-1);
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

void __fastcall TDataModule2::ClientDataSetKeyAfterPost(TDataSet *DataSet)
{
 ClientDataSetKey->ApplyUpdates(-1);
}
//--

Запускаю приложение в гриде 4 записи.
1. Удаляю одну из них.
2. Подтвеждаю удаление.
3. Нажимаю refresh и снова выпазить строка которую я удалила. smile 


Если перезапустить приложение то строки действительно удалена, не понятно, почему она появлалась после refresh до перезапука приложения? Как заставить навигатор намертво фиксировать каждое свое действие? Если строка удалена то никаким refresh ее уже не увидеть в этой ссесии.

Автор: Vyacheslav 21.9.2006, 17:33
А дело не в навигаторе, а в том, что у Вас провайдер неверно обновляет. Он где то закешировал данные. Кстати, ошибка на refresh - очень чато встречающийся баг в реализации. Надежнее будет вместо refresh  просто закрыть-открыть таблицу.  

Автор: Лена 21.9.2006, 17:42
>что у Вас провайдер не верно обновляет.

Cпасибо, теперь понятно, а то я уже начала тихо ненавидеть ClientDataSet  smile 
У меня настроено на базу данных на PostgreSQL. Решила так: запретила кнопку refresh и теперь все работает и выглядит как надо.  smile 


Автор: Vyacheslav 22.9.2006, 10:15
Я бы всетаки реализовал вариант с переоткрытием соответсвенно задав обработчик BeforeRefresh. Если бы был простая таблица, то это бы выглядела вот так
Код

void __fastcall TForm1::ClientDataSet1BeforeRefresh(TDataSet *DataSet)
{
    Table1->Active  = false;
    Table1->Active  = true;
    Abort();
}


Тогда бы и кнопка refresh  работа нормально 

Но у Вас используется провайдер, насколько я понял. Там  сложнее. Вернее не сложнее, но я подзабыл уже все. Больше двух лет с Builder и с базами не работаю

Автор: Embesse 26.1.2023, 15:22
Модератор: Сообщение скрыто.

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