3

I would like to retrieve a value from a TDBGrid the selected row, how can I do?

procedure TForm7.Button2Click(Sender: TObject);
    var
      i, j: Integer;
      s: string;
    begin
      if DBGrid1.SelectedRows.Count>0 then
        with DBGrid1.DataSource.DataSet do
          for i:=0 to DBGrid1.SelectedRows.Count-1 do
          begin
            GotoBookmark(DBGrid1.SelectedRows.Items[i]);
            for j := 0 to FieldCount-1 do
            begin
              if (j>0) then s:=s+', ';
              s := s + FindField(Fields.Fields[j].FieldName).AsString;
            end;
            Listbox1.Items.Add(s);
            s:= '';
          end;
    end;
Morteza Asadi
  • 1,819
  • 2
  • 22
  • 39
Nu Carvignulu
  • 61
  • 1
  • 1
  • 15
  • What is your question? There is one obvious problem with the code in your q, namely that you do not explicitly initialise your variable `s` for each selected row: add `s := '';` after the `GotoBookmark...` line. – MartynA Jan 21 '17 at 11:51

5 Answers5

8

The code below fixes a few problems with yours.

The main problems were the fact that you weren't correctly initialising s and your way of getting the fields for the selected row(s) was flawed.

The calls to DataSet.Disable/EnableControls and ListBox1.Items.BeginUpdate/EndUpdate are to speed the process up.

Also, avoid the with construct like the plague. As you can see, my use of a local DataSet variable instead involves minimal extra typing and avoids all sorts of accidental problems that can arise when you use with.

procedure TForm1.GetSelected;
var
  i,
  J : Integer;
  s : String;
  DataSet : TDataSet;
begin
  if DBGrid1.SelectedRows.Count>0 then begin
    DataSet := DBGrid1.DataSource.DataSet;
   //  with DBGrid1.DataSource.DataSet do
   try
     ListBox1.Items.BeginUpdate;
     DataSet.DisableControls;
     for i:=0 to DBGrid1.SelectedRows.Count-1 do
      begin
        DataSet.GotoBookmark(Pointer(DBGrid1.SelectedRows.Items[i]));
        s := '';
        for j := 0 to DataSet.FieldCount - 1 do
        begin
          if (j>0) then s:=s+', ';
          s := s + DataSet.Fields[j].AsString;
          //s := s + FindField(Fields.Fields[j].FieldName).AsString;
        end;
        Listbox1.Items.Add(s);
        //s:= '';
      end;
    finally
      DataSet.EnableControls;
      ListBox1.Items.EndUpdate;
    end;
  end;
end;

**Update: **

You can set the current grid row as selected like this

DBGrid1.SelectedRows.CurrentRowSelected := True;

Update #2

The grid's selected rows are stored in a TBookmarkList named SelectedRow. To clear the current selections, all you need do is to call its Clear method, like so:

procedure TForm1.btnClearSelectedClick(Sender: TObject);
begin
  DBGrid1.SelectedRows.Clear;
end;

Equally, if you want to clear your ListBox, you just call its Clear method, as in:

procedure TForm1.btnClearListBoxClick(Sender: TObject);
begin
  ListBox1.Clear;
end;

If you are having trouble getting my code to work, try this:

  1. In the Object Inspector, set the DBGrid Options property dgMultiSelect to True.

  2. Place a button on your form and in its OnClick handler call GetSelected.

Compile and run. Click a row in the grid and then the button. Nothing happens. The reason is that clicking the button moves focus away from the DBGrid, so that as far as it is concerned, none of its rows is selected. Then try step 3.

  1. Run the app again. This time press and hold the Ctrl key while you click the grid then the button. This time the selected row appears in the ListBox. With the Ctrl button still down, click another row in the grid, then the button. This time, both rows are added to the ListBox.
MartynA
  • 30,454
  • 4
  • 32
  • 73
  • It does not work, unfortunately there is no row selected, but there is some property of which must be activated to select a row? – Nu Carvignulu Jan 21 '17 at 16:13
  • It does work. See the update for how to select the current grid row. – MartynA Jan 21 '17 at 16:54
  • but this istruction: if DBGrid1.SelectedRows.Count>0 then begin, does not find rows selected . – Nu Carvignulu Jan 21 '17 at 17:10
  • Then you are not using the code I posted. Try this: paste ` DBGrid1.SelectedRows.CurrentRowSelected := True;` in as the first line of my `GetSelected` routine, then single-step through it in the debugger. – MartynA Jan 21 '17 at 17:37
  • Work fine but only for one time. i need to reset maby? thank's very mutch – Nu Carvignulu Jan 23 '17 at 07:19
  • Please explain exactly what you mean "by only for one time". How does it "not work" after that? – MartynA Jan 23 '17 at 07:34
  • simply put in the first time takes the data, then when we select another different line, the data of the first selection with the second are added together – Nu Carvignulu Jan 23 '17 at 11:06
  • we need a reset for bookmard, becose with instruction 's:=' '; don't resolve my problem – Nu Carvignulu Jan 23 '17 at 11:52
  • Ah, ok - see my **Update #2**. – MartynA Jan 23 '17 at 12:11
  • what? i don't understand – Nu Carvignulu Jan 23 '17 at 12:16
  • Look, when you call my GetSelected method, it lists the records which are currently selected in the grid. You said "then when we select another different line, the data of the first selection with the second are added together". If you want the grid to permit **only** one record to be selected at a time, set the grid's `dgMultiSelect` to false. If you want to allow more than one row to be selected at a time, set dgMultiSelect to true, and then when you want to clear the existing selections, call `DBGrid1.SelectedRows.Clear`. You follow now? – MartynA Jan 23 '17 at 12:22
  • Btw, please feel free to "accept" this answer by clicking the green tick at its top left. – MartynA Feb 02 '17 at 11:46
  • If you are with Delphi Rio so use directly: DataSet.GotoBookmark(DBGrid1.SelectedRows.Items[i]); – Roberto Novakosky Mar 20 '20 at 20:12
1

only a single line call is needed to retrieve a value when you know the column number. The system will automatically return values from the current row, or last line clicked or double-clicked in a grid list.

var colidx : integer; ss : string;

..

ss := DBGrid1.Fields[colidx].AsString;
Joseph Poirier
  • 386
  • 2
  • 17
0

this is my method to retrieve the key

procedure TfrmArticle.Button2Click(Sender: TObject);

begin op:='M';

with frmajtArticlee do
  begin
    Edit1.text:=dm.ADOQueryArticle.fieldbyname('ID_prod').Value;
    Edit2.text:=dm.ADOQueryArticle.fieldbyname('ref_art').Value;
    Edit3.text:=dm.ADOQueryArticle.fieldbyname('code_barre').Value;
    Edit4.text:=dm.ADOQueryArticle.fieldbyname('marque').asstring;
    Edit5.text:=dm.ADOQueryArticle.fieldbyname('qts_art').Value;
    Edit6.text:=dm.ADOQueryArticle.fieldbyname('designation').asstring;
    Edit7.text:=dm.ADOQueryArticle.fieldbyname('prix_achats_ht').Value;
    Edit8.text:=dm.ADOQueryArticle.fieldbyname('prix_vente_faciliter').Value;
    Edit9.text:=dm.ADOQueryArticle.fieldbyname('prix_vente_cache').Value;
    val_mod:=dm.ADOQueryArticle.fieldbyname('ID_prod').asstring;

val_mod:string "declare it in public "

0

Fast solution for one selected row:

  1. Add Data Controls > DBText on current form.
  2. Pick actual DataSource for TDBText with Object Inspector.
  3. Pick necessary DataField in the TDBText with Object Inspector.
  4. Get value in the code as follows: DBText.Caption
sergo911
  • 21
  • 5
-1

IF YOU'RE NEED TO FIND HOW TO GET DATA OF A SELECTED ROW IN THE DBGRID, I HAD THE HINT. I USE DBGRID.SelectedField TO GET THE SELECTED FIELD AND CONVERT THE FIELD TO BE SELECTED TO BOOKMARK BY DB_GRID.SelectedField.DataSet.Bookmark AND USE DATASET.GOTOBOOKMART TO GO TO THE SELECTED RECORD FIELD IN DBGRID DB_DATA.DataSet.GotoBookmark (DB_GRID.SelectedField.DataSet.Bookmark);