C++ Builder Tutorials

C++Builder - ClientDataSet, part 2

Preparations

  1. If you haven't done so already, create a new folder \CppProjects on your disk.
  2. Create folder XMLDatabase2 "under" \CppProjects.
  3. Download XMLDatabase2.zip (source code for parts 2 and 3) and unzip it to folder XMLDatabase2.
  4. Compile and run the application, immediately stop it and next copy Articles.xml from folder XMLDatabase2 to folder XMLDatabase2\Win32\Debug.

Reading from / writing to a file

What's the use of a database, that is not saved to a disk file?

So, at the start of the application, we load our database from an XML file (Articles.xml) that is located in the same folder as the exe-file. If that .xml file doesn't exist, we create an empty TClientDataSet:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  panEdit->Hide();
  ArticlesXML = ExtractFilePath(Application->ExeName) + "Articles.xml";
  if (FileExists(ArticlesXML))
    cdsArt->LoadFromFile(ArticlesXML);
  else
    cdsArt->CreateDataSet();
  cdsArt->LogChanges = false;
  cdsArt->IndexFieldNames = "Name"; // order the grid on field NAME
  cdsArt->First();
  ShowStatus("browsing", "OK");
}

When the application terminates, we save the data to Articles.xml:

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  cdsArt->MergeChangeLog();
  cdsArt->SaveToFile(ArticlesXML);
}

If you run the application in the IDE of C++Builder, the exe-file and the XML file will be saved in the "Debug" folder, in our case in \CppProjects\XMLDatabase2\Win32\Debug.
If you copy the exe-file to another folder, also copy Articles.xml to that folder.


Safer adding and editing of records

Instead of directly adding and editing in the grid, we added a panel named panEdit, with 4 TDBEdit controls, each holding one of the fields.

We are not using the buttons "Post" and "Cancel" of the navigator anymore, so we removed them (see the Object Inspector, property VisibleButtons). Instead, we use two buttons on the panel that we designed.

panEdit

We show and hide the panel panEdit at the appropiate times. Look at the code:

  • when the program starts, the panel is hidden
  • the events BeforeInsert and BeforeEdit of cdsArt show panEdit
  • the button btnOK "posts" the record (if there are no errors, see later) and it hides panEdit
  • the button btnCancel "cancels" the clientdataset operation and hides panEdit

    Showing the status

    We added a TStatusBar component that shows what is going on.
    This is controlled by our function ShowStatus():

    void TForm1::ShowStatus(String DState, String Stat)
    { SBar->Panels->Items[0]->Text = "Records: " + IntToStr(cdsArt->RecordCount);
      SBar->Panels->Items[1]->Text = "State: " + DState;
      SBar->Panels->Items[2]->Text = "Status: " + Stat;
    }

    Validating

    Before posting a record, we check if every field value is valid. Are there no double ID's? Are there no empty fields? And more.

    We deal with this very important issues in the next part of our tutorial.