1

This code gets the StringGrid contents per row with '|' as a separator.

procedure TForm1.datas();
var
  iRow: integer;
  RowData : string;
begin  
  {get stringgrid content}
  for iRow := 1 to Form7.StringGrid1.RowCount -1 do  // count rows
  begin
    RowData := Form7.StringGrid1.Cells[0, iRow] + '|' + Form7.StringGrid1.Cells[1, iRow] + '|' + Form7.StringGrid1.Cells[2, iRow] + '|' + Form7.StringGrid1.Cells[3, iRow] + '|' + Form7.StringGrid1.Cells[4, iRow] + '|' + Form7.StringGrid1.Cells[5, iRow] + '|';
     
    names := RowData; // it only get the last row in string grid :(
  end;
end;

This code is for saving the data to the database:

{SAVE}
procedure TForm1.SaveBtnClick(Sender: TObject);
begin                                                
  datas; // get data
  with SQLQuery4 do
  begin
    if RecordCount = 0 then
    begin
      close;
      SQL.Text := 'Insert into my_db(names) values(:names)';
      Params.ParamByName('names').AsString := names;
    
      ExecSQL;
      SQLTransaction4.Commit;
      Close;
      ShowMessage('Records Successfully Saved!');
    end;
  end;
end;

I want to save all of the StringGrid rows into one database column, but it only saves the data of the last row :(

I want to save it like this in my DB column:

A|B|C|D|E|  // first row
F|G|H|I|J|  // second row

1 Answer 1

1

Inside of your datas() method, each loop iteration is overwriting the value of names with just the current row's data. That is why you are saving only the last row assigned to names. You need to instead append each row to names, preserving its existing data, eg:

procedure TForm1.datas();
var
  iRow: integer;
  RowData : string;
begin  
  names := ''; // <-- RESET THE STRING HERE
  {get stringgrid content}
  for iRow := 1 to Form7.StringGrid1.RowCount -1 do  // count rows
  begin
    RowData := Form7.StringGrid1.Cells[0, iRow] + '|' + Form7.StringGrid1.Cells[1, iRow] + '|' + Form7.StringGrid1.Cells[2, iRow] + '|' + Form7.StringGrid1.Cells[3, iRow] + '|' + Form7.StringGrid1.Cells[4, iRow] + '|' + Form7.StringGrid1.Cells[5, iRow] + '|' + sLineBreak;
     
    names := names + RowData; // <-- APPEND, NOT OVERWRITE!
  end;
end;

Though, I would probably re-write it to something more like this to clean it up a little:

procedure TForm1.datas();
var
  iRow, iCol: integer;
  Grid: TStringGrid;
begin  
  names := '';
  {get stringgrid content}
  Grid := Form7.StringGrid1;
  for iRow := Grid.FixedRows to Grid.RowCount-1 do  // count rows
  begin
    for iCol := Grid.FixedCols to Grid.ColCount-1 do // count colums
    begin
      names := names + Grid.Cells[iCol, iRow] + '|';
    end;
    names := names + sLineBreak;
  end;
end;
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for this answer! :) Now my other problem is retrieving data from database to stringGrid, by splitting data per column by '| ' and put it per row..
There are many different ways you could handle that - 1) Pos() and Copy(), 2) StrUtils.SplitString(), 3) SysUtils.TStringHelper.Split(), 4) TStringList.DelimitedText, 5) a combination of the above
I can get the data by doing Form7.StringGrid1.Cells[0, Form7.StringGrid1.RowCount-1] := (names.split('|')[0]); but I don't know how to put in a loop so that it will get data for each row...
@NewbieKid Please ask a new question for this problem.
@NewbieKid Since you are concatenating all of the grid's rows and columns into a single string in the db, you are going to have to split that db string into rows using sLineBreak as the delimiter, and then split each row into columns using | as the delimiter. split() returns an array, save it to a local variable, and then loop through it as needed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.