ADO Methods

These methods correspond to the buttons on the DBNavigator control. You can, if you wish, create your own buttons to replace the DBNavigator, in which case you need to set each button to carry out a discrete operation such as inserting an empty record, allowing the user to enter data and then saving the new data with a new button.

Replacing the DBNavigator bar is a matter of form design. You may think, probably correctly, that the DBNavigator bar is a little intimidating for a new user so you prefer to create your own friendly buttons with more descriptive labels such as 'Insert New Record' and 'Save New Record'.

First

Moves the file pointer to the first record in the table. Contents of the record should be displayed in any ADO data fields. Any button that calls First or Prior should now be disabled so the user cannot request an action that cannot be completed. Any button that calls Next or Last should probably be enabled.

Prior

Sets current record to the one before the current record. Any buttons calling the Next or Last methods should be enabled at this point.

Next

Moves the file pointer to the next record in the table. Contents of the record should be displayed in any ADO data fields. Any buttons calling the Prior or First methods should be enabled at this point.

Last

Moves the file pointer to the last record in the table. Contents of the record should be displayed in any ADO data fields. Any buttons calling the Last or Next methods should be disabled at this point.

Insert

Inserts a new record before the current record and puts the dataset into Insert and Edit modes.

Delete

Deletes the current record and makes the next record the current one.

Edit

Puts the dataset into edit mode so the current record can be edited.

Post

Writes the change to the current record in the database.

Cancel

Cancels edits to the current record, restores the record display to its condition prior to editing, and turns off Insert and Edit states if they are active.

Refresh

Refreshes the buffered data in the associated dataset.

Locate

This command locates (finds) a record in a table from the field information supplied. For example:

ADOTable1.Locate('CDTitle',combobox3.Text,[]);

This is a whole lot better than constructing your own search routine using while not table.eof do...

The parameters are: the field name in the table, the value sought and a pair of empty square brackets.

Example 1

In this example a link is made to database and fields are extracted from an ADO table object. An edit box is provided so the user can find a team by name.

Code:

procedure TForm1.Button1Click(Sender: TObject);
var found: Boolean;
begin
 found:=false;
//adotable1.open;   (not needed because table opened on form create event
//adotable1.First;   (not needed, table opens at first record anyway)
 while not adotable1.Eof and not found do
  if adotable1clubname.Value = edit1.Text then 
//use locate method for searches - see above
      found := true
  else
   adotable1.Next;
 if not found then
  showmessage ('Not found');
end;

The user can enter the name of a team to find in the box. The code uses the next procedure to scan through the ADO table until the requested record is found. If the record is not found then a message is displayed and the table pointer is moved to the first record.

Example 2

In this example we place two buttons on a form, one to insert a new record and the other to save it.

The form after pressing the Insert New Record button and adding some text.

Code for the buttons:

procedure TForm1.Button1Click(Sender: TObject);
begin
 with adotable1 do
  insert;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
with adotable1 do
 begin
  edit;
  post;
  refresh;
 end;
end;

Additional buttons could be added to edit the current record and save (post) changes, or to delete records.

Example 3

In this example there are two list boxes on a form, one for CD titles and the other for the tracks on each one. When a user clicks on a CD title in the first list box the tracks of that CD are shown in the second list box.

The code for loading the CD titles into the first list box is:

procedure TForm1.FormCreate(Sender: TObject);
begin
 ADOCDsTable.Open;
 while not ADOCDsTable.Eof do
 begin
  listbox1.Items.Add(ADOCDsTableCDTitle.Value);
  ADOCDsTable.Next;
 end;
 ADOCDsTable.Close;
end;

The code for loading the tracks on a selected CD is as follows:

procedure TForm1.ListBox1Click(Sender: TObject);
var i:integer;
 serial_number:string;
begin
 listbox2.Clear; //clear track list
 i:=listbox1.ItemIndex;
 adotable1.Open;
 while not adotable1.Eof do
 begin
  if ADOCDsTableCDTitle.Value=listbox1.Items[i] then
  serial_number:=adotable1SerialNumber.Value;
  ADOCDsTable.Next;
 end;
 ADOCDsTable.Close;
 ADOTrackstable.Open;
 while not ADOTrackstable.Eof do
 begin
  if ADOTrackstableCDID.Value=serial then
   listbox2.Items.ADOTrackstableTrackTitle.Value);
  ADOTrackstable.Next;
 end;
 ADOTrackstable.close;
end;

This scans the first table for a match between the selected title and the titles in a database table. When a match is found the serial number of the CD is copied into a variable for use in the second part of the procedure. This technique is useful in situations where the user is choosing a data item that is not the primary key but where the primary key is required later on. There is a potential problem here in that two CDs could have the same title (e.g. Greatest Hits).

In the second part of the code the primary key, serial_number, is used to identify tracks that include it as their foreign key so that they can be displayed in the second list box.

Example 4

In this example we see how we can populate two combo boxes from two ADO tables. The first combo box is populated from a table that includes company department details. When a department is selected the second combo box is populated with the members of the department, which are taken from the second table. This process involves a fair amount of manipulation of the contents of the ADO tables to identify the items required and place them in the boxes. As the names are chosen from the second combo box one of two buttons on the form is enabled.

procedure TForm1.populatecombo1;  //generalise process
begin
 combobox1.Clear;
 combobox1.Text:='Choose Department';
 adotable1.Open;
 while not adotable1.Eof do
 begin
  combobox1.Items.Add(adotable1DeptName.Value);
  adotable1.Next;
 end;
 adotable1.Close;
end;

procedure TForm1.populatecombo2;
begin
 combobox2.Clear;
 combobox2.Text:='Choose Employee';
 adotable2.Open;
 while not (adotable2.Eof) do
 begin
  if adotable2deptid.Value=deptid then 
//deptid taken from table 1 - primary key/foreign key
  combobox2.Items.Add(adotable2empname.Value);
  adotable2.next;
 end;
 adotable2.close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 populatecombo1;
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
 adotable1.Open;
 while not adotable1.Eof do
 begin
  if adotable1deptname.Value=ComboBox1.Text then 
//match value from table1 with text in combo 1
  deptid:=adotable1deptid.Value; 
//set deptid for later use
  adotable1.Next;
 end;
 adotable1.Close;
 populatecombo2; 
//get data from table 2 based on deptid
end;

procedure TForm1.ComboBox2Change(Sender: TObject);
begin
 populatecombo1; 
//refresh combo box 1
 empname:=combobox2.Text;
 adotable2.Open;
 while not adotable2.Eof do
 begin
  if adotable2empname.Value=empname then 
//use empname to locate record in table
   if adotable2inorout.Value=false then
 //read data fields from record
   begin
    inbutton.Enabled:=true;
    outbutton.Enabled:=false;
   end
  else
  if adotable2inorout.Value=true then
  begin
   outbutton.Enabled:=true;
   inbutton.enabled:=false;
  end;
 adotable2.Next;
end;
 adotable2.Close;
 populatecombo1;
end;

Example 5: Creating Empty Records

This example covers the situation where you want to create a large number of records in a database with a minimal amount of data so that they are available to the user when needed. For school reports, for example, the teachers would want to see a blank report with the pupil's name, form, subject, etc. in the header areas, rather than having to type this in for themselves and create the record from scratch. The following code deals with the creation of a number of bookings in a table. The particular issue here is that there are three sessions in each day that can be booked so there is a nested for loop to achieve this.

procedure TForm2.Button3Click(Sender: TObject);
var i,j,k:integer;
startdate:TDateTime;
begin
 startdate := EncodeDate(2006, 3, 1);
 ADOTable1.Open;
 ADOTable1.Edit;
 for i:= 1 to 61 do //for each day march and april
 begin
  for j:= 1 to 3 do //for each session in a day
  begin
   ADOTable1.Insert; //insert new record
   ADOTable1.FieldValues['Date']:=startdate; //add date
   k:=j mod 3;
   case k of
    1: ADOTable1.FieldValues['Session']:='Morning';
    2: ADOTable1.FieldValues['Session']:='Afternoon';
    0: ADOTable1.FieldValues['Session']:='Evening';
   end;
   ADOTable1.FieldValues['Extension']:=False;
   ADOTable1.FieldValues['EventTitle']:='';
   ADOTable1.FieldValues['CustomerID']:='';
   ADOTable1.FieldValues['Fee']:=0.0;
   ADOTable1.FieldValues['Paid']:=False;
   ADOTable1.Post;
   ADOTable1.Refresh;
  end;
 startdate:=IncDay(startdate,1);
 end;
ADOTable1.Close;
showmessage('Records created');
end;

Example 6 - Updating Accounts and Stock

This example is based on ordering items for a tuck shop or private bar. Items are read with a bar code reader and are displayed on the screen in a list box. For each item ordered the customer ID, the item code and the price are entered in a sales table and the number in stock decreased by 1. 

procedure TScanscreen.AcceptTotalOrderButtonClick(Sender: TObject);
var i:integer; balance:currency; noinstock:integer;
begin
 if MessageDlg(' Confirm Purchase? ', mtConfirmation, [mbYes, mbNo], 0) = mryes then
 begin
  ordertable.open;
  ordertable.edit;
  for i := 0 to currentorderbox.items.count -1 do 
//take each item in the list box
  begin
   ordertable.insert; 
//insert a new record in the orders table
   ordertable.FieldValues['StaffID'] := label2.Caption; 
//set the field values of the order
   ordertable.FieldValues['NameOfItem'] := Currentorderbox.Items[i];
   ordertable.FieldValues['Itemcost'] := strtocurr(currentpricebox.Items[i]);
   stafftable.Open;
   stafftable.Locate('name',label2.Caption,[]) ;
   balance:= stafftable.FieldValues['termlybill']; 
//read the current balance in the staff table
   stafftable.edit;
   stafftable.FieldValues['termlybill']:= balance + strtocurr(currentpricebox.Items[i]); 
//update the balance
   stafftable.Post;
   stafftable.refresh;
   stocklist.open;
   stocklist.locate ('nameofitem',currentorderbox.items[i],[]);
   noinstock:= stocklist.FieldValues['numberinstock'];
 //update the stock total
   dec(noinstock);
   stocklist.edit;
   stocklist.FieldValues['numberinstock']:= noinstock;
   stocklist.Post;
   stocklist.refresh;
   ordertable.Next;
  end;
  ordertable.close;
  stafftable.Close;
  stocklist.close;
 end;
 CurrentOrderBox.clear;
 currentpricebox.clear;
 label4.caption:= '0';
end;

 

Back to Tutorial

Back to Palette List