Board index » delphi » how to know which rows are selected in dbgrid delphi2

how to know which rows are selected in dbgrid delphi2

In delphi2 I use multiselect in dbgrid. When i use
gbgrid1.selectedrows.count, i can tell how many rows are selected,
but how can i know which rows are selected? Any ideas?  Thanks for
any suggestions.

Frank at fji...@msn.com

 

Re:how to know which rows are selected in dbgrid delphi2


Quote
Frank Jiang (fji...@msn.com) wrote:

: In delphi2 I use multiselect in dbgrid. When i use
: gbgrid1.selectedrows.count, i can tell how many rows are selected,
: but how can i know which rows are selected? Any ideas?  Thanks for
: any suggestions.

: Frank at fji...@msn.com

That's something I would like to know, too.
In Delphi's readme file some lines are spent on how to use the
multiselect property, but I could not make sense of them.
To me it is a very important feature that should deserve (better)
documentation (does anyone know if Steve Koterski is still with us?).
Regards,

Andy

Re:how to know which rows are selected in dbgrid delphi2


Hello,
  This one really got me going.  I went through the VCL source
and found indeed there is a bunch of undocumented multiselect features
for the DBGrid.  I think the reason they are undocumented is because
they don't work.

  For example the TDBGrid (found in DBGrids.pas) has a property
called SelectedRows which is of type TBookMarkList (also in
DBGrids.pas).  It has an Items property which supposed to keep a list
of bookmark strings (I guess they wanted to name bookmarks with
strings and pointers)  I dug deeper and wrote some code to see if I
could pull the SelectedRows.Items[cnt] text out. Guess what?
  The strings came up empty.  Yes, the Count property worked great,
but the strings were empty. Now, I'm getting real curious.

  I look into how the thing actually works and find DBGrids has a
BookMark property of type TBookMarkStr (just a string).  Well, I
decided I'd see what happens if I placed a string into this property.
It bombed in a big way.  Some exception about being at the top of the
table.  I think the exact call that is bombing in the VCL is:

{* this is Delphi 2.0 Code from its RTL Source released with Delphi
2.0 C/S.  All copyrights are granted.*}
function TDataset.GetBookmarkStr: TBookmarkStr;
begin
  Result := '';
  if (State in [dsBrowse, dsEdit, dsInsert]) and (FRecordCount > 0)
    and (ActiveBuffer[FBookmarkOfs] = #0) then
  begin
    SetString(Result, PChar(@ActiveBuffer[FBookmarkOfs + 1]),
FBookmarkSize);
  end;
end;

procedure TDataSet.GotoBookmark(Bookmark: TBookmark);
begin
  if Bookmark <> nil then
  begin
    CheckBrowseMode;
    Check(DbiSetToBookmark(FHandle, Bookmark));
    Resync([rmExact, rmCenter]);
  end;
end;

==== Right here we pass in a type of TBookMarkStr and then pass
it as pointer to a string === Up above is where the error occurs.
procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr);
begin
  GotoBookmark(Pointer(Value));
end;

So I figure I am hosed, but then I actually look at what the VCL was
trying to do and it makes sense.  When is multiselect mode they simply
create an anchor bookmark and then keep track of the number of rows.
With these two values you can goto the bookmark and then parse the
records using the count.

With this I made the following chunk of TEST code to see I could do it
and I could.  It's ugly, and I probably would go into the VCL and make
it work correctly before I actually implemented this, but it works so
hey take it for what it's worth:

type

   TGridSelection = record
      bSelected : boolean;
      iRows     : integer;
      bkAnchor  : TBookMark;
   end;

var
  Form1: TForm1;
  MyGridSel  : TGridSelection;

implementation

{$R *.DFM}

{* this event procedure simply goes through the GridSelection based on
the *}
{* anchor and the number of rows.  If rows is negative then they
selected  *}
{* with the up arrow and if it is positive they selected with the down
*}
{*
*}
{* basic premise is to go from the anchor record and physically go
through *}
{* the table records.  This mimics closely what the VCL tried to
accomplish*}
procedure TForm1.BitBtn1Click(Sender: TObject);
type TEnum_Dir = (UP,DOWN);

var  cnt : integer;
     eDir: TEnum_Dir;

begin
   eDir := UP;
   if (MyGridSel.bSelected) then
     begin
        memo1.lines.clear;
        if MyGridSel.iRows > 0 then
           eDir := DOWN;

        cnt := ABS(MyGridSel.iRows);

        table1.gotobookmark(MyGridSel.bkAnchor);
        While cnt >= 0 do
           begin
              memo1.lines.add(table1.fields[1].asstring);
              if eDir = UP then
                 table1.prior
              else if eDir = DOWN then
                 table1.next;

              dec(cnt);
           end;
        table1.gotobookmark(MyGridSel.bkAnchor);

        memo1.lines.add('This is the end of the list...');
     end;
end;

{************************************************************}
{* This event creates the bookmark for the current record   *}
{* and begins the row counting.                             *}
{************************************************************}
procedure TForm1.DBGrid1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
   cnt : integer;
begin
   if (ssShift in Shift) and ((Key = VK_DOWN) or (Key = VK_UP)) then
      begin
           try
              {*if we do not have selection area yet, start one*}
              if not MyGridSel.bSelected then begin
                 {* the shift arrow key moved the table record *}
                 if (Key = VK_DOWN) then
                    table1.prior
                 else if (Key = VK_UP) then
                    table1.next;

                 {*create the actual GridSelection record*}
                 MyGridSel.bkanchor := table1.getbookmark;
                 MyGridSel.bSelected := true;
                 MyGridSel.iRows := 0;

                 {* move the table record back *}
                 if (Key = VK_DOWN) then
                    table1.next
                 else if (Key = VK_UP) then
                    table1.prior;
              end;

              {* now increment or decrement the row counter *}
              if MyGridSel.bSelected then
                 if Key = VK_UP then
                    dec(MyGridSel.iRows)
                 else
                    inc(MyGridSel.iRows);

           except on E:EDBEngineError do
               begin
                  Memo1.lines.clear;

                  for cnt := 0 to E.Errorcount-1 do
                     Memo1.lines.add(IntToStr(E.Errors[cnt].ErrorCode)
+ ' -- ' + E.Errors[cnt].Message);

                  Memo1.lines.add('There was an error with your
database modification request.');
                  Memo1.lines.add('Please try again later.');
               end;
            end;
      end
   {* if they just hit the arrow key without the shift held down, then
reinit*}
   {* the GridSelection record
*}
   else if (Key = VK_UP) or (Key = VK_DOWN) then
      if MyGridSel.bSelected then
         begin
            MyGridSel.bSelected := false;
            MyGridSel.iRows := 0;
            table1.FreeBookMark(MyGridSel.bkAnchor);
         end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   MyGridSel.bSelected := false;
   MyGridSel.iRows     := 0;
end;

end.

Boy, I hate these newsgroups, they really get me digging.

Hope this helps,
Jeff
-------------------

Quote
atroe...@nelly.mat.univie.ac.at (Andreas Troester) wrote:
>Frank Jiang (fji...@msn.com) wrote:
>: In delphi2 I use multiselect in dbgrid. When i use
>: gbgrid1.selectedrows.count, i can tell how many rows are selected,
>: but how can i know which rows are selected? Any ideas?  Thanks for
>: any suggestions.
>: Frank at fji...@msn.com
>That's something I would like to know, too.
>In Delphi's readme file some lines are spent on how to use the
>multiselect property, but I could not make sense of them.
>To me it is a very important feature that should deserve (better)
>documentation (does anyone know if Steve Koterski is still with us?).
>Regards,
>Andy

Re:how to know which rows are selected in dbgrid delphi2


thom...@usafe16.ramstein.af.mil (Capt Jeffrey T. Thomas) wrote:

a whole lot of code.

Snipped all, because it can be done a lot easier. I found a solution
to  the problem, but since I don't have the code anymore I suggest you
take a look at Borlands site. There is an example, I think it was in
the Delphi Tech info section.

B. Eiklid

Other Threads