I think I see the difference. I was thinking the stringgrid used a TStringlist for storage and "savetofile" but it may be different. my code looks like this without the try..finally and getdata stuff:
...
var tstr:TStringlist;
str:string
begin
tstr := Tstringlist.create();
tstr.add(HeaderString); // := 'Var1,Var2,Var3,Var4';
...
loop
str := format('%d,%d,%d,%d',[v1,v2,v3,v4]);
tstr.add(str); // simple
------ or to add another Tstringlist ---
tstr.addstrings(TstrLineOfData);
----
endofloop
tstr.savetofile(CVS_filename);
tstr.free;
end;
sometimes I use something like..
str:= timestr + ',' + tstrLine.commatext;
Tstr.add(str);
and I don't even change the tstr.delimiter or .delinitertext properties and I still get one line per .add() in the final file.
you may be able to transfer a line at a time from the grid to a tstringlist or someone may answer your original question