Programowanie w języku Delphi » FAQ

Jak zapisać i odczytać StringGrida

Nie jestem pewien czy to przypadkiem już nie było ale...

Dopisane po przeczytaniu komentarza Milki:
Zapisywałem zwykle StringGridy w plikach tekstowych wstawiając znaczniki kolejnych komórek w wierszach, ale razu jednego musiałem szyfrować zapisy(tutaj nie pokazuję jak) i stąd taki sposób  pozwalający na zapis zamiast stringów np ciągu liczb z dodatkowymi wartościami dopisywanymi do każdej komórki. Poza tym metoda pokazana przez Milke ma jedną zasadniczą wadę - zapisuje puste komórki i przy dużych tabelach nie zawsze wypełnianych przez użytkownika powstają niepotrzebnie duże pliki. Należałoby wstawiać znaczniki definiujące komórkę i pomijać zapis komórek pustych. Każde takie definiowanie ogranicza zakres dozwolonych dla użytkownika znaków (musimy coś wpisać jakieś #, ^ czy $). Zapisując StringGridy w plikach tekstowych stosowałem zasadę wiersz tabeli - wiersz w pliku.

zapisywanie i czytanie StringGrida, dir_path - adres katalogu, nazwa pliku jest tworzona
na podstawie StringGrid.Name

Nie wiem co z ukośnikami - nie są wyświetlane, wpisałem ukosnik

procedure ZapiszSG(SG:TStringGrid;dir_path:string);
type
   Twpis_f=array of Char;
var
   SG_file_inf : record
                 kolumna:Integer;
                 wiersz:Integer;
                 size:Integer;
                 end;
   plik:File;
   aCol,aRow:Integer;
   wpis_SG:string;
   wpis_f:Twpis_f;
 
   function String_arrayChar(tekst:string):Twpis_f;
   var
      i:Integer;
   begin
      SetLength(Result,Length(tekst));
      for i:=0 to High(Result) do
      Result[i]:=tekst[i+1];
   end;
 
begin
   AssignFile(plik,dir_path+'ukosnik'+SG.Name+'.sgf');
   Rewrite(plik,1);
   try
      for aCol:=0 to SG.ColCount-1 do
      for aRow:=0 to SG.RowCount-1 do
      begin
         wpis_SG:=SG.Cells[aCol,aRow];
         if wpis_SG<>'' then
         begin
            wpis_f:=String_arrayChar(wpis_SG);
            SG_file_inf.kolumna:=aCol;
            SG_file_inf.wiersz:=aRow;
            SG_file_inf.size:=Length(wpis_SG);
            BlockWrite(plik,SG_file_inf,SizeOf(SG_file_inf));
            BlockWrite(plik,wpis_f[0],SG_file_inf.size);
         end;
      end;
   finally
      CloseFile(plik);
   end;
end;
 
 
procedure CzytajSG(SG:TStringGrid;dir_path:string);
type
   Twpis_f=array of Char;
var
   SG_file_inf : record
                 kolumna:Integer;
                 wiersz:Integer;
                 size:Integer;
                 end;
   plik:File;
   aCol,aRow,el:Integer;
   wpis_SG:string;
   wpis_f:Twpis_f;
 
   function ArrayChar_string(tekst:Twpis_f):string;
   var
      i:Integer;
   begin
      Result:='';
      for i:=0 to High(tekst) do
      Result:=Result+tekst[i];
   end;
 
begin
   for aCol:=0 to SG.ColCount-1 do
   for aRow:=0 to SG.RowCount-1 do
   SG.Cells[aCol,aRow]:='';
 
   AssignFile(plik,dir_path+'ukosnik'+SG.Name+'.sgf');
   Reset(plik,1);
   try
      while not Eof(plik) do
      begin
         BlockRead(plik,SG_file_inf,SizeOf(SG_file_inf));
         SetLength(wpis_f,SG_file_inf.size);
         BlockRead(plik,wpis_f[0],SG_file_inf.size);
         if SG_file_inf.kolumna>SG.ColCount-1 then SG.ColCount:=SG_file_inf.kolumna+1;
         if SG_file_inf.wiersz>SG.RowCount-1 then SG.RowCount:=SG_file_inf.wiersz+1;
         SG.Cells[SG_file_inf.kolumna,SG_file_inf.wiersz]:=ArrayChar_string(wpis_f);
      end;
   finally
      CloseFile(plik);
   end;
end;

2 komentarze

AklimX 2004-09-16 19:14

mój kodzik

procedure TForm1.Button1Click(Sender: TObject);
var tf:TextFile;
    c, cc :word;
begin
  AssignFile(tf, file_name);
  rewrite(tf);
  writeln(tf, '#');
  for c:=0 to StringGrid1.RowCount-1 do
  begin
    for cc:=0 to StringGrid1.ColCount-1 do
      if stringGrid1.Cells[cc, c] = '' then Writeln(tf, ' ') else
        Writeln(tf, stringGrid1.Cells[cc, c]);
    writeln(tf, '#');
  end;
  closefile(tf);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var tf:TextFile;
  tab:array[0..100] of string;
  i: integer;
  row,col:integer;
 
begin
  i:= 0; row:= -1; col:= 0;
  if FileExists(file_name) then
  begin
    AssignFile(tf, file_name);
    reset(tf);
    while not Eof(tf) do
    begin
      Readln(tf, tab[i]);
      if tab[col][1] = '#' then // jeżeli nowy rząd
      begin
       row:= row+1;           // zwiększ licznik
       col:= 0;
      end else
      begin
        StringGrid1.Cells[col-1,row]:= tab[i];
      end;
      col:=col+1;
     i:=i+1;
    end; // while not eof
    closefile(tf);
  end
  else
  ShowMessage('Nie znalazłem pliku !');
 
end;

AklimX 2004-10-19 06:14

czy zapisywanie spacji jest aż takim problemem ? - po kompresji Huffmanem (albo zip czy rar) plik nie będzie miał wielkich rozmiarów