delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
495 Users Online NOW
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi



Loremo - the 1.5 liter car coming in 2009




Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (0)


Direct File Access with a StringGridGo to Max Kleiner's websiteFormat this article printer-friendly!Bookmark function is only available for registered users!
Product:
Delphi all versions
Category:
VCL-General
Skill Level:
Scoring:
Last Update:
06/26/2003
Search Keys:
delphi delphi3000 article borland vcl code-snippet PAC Architecture StringGrid Fileaccess populate
Times Scored:
3
Visits:
3815
Uploader: Max Kleiner
Company: kleiner kommunikation
Reference: N/A
 
Question/Problem/Abstract:
From time to time we need to populate a stringgrid from a file and save to a file in a well defined structure like a record.
Here's a way to handle this with a contol class.
Answer:



Direct file access refers to that reading physical files from a local file system, and

managing the data stored in them.
These files can be simple of binary or ASCII filetyp, in our case the container is a record.

type
TAppData = record
   Name: string[50];
   Size: string[20];
   Release: string[30];
   descript: string[80];
end;


You can always use a StringGrid to display a Query Result, but if you donīt need the overhead of a data aware component or you don't want a database in an embedded system for ex., direct file access is the choice.  
But as a developer you are responsible for every aspect of the data access.
In short, before any data access can occur, data must be read from one or more files and stored in memory.

Memory structures are
- Streams,
- StringLists
- file of record
- arrays of records, and so on

Next we need a class, which shows sort of the principle of the PAC Architecture
(Presentation, Abstract, Control) in One. Every agent is responsible for a specific aspect of the application's functionality and consists of three elements: presentation (stringgrid), abstraction (record), and control (load from file of record to a stringgrid).  


  TBuildAppGrid = class (TObject)
  private
    aGrid: TStringGrid;
    app: TAppData;
    f: file of TAppData;
    FaDatfile: ShortString;
  protected
    function GetaDatfile: ShortString;
    procedure SetaDatfile(const Value: ShortString);
  public
    constructor initGrid(vGrid: TStringGrid; vFile: shortString);
    procedure fillGrid;
    procedure storeGrid;
    property aDatfile: ShortString read GetaDatfile write SetaDatfile;
  end;


Next, if a data file already exists, it is opened and the previously stored
data is read from it. In our case the data is written to the stringgrid (which is serving both as a memory structure for holding the data and as a visual control for navigating and editing the data). We need the constructor to pass the grid and the filename, so the class TBuildAppGrid is independent from a form namespace, no uses like frmUnit is needed, just uses QGrids as a dependency.

{
******************************** TBuildAppGrid *********************************
}
constructor TBuildAppGrid.initGrid(vGrid: TStringGrid; vFile: shortString);
begin
  aGrid:= vGrid;
  aDatfile:= vFile;
  with aGrid do begin
    ScrollBars:= ssAutoVertical;
    FixedRows := 1;
    FixedCols:= 0;
    ColCount:= 4;
    RowCount:= 10;
  end;
end;

procedure TBuildAppGrid.fillGrid;
var
  crow: Integer;
begin
  crow := 1;
  with aGrid do begin
    Cells[0,0]:= 'Application Name';
    ColWidths[0]:= 120;
    Cells[1,0]:= 'App Size';
    ColWidths[1]:= 60;
    Cells[2,0]:= 'Release Date';
    ColWidths[2]:= 90;
    Cells[3,0]:= 'Description';
    ColWidths[3]:= 140;
    if aDatFile <> '' then begin
      AssignFile(f,aDatFile);
      Reset(f);
      try
        while not Eof(F) do begin
          Read (F, app);
          Cells[0,crow]:= app.Name;
          Cells[1,crow]:= app.size;
          Cells[2,crow]:= app.Release;
          Cells[3,crow]:= app.descript;
          Inc(cRow);
          RowCount:= crow;
        end;
      finally
     CloseFile(f);
    end;
   end;// if FileExists...
  end; //with
end;

function TBuildAppGrid.GetaDatfile: ShortString;
begin
  if FileExists(FaDatFile) then
  result:= FaDatFile
  else result:= '';
end;


This CLX example of direct access presented so far assumes that only a single user can access the files. If two or more users (or applications) can be permitted to access the data simultaneously, your code must also be build to resolve competition for records.
Next, we have to store the data after editing:


implementation

uses sysutils, QDialogs, QControls,
  QStdCtrls;


procedure TBuildAppGrid.SetaDatfile(const Value: ShortString);
begin
  if FaDatfile <> Value then begin
    FaDatfile := Value;
  end;
end;

procedure TBuildAppGrid.storeGrid;
var
  crow: Integer;
begin
  //if FModified then
  if MessageDlg('Save Changes in ' +
             aDatFile, mtConfirmation,mbOkCancel,0) = mrOK then
   begin
     AssignFile(f, aDatfile);
     Rewrite(f);
   try
     for crow:= 1 to Pred(aGrid.RowCount) do begin
       app.Name:= aGrid.Cells[0, crow];
       app.size:= aGrid.Cells[1, crow];
       app.Release:= aGrid.Cells[2, crow];
       app.descript:= aGrid.Cells[3, crow];
       Write (f, app);
     end;
   finally
     CloseFile(f);
   end;
  end; //if MessageDlg...
end;
end.

At least the client calls the class like this:

procedure TForm1.FormCreate(Sender: TObject);
begin
  myDatFile:= 'binaries3.txt';
  myGridC:= TBuildAppGrid.initGrid(strGrd, myDatFile);
  myGridC.fillGrid;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  myGridC.storeGrid;
  myGridC.Free;
end;





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment













 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
I. Siticov
 
   














 







     
  Copyright Đ 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)