[DUG] StringGrid/DBGrid

John Bird johnkbird at paradise.net.nz
Thu Sep 8 13:50:54 NZST 2005


I like both options - the Virtual TreeView looks terrific, although there is
some learning curve

Any advice on the best way to get either D7 or D2005?

John B

-----Original Message-----
From: Rohit Gupta [mailto:rohit at cfl.co.nz] 
Sent: Thursday, 8 September 2005 9:07 a.m.
Subject: Re: [DUG] StringGrid/DBGrid


I would go for the dbgrid and clientdataset.  The virtualtreeview is 
good but does have the initial high cost of setup.... which always 
deters me as I have to relearn it every time I use it.  :-)

From:           	"John Bird" <johnkbird at paradise.net.nz>
To:             	"'NZ Borland Developers Group - Delphi List'"
<delphi at ns3.123.co.nz>
Subject:        	[DUG] StringGrid/DBGrid
Date sent:      	Wed, 7 Sep 2005 15:54:38 +1200
Organization:   	John Bird Consulting
Send reply to:  	johnkbird at paradise.net.nz,
       	NZ Borland Developers Group - Delphi List <delphi at ns3.123.co.nz>
	<mailto:delphi-request at ns3.123.co.nz?subject=unsubscribe>
	<mailto:delphi-request at ns3.123.co.nz?subject=subscribe>

[ Double-click this line for list subscription options ] 

I have been using the D5 vanilla StringGrid for displaying data. The data I
am reading is from non database data files - I am reading it in myself using
TFileStream.

>From now on I want to be inputting and editing data in grids, but the
standard StringGrid does not have many embedded cell editors - the one it
supplies seems pretty simple - it does not do even the things the standard
editbox one does (move through a string one word at a time etc with Ctrl/W
etc).

Can anyone who has an opinion on the options below kindly give a
recommendation! (see below for a tiny reward)

As I see it my options are:

Option 1 - Add a few extra features to the standard stringgrid and use that
for my stuff.
____________________________________________________________________________
______________
I would need:
    -a enter cell event (to store the current contents of the cell to check
for changes)
    -a exit cell event (so I can call code to verify any cell changes)
    -someway to know the position on the screen of the current cell in case
I want to pop up a lookup window  If I could do all of these I would have
all I need.  Best way to get these? I could use the onDrawCell event?

Option 2 - DBGrid
_________________
I note the DBGrid seems to have a lot more data verification and cell events
onColEnter and onColExit (are these meant to be called onCellEnter and
onCellExit?)  The help says these are when a cell is entered and exited.  If
it is a colenter and not a cell enter, what happens if the user arrows from
one cell to the one below it - does it fire?

I notice there is a LoadFromFile and a SavetoFile which looks like I could
use to get the data into the grid. To use the TDBGrid I could use these
methods or a TClientDataSet.

Option 3 - use a third party grid control.
__________________________________________
So far I haven't needed to do this, but have been wondering about some of
the 3rd party components like XStringGrid and AliGrid.  I like having
everything vanilla and not having upgrade issues, but also don't wish to
reinvent the wheel all the time! 

Option 4 - TClientDataSet and upgrade _____________________________________
Now TClientDataSet is not in D5, and some friends (namely Gary B) have been
long telling me this is the simplest way to display, edit and manipulate
data (using DBGrid), so it might be time to upgrade, hence look at D7 or
D2005.  I think the stuff I have done so far is unlikely to break D2005, so
happy to look at either.  Best sources of an upgrade?


Reward
______
For reading this far here is a tiny reward: a little bit of code I wrote to
sort a standard stringgrid.  Very fast. Note it only does (case insensitive)
alpha compares, but could easily be modified to do other orderings.  As I
already put in numbers right justified into grids it also works for numbers
for me.

It makes a tag stringlist which is sorted in one step, then copies the
original data into a temporary array and then puts it back in the new order
to the original stringgrid.  While a bit more work, it is a lot faster than
using a two record at a time exchange or a bubblesort.  It also allows
sorting by two columns.

If there is anything I have done you would like to improve kindly tell me!

procedure xcSortGrid(var
PGrid:TStringGrid;SortColumn1:Integer;SortColumn2:integer;AscDesc:char;CaseI
nSensitive:Boolean);
var
UnsortedList:TStringList;
olddefrow,newdefrow:integer;	//keep same data row as default
oldrow,datalhs,ptr,colptr,rowptr:integer;
tempstr:string;
lAscDesc:char;
tempcells:array of array of string;
begin
  if PGrid.rowcount < 2 then exit;	//nothing to sort
  UnsortedList:=TStringList.Create;
  UnsortedList.sorted:=false;
  olddefrow:=-1;
  NewDefRow:=-1;
  if PGrid.row>0 then oldDefRow:=PGrid.row;
  for ptr:=0 to PGrid.rowcount-1 do
  begin
    //put sort col plus orig pointer into stringlist
    tempstr:=PGrid.cells[SortColumn1,ptr]+PGrid.cells[SortColumn2,ptr];
    if CaseInsensitive=true then uppercase(tempstr);
    xcstrpad(tempstr,60);		//make the string 60 chars long
    tempstr:=tempstr+inttostr(ptr);
    UnSortedList.Add(tempstr);
  end;
  //sort it
  UnSortedList.sorted:=true;
  //now copy original cells to tempcells dynamic array
  setlength(tempcells,PGrid.colcount,PGrid.rowcount);
  for rowptr:=0 to PGrid.rowcount-1 do
  begin
    for colptr:=0 to PGrid.colcount-1 do
    begin
      tempcells[colptr,rowptr]:=PGrid.cells[colptr,rowptr];
    end;
  end;
  //now write back to grid
  lAscDesc:=upcase(AscDesc);
  if lAscDesc='A' then
  begin
    for ptr:=0 to PGrid.rowCount-1 do
    begin
      tempstr:=copy(UnSortedList[ptr],61,10);
      oldrow:=strtoint(tempstr);
      if oldrow=oldDefRow then NewDefRow:=ptr;
      //oldptr is orig row number, ptr is new row number
      for colptr:=0 to PGrid.colcount-1 do
      begin
        PGrid.cells[colptr,ptr]:=tempcells[colptr,oldrow];
      end;
    end;
  end
  else
  begin
    for ptr:=PGrid.rowcount-1 downto 0 do
    begin
      tempstr:=copy(UnSortedList[ptr],61,10);
      oldrow:=strtoint(tempstr);
      if oldrow=oldDefRow then NewDefRow:=ptr;
      //oldptr is orig row number, ptr is new row number
      for colptr:=0 to PGrid.colcount-1 do
      begin
        PGrid.cells[colptr,ptr]:=tempcells[colptr,oldrow];
      end;
    end;
  end;
  UnsortedList.free;
  tempcells:=nil;
  if (OldDefRow>0) and (NewDefRow >=0) then PGrid.row:=NewDefRow;
  //note this means if the current row was 0 (the top) the new default row
after sorting is still the top, 
  //which is generally the best sense.
end;


John B


_______________________________________________
Delphi mailing list
Delphi at ns3.123.co.nz http://ns3.123.co.nz/mailman/listinfo/delphi
Regards

Rohit

======================================================================
CFL - Computer Fanatics Ltd.  21 Barry's Point Road, AKL, New Zealand
PH    (649) 489-2280 
FX    (649) 489-2290
email rohit at cfl.co.nz  or  r.gupta at xtra.co.nz
======================================================================






More information about the Delphi mailing list