Textový súbor a StringGrid

Textové súbory TEXT

Súbor = postupnosť (sekvencia) prvkov rovnakého typu, zaujímavé sú postupnosti znakov, t.j. textové súbory + špeciálne
znaky <Eoln> a <Eof>. Všetky informácie sú v textovom súbore zapísané ako ASCII znaky.
          vstupný súbor -- len čítať pripravené informácie
          výstupný súbor -- len zapisovať, na koniec súboru!
          do textového súboru sa nedá aj zapisovať aj súčasne z neho čítať

Ako pracujeme s textovým súborom
     deklarovanie premennej typu textový súbor:
          var t:TextFile; // premenná t je typu textový súbor
     priradenie fyzického súboru najčastejšie na disku:
          AssignFile(t,'meno_súboru');
     otvorenie súboru
          buď na čítanie (musí už existovať):
          Reset(t);
          alebo zápis (ak už existuje, tak sa najprv vyprázdni):
          Rewrite(t);
     práca so súborom, t.j. samotné čítanie alebo zapisovanie:
          read(t,...); readln(t,...);
          write(t,...); writeln(t,...);
     zatvorenie súboru, t.j. ukončenie práce so súborom:
          CloseFile(t);
     textový súbor = postupnosť riadkov (aj prázdna) ukončená značkou <Eof>
     pričom riadok textového súboru = postupnosť znakov (aj prázdna) ukončená <Eoln>

Vytvorme súbor

! Začnime novou aplikáciou v Delphi -- File -> New Application. Potom si v tejto aplikácii pripravme nejaký textový súbor File -> New a z rôznych možností, ktoré nám Delphi ponúkajú vyberme teraz Text. Ďalej si doň pripravme údaje, napr. mená detí niektorej vašej triedy spolu s ich známkami z nejakého predmetu, ktorý ich učíte.
Súbor nech má nasledujúcu štruktúru:
v prvom riadku súboru nech je priezvisko, v druhom meno žiaka a v treťom jeho známka, štvrtý riadok je znovu priezvisko
ďalšieho žiaka, atď.
Napr.
Kalamajka
Jan
3
Drobny
Michal
1
...

! Zapíšme tento súbor File -> Save (nezabudnite, že do nového adresára) napr. ako mena.txt.



Zobrazme súbor do tabuľky

Teraz chceme vidieť tento súbor v nejakej prijateľnej podobe na obrazovke. Použijeme na to ďalší komponent z palety komponentov Additional -- StringGrid

Novovyrobená tabuľka má

Ďalej do formuláru položme ešte tlačidlo -- Button z palety Standard a naprogramujeme načítanie textového súboru mena.txt do tabuľky -- keďže sme informácie uložili po riadkoch, je čítanie jednoduché...
 
procedure TForm1.Button1Click(Sender: TObject);
var t:TextFile;
    s:string;
    n,i:integer;
begin
  AssignFile(t,'mena.txt'); Reset(t);
  while not eof(t) do
    begin
      for i:=1 to 3 do
        with StringGrid1 do
          begin
             n:=RowCount-1;
             readln(t,s);
             Cells[i-1,n]:=s;
          end;
        StringGrid1.RowCount:=StringGrid1.RowCount+1;
    end;
  CloseFile(t);
end;

! Vyskúšajte projekt.



Menu v aplikácii

Tabuľku natiahneme na maximálny rozmer okna (t.j. v Objektovom inšpektore Align nastavíme na alClient) -- pri naťahovaní celého okna sa naťahuje celá tabuľka. Tiež zrušíme tlačidlo (jeho procedúru zatiaľ nemažeme -- použijeme ju neskôr). Ďalej zapneme (v Objektovom inšpektore property Options) goColSizing na True (aby sa dalo za behu meniť šírku stĺpcov) aj goRowSelect na True (aby sa vždy automaticky oselektoval celý riadok a nie iba niektorá položka)

Aby sa v tomto prostredí dobre pracovalo a aby sme mohli načítavať aj iné súbory, zadefinujme hlavné menu (položka MainMenu v palete komponentov Standard) s položkami: Otvor a Koniec.

Komponent položíme do formuláru a dvojklikneme naň. Otvorí sa nám okno, v ktorom môžeme pomenovávať a pridávať nové položky menu, keď klikneme pravým tlačidlom, môžeme definovať položky:

Pridajte položku menu Subor a jeho položky Otvor a Koniec -- mená im zmeňte v Objektovom inšpektore.
Po skončení definície sa objavia vo formulári:



Dialóg na otvorenie súboru

Aby sme súbor nemuseli čítať z konštantného mena.txt, ale aby po kliknutí na položku menu Otvor otvoril štandardný dialóg na výber súboru, tzv. OpenDialog, dáme do formuláru a palety komponentov Dialogs komponent OpenDialog.
Nastavme niektoré jeho property v Objektovom inšpektore:

OpenDialog je neviditeľný komponent a po spustení projektu nevieme vôbec o jeho existencii. Môžeme sa však naň odvolávať pri programovaní. Pozrite si v štandardnom helpe Delphi jeho metódu Execute a property FileName, ktoré využijeme pri ďalšom programovaní. Tiež si pozrite procedúru GetDir -- napíšte jej meno niekde do Delphi a stlačte Ctrl+F1 -- Delphi otvoria help tak, aby ste videli informácie o príslušnej procedúre.

! Naprogramujme správanie programu po výbere položky Otvor v menu Subor:
Vo formulári klikneme na menu Subor a jeho položku Otvor. Delphi nás prepnú do editovacieho okna Unitu a môžeme naprogramovať metódu Otvor. Väčšinou to bude to, čo sme predtým robili na stlačenie tlačidla -- t.j. načítanie súboru do tabuľky StringGrid, ale teraz použijeme dialóg na otvorenie štandardného výberu súboru:
 
procedure TForm1.OtvorClick(Sender: TObject);
var t:TextFile;
    s:string;
    n,i:integer;
begin
  GetDir(0,s);
  OpenDialog1.InitialDir := s;
  if not OpenDialog1.Execute then exit;
  AssignFile(t,OpenDialog1.Filename); 
  Reset(t);
  while not eof(t) do
    begin
      ... // to čo tu bolo aj predtým na stlačenie tlačidla
    end;
end;

Ešte naprogramujme ukončenie aplikácie po výbere položky Koniec v menu Subor -- opäť sa vo formulári nastavme na túto položku a v editovacom okne napíšme:
 
procedure TForm1.Koniec1Click(Sender: TObject);
begin
  Close;
end;

! Vyskúšajte projekt.



Úpravy projektu

Tento projekt je základom pre všetky projekty, v ktorých potrebujeme pracovať so súbormi.
Postupne ho dokončujme a programujme nasledujúce možnosti:

zmeny položiek v tabuľke

napr. ak nastavíme property goRowSelect na False a goEditing na True, môžeme po spustení programu priamo editovať jednotlivé položky
zapisovanie súboru
podobne ako existuje OpenDialog, existuje aj štandardný dialóg na zápis súboru -- SaveDialog. Vložte ho do formulára, podobne mu nastavte property ako pre OpenDialog a naprogramujte zapísanie do súboru. Nezabudnite využiť jeho metódu Execute.
vkladanie nových položiek a mazanie položiek
využite udaloť OnKeyDown tabuľky -- v objektovom inšpektore záložka Events. Po dvojkliknutí na ňu sa otvorí editovacie okno a v pripravenej metóde môžete reagovať na udalosť. Pomôcka -- stlačenie klávesu Ins dáva hodnotu Key=45, kláves Del dáva hodnotu 46. Pomocou týchto dvoch klávesov naprogramujte pridanie riadku a zmazanie posledného riadku -- v tabuľke vždy nechajte horný fixný riadok a jeden voľný riadok.


Zhrnutie komponentu StringGrid

     užitočné stavové premenné (property)
          RowCount, ColCount, FixedCols, FixedRows
          Cells[aCol,aRow], Cols[Index], Rows[Index]
          DefaultRowHeight, DefaultRowHeight - počiatočná veľkosť políčok
          ColWidths[Index], RowHeights[Index] - momentálna veľkosť políčok - počas behu možno meniť
          počas dizajnu: ScrollBars, Align
          Width, Height
          Canvas
          Options: set of (goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine,
          goRangeSelect, goDrawFocusSelected, goRowSizing, goColSizing, goRowMoving,
          goColMoving, goEditing, goTabs, goRowSelect, goAlwaysShowEditor, goThumbTracking);
     metódy
          MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
     udalosti
          OnMouseDown - parametre X a Y sú myšacie súradnice => bude treba použiť MouseToCell(...)
          OnSelectCell - parametre: (Sender: TObject; Col, Row: Longint; var CanSelect: Boolean)
          OnDrawCell - parametre: (Sender: TObject; Col, Row: Longint; Rect: TRect; State: TGridDrawState)
               kde TGridDrawState = set of (gdSelected, gdFocused, gdFixed);
               napr.
             StringGrid1.Canvas.TextRect(Rect,Rect.Left,Rect.Top,StringGrid1.Cells[Col,Row]);
               alebo aj StringGrid1.Canvas.DrawFocusRect(Rect);



Použitie tabuľkového komponentu StringGrid


Súbor vznikol na základe prednášok Andreja Blaha