Órarendkészítés (TFOR)
Gépi tantárgyfelosztás- és órarendkészítő
program
Alapvetések
Osztályszintű
óraterv: egy olyan táblázat, amely
azt tartalmazza, hogy egy adott osztálynak, valamely tantárgyból, hetente hány
órája van. Minden tantárgynak annyi sora van a táblázatban, ahány csoportra bontva
tartják. (Oszlopai az osztályok, sorai a tantárgyak, tartalma a tantárgy heti
óraszáma.)
Osztály tantárgyfelosztás: egy olyan táblázat, mely minden osztályban, minden
tantárgyhoz megmutatja, hogy melyik pedagógus tanítja. Minden tantárgynak annyi
sora van a táblázatban, ahány csoportra bontva tartják. (Oszlopai az osztályok,
sorai a tantárgyak, tartalma a pedagógus.)
Pedagógus
órarend: olyan táblázat, mely a hét minden napjára és órájára
megmutatja, hogy az adott pedagógus milyen tantárgyat, melyik osztálynak,
melyik tanteremben tanítja. (Oszlopai a hét napjai és azon belül a napok órái,
sorai az pedagógusok, tartalma a tantárgy, az osztály és a tanterem.)
Osztályórarend: olyan táblázat, mely a hét minden napjára és órájára
megmutatja, hogy az adott osztályban milyen tantárgyat, ki vagy kik tanítanak,
melyik tanteremben, illetve tantermekben. (Oszlopai a hét napjai és azon belül
a napok órái, sorai az osztályok, tartalma a tantárgy, a pedagógus és a
tanterem. Minden osztálynak annyi sora van, amennyi a csoportbontásban
résztvevő pedagógusok száma.)
Tanteremórarend:
olyan táblázat, mely a hét minden napjára és órájára megmutatja, hogy az adott
tanteremben milyen tantárgyat, melyik osztálynak, melyik pedagógus tanítja.
(Oszlopai a hét napjai és azon belül a napok órái, sorai a tantermek, tartalma
a tantárgy, az osztály és a pedagógus.)
Elemzések:
A fentebbi leírásokkal kapcsolatban a következő megállapítások tehetők.
1.) Az Osztályszintű óraterv és az Osztály tantárgyfelosztás nagyon
hasonlít egymásra. Az óraterv kiegészíthető az óraszám mellett annak a
pedagógusnak a nevével (illetve tömbindexével), aki azt a tantárgyat a kérdéses
osztályban tanítja. A programban ezt az összekapcsolást alkalmazni is fogjuk.
2.) Ha az órarendek gépi feltöltésekor, az egyszerűség kedvéért, ragaszkodunk
ahhoz, hogy valamely táblázatban egy elem tulajdonságait csak egy sor
tartalmazza, akkor ilyen értelemben csak a Pedagógus órarend jöhet számításba az
órarendkészítésnek ebben a fázisban. Ugyanis az Osztályórarendek egy osztályhoz
több sort is tartalmazhatnak a csoportbontás miatt. A Teremórarendekkel meg az
a bökkenő, hogy szintén a csoportbontások miatt, bizonyos órákhoz csak a
feltöltés végén lehet tantermet rendelni, hiszen a feltöltés elején még nem
rögzíthető minden bontott órára az, hogy melyik teremben kell tartani. Ehhez
ugyanis minden szaktantermi órának ismerni kellene az időpontját, hiszen ezek
biztosítják a szabad tantermeket a bontások számára. (Ilyenek: a testnevelés,
ének, rajz, informatika, nyelvi labor órái, gyakorlati foglalkozások, stb.)
Márpedig úgy órarendet generálni, hogy nem biztos az, hogy a kiválasztott
teremben és időpontban egy adott osztálynak egyáltalán lehet-e órája vagy nem,
nem lehet.
Következmény: marad az automatikus generálás idejére a Pedagógus
órarend nézet.
Csoportbontás: Az eredményesebb oktató-nevelő munka érdekében
gyakran előfordul, hogy az osztálykereteket megbontva, egy-egy tantárgyat
kisebb csoportokban tanítunk. Ezekre az időpontokra az osztálykeretek megszűnnek,
hiszen tanulói több pedagógushoz tartoznak. Ebben a programban csak a két
legegyszerűbb lehetőség áll rendelkezésre.
Egyik lehetőség az, hogy egy adott tantárgy tanítási
idejére két csoportot hozunk létre az osztályból, melynek két pedagógus és két
teremigénye lesz. Bármely tantárggyal kapcsolatban megtehetjük például, hogy
kezdő és haladó csoportokra bontjuk az osztályt, így alakítva ki két csoportot.
De egyszerűen csak azért is bonthatjuk egy tantárgyból, például matematikából
ketté az osztályt, hogy kisebb csoportokban eredményesebben dolgozhassunk. A
testneveléssel kapcsolatban pedig majdnem törvényszerű, hogy a lányok és fiúk
külön csoportot alkossanak, már csak anatómiai megfontolások miatt is.
A másik csoportbontási lehetőség az, amikor egy adott
órában az osztály egyik felének például angol, a másik felének német órát
tartunk, azaz két különböző tantárgy óráit. Az ilyen bontás alapja lehet
például az, hogy az osztályfőnök angol szakos, és szeretné az osztály minden
tanulóját tanítani. Természetesen bármely két tantárgy, aminek a heti óraszáma
azonos, így párba állítható.
Időpont
összevonás: Erre ebben a
programban nincs lehetőség, de a teljesség kedvéért említést teszek róla.
Pontosabban az alapértelmezett időpont összevonás a csoportbontás kezelésében
megvalósul, vagyis a tantárgyfelosztásban lévő két tanítási tételt egy
időpontban kell és lehet megtartani. Az általános időpont összevonás azt
jelenti, hogy a tantárgyfelosztás bármely két, esetleg több tételét is
összevonjuk, egy időpontban tartjuk. Erre tehát ez a program nem alkalmas.
Az összevonásra több ok miatt is szükség lehet. Ez
első tehát az említett egyszerű csoportbontás. A másik a fakultáció. A
tantárgyfelosztásban például szerepelhet öt tanítási tétel is a harmadik
évfolyamon, melyet egy időpontban, a teljes évfolyamról származó tanulók
részére szervezünk. Hasonló megoldásra van szükség, ha a testnevelési órákon a
nemek aránya miatt egy teljes csoportot csak több osztályból lehet összehozni,
akkor is szükség lehet időpont összevonásra (például: 1.a testnevelés lány, 1.b
testnevelés lány és 1.ab testnevelés fiú formában). A következő igény akkor
adódik időpont összevonásra, amikor az érintett tételeknek nincs is közük
egymáshoz tanulói szinten, de ha például egy osztályban nyelvi bontás van, és
ezért plusz tanteremigény jelentkezik, akkor legyen egy másik osztályban
testnevelés vagy informatika óra, a teremgondok enyhítése miatt (az informatika
teremben, vagy sportcsarnokban ugyanis nem lehet más órát tartani, mint informatikát,
illetve testnevelést). Az időpont összevonás további gondokat vet fel abban az
esetben, ha valódi csoportokkal dolgozik, de kevesebb pedagógussal, mint
amennyi osztályból érkeznek a tanulók. Ilyenek lehetnek például a gyakorlati
foglalkozások. Ezt az esetet meg kell oldani a programban kódolás szintjén,
vagyis nyilván kell tartani azt is, hogy mely osztályokba tartoznak a csoport
tanulói.
A feladat
Készítsünk olyan
programot, amely az iskolai tantárgyfelosztás és órarendek elkészítésére
alkalmas.
Programspecifikáció.
1.
Általános követelmények.
A
program kezeljen:
-
osztályokat;
-
tantárgyakat;
-
osztályszintű óraterveket;
-
pedagógusokat és
-
tantermeket.
Input,
output:
Az
adatokat tipizált lemezes állományban tárolja. Indításkor az adatokat lemezről
automatikusan töltse be, a programból való kilépéskor opcionálisan mentse ki.
Lehessen tetszőleges alapadatokkal feltölteni a kezelhető adatállományokat.
Minden adatbevitelre könnyen kezelhető beviteli felület álljon rendelkezésre. A
tantárgyfelosztás és órarend készítése az alapadatok bevitele után csak
hozzárendelésekkel valósuljon meg.
- legyen
alkalmas tantárgyfelosztás készítésére, annak iskolai szintű, pedagógusok
szerinti összesítésére és Excel táblázatba való mentésére;
-
lehessen tantárgyfelosztást lekérdezni tantárgyak szerint is;
- legyen
alkalmas órarendkészítésre, ezen belül kézi és gépi feltöltésre;
-
az órarendkészítésben kezeljen csoportbontást, azaz egy tantárgyat két
pedagógus is taníthasson;
-
lehessen a pedagógusoknak tiltott órái (amikor nem tud órát tartani) és gépi
módosítás ellen védett (rögzített) órái;
-
lehessen osztályonként és azon belül naponként megadni az osztály számára
elfogadó időpontokat (az 1.-6. standard kiterjesztése);
-
lehessen az órarendet osztályonként, pedagógusonként, tantermenként és
tantárgyanként is Excel táblázatba menteni.
Nem
módosítható konstansok (a lemezes állomány rekordhosszát változtatja):
-
maximum heti 5 nap: NaSz=5;
-
maximum napi 10 óra: NOSz=10;
-
maximum 50 óra hetente: HOSz=NaSz*NOSz=50;
-
maximum 32 osztály: OMax=32;
-
maximum 64 pedagógus: PMax=64;
-
maximum 21 tantárgy: TMax=21;
-
maximum 64 tanterem: HMax=64;
Módosítható
konstansok:
-
napok jelölése: Nap=’HKSCP’;
-
párhuzamos osztályok száma egy évfolyamon: POSz=8;
-
pedagógusoknak heti maximum 26 óra: OSzM=26;
-
pedagógusok tanítási tételeinek maximuma: PTTM=32;
-
tiltott pedagógusóra kódja: Tilt=99;
-
kétórás tantárgy jelölő kódja: KetO=999;
-
a megengedett beírási időpont jele a pedagógus órarendben: Jel=’___’.
4.
Programkörnyezet, nyelvi megoldások:
-
a programot Delphi nyelven kell megírni;
-
mivel több beviteli és kezelő felületre van szükség, ezért MDI alkalmazást kell
használni;
-
a lemezes állományokra vonatkozó megkötés miatt, az adatszerkezet rekordokra
épüljön (ugyanis erről könnyebb átírni adatbázis alapúra).
Programterv
Név: |
Azonosító: |
Osztály |
Oszt |
Tantárgy |
Tant |
Pedagógus |
Peda |
Tanterem |
Hely |
2. Rekordleírás:
TTFOR:
TTFOR |
Mezőnév |
Tulajdonság |
Időpont neve |
INev |
St2 |
Osztály neve |
ONev |
St3 |
Osztály osztályfőnöke |
OOfo |
Word |
Osztály tanterme |
OHel |
Word |
Osztály óraterve |
OTer |
Array[0..OMax,0..TMax,0..6]
Of Word |
Osztály lehetőségek |
OLeh |
Array[0..HOSz+1,0..2*OMax+1]
Of Word |
Tantárgy neve |
TNev |
St3 |
Tantárgy lehetőségek |
TLeh |
Array[0..HOSz+1,0..TMax+1]
Of Word |
Pedagógus neve |
PNev |
St36 |
Pedagógus rövidítése |
PRov |
St3 |
Pedagógus beosztása |
PBeo |
St3 |
Pedagógus kötelező-óraszáma |
PKot |
Word |
Pedagógus nem óratervi órái |
PNOT |
Word |
Pedagógus órarend |
POra |
Array[0..HOSz+1,0..PMax+1,0..4]
Of Word |
Tanterem neve |
HNev |
St3 |
Tanterem lehetőség |
HLeh |
Array[0..HOSz+1,0..HMax+1]
Of Word |
Az alkalmazott
hivatkozások:
St2: 2 karakter hosszú
szöveg.
St3: 3 karakter hosszú
szöveg;
St36: 36 karakter hosszú
szöveg.
Megjegyzések:
-
A rekordnevek első T betűje a Type szokásos konvencióját jelenti.
-
Az óraterv deklarációjában (OTer: Array[0..OMax,0..TMax,1..6] Of Word) az 1..6
index a kettős csoportbontást szolgálja: két óraszám, két pedagógus és két
tanterem (mint a tanítási tétel tanterme, ha ezt meg szeretnénk adni).
-
Minden névre hárombetűs rövidítéseket használunk, kivéve az időpontok neveit:
H0,H1,H2..H9,K0,K1,K2… P8,P9, melyeket nem módosíthatjuk.
-
A tantárgyneveket az Óratervi lapon, a pedagógusok nevének rövidítését a Pedagógus
órarenden, az osztályok nevét az Osztályórarenden, míg tantermek nevét a Tanteremórarenden
módosíthatjuk.
-
Az osztályok osztályfőnökét és az osztály számára engedélyezett (lehetséges)
időpontokat az Osztályórarend lapon beállíthatjuk.
-
Az osztályok tantermét és a tanítási tételek tantermét (szaktantermét) az
Óratervi lapon beállíthatjuk.
-
A pedagógusok teljes nevét, nevének rövidítését, beosztását, túlóráinak számát,
nem óratervi óráinak számát egy külön lapon beállíthatjuk, melyen különböző
kimentek készítésére is lehetőség van Html és XLS formátumban.
A Formok várható listája:
fmTFOR - az alkalmazás
főformja;
fmAdat - az adatállomány
leírása;
fmModul - modulgyűjtemény;
fmOTer - az óraterv beviteli
felülete;
fmPOR - a pedagógus órarend
és tiltások bevitele, gépi órarendkészítés;
fmOOR - az osztályórarend
lekérdezése, tiltások bevitele;
fmHOR - a teremórarend
lekérdezése, tiltások bevitele.
fmMentMint – pedagógusok
további adatai, a tantárgyfelosztás és az órarendek Html és XLS formátumban
való nyomtatása.
Kódolás (1)
A kódolás első lépéseként hozzunk létre egy mappát
projektünk számára (TFOR). Delphiben hozzuk létre alkalmazásunk főformját, az
fmTFOR-t. Tulajdonságát FormStyle tulajdonságát állítsuk fsMDIForm-ra.
Következő lépésben hozzuk létre mind a további 7 formot, melyek FormStyle
tulajdonságát állítsuk fsMDIChild-re. Minden form WindowState tulajdonsága
legyen wsMaximized. Az fmAdat és a fmModul kivételével mindegyikre helyezzünk
el egy, a tartalmát leíró szöveget egy-egy Label elemen, és egy Kilépés
feliratú nyomógombot. A nyomógomb Click határára zárja a formot: Close
paranccsal. Minden utóbbi form onClose eseményébe írjuk be: Action:= caFree.
Ezzel a formok elő vannak készítve az MDI kezelésre.
Következő lépésként helyezzünk a főform-ra egy főmenüt
és a menüit alakítsuk ki a következő screenshot szerint:
A menük és a MDIChild formok összekapcsolását a
menüpontok OnClick eseményének megírásával hozzuk létre (a form létrehozása és
megjelenítése). A program indítás utáni képernyője:
A főform
listája:
unit UTFOR;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms,
UAdat, UModul, UOTer, UPOR, UOOR, UHOR, UMentMint,
Dialogs, Menus, StdCtrls;
type
TfmTFOR = class(TForm)
mmTFOR: TMainMenu;
miTFOR: TMenuItem;
miOTer: TMenuItem;
miPOR: TMenuItem;
miOOR: TMenuItem;
miHOR: TMenuItem;
miNo1: TMenuItem;
miExitNoSave: TMenuItem;
miExit: TMenuItem;
miMentes: TMenuItem;
miMentesMint: TMenuItem;
miNo2: TMenuItem;
procedure miOTerClick(Sender: TObject);
procedure miPORClick(Sender: TObject);
procedure miOORClick(Sender: TObject);
procedure miHORClick(Sender: TObject);
procedure miExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure miExitNoSaveClick(Sender: TObject);
procedure miMentesClick(Sender: TObject);
procedure miMentesMintClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmTFOR: TfmTFOR;
implementation
{$R *.dfm}
procedure TfmTFOR.miMentesClick(Sender: TObject);
begin
Lemezre;
end;
procedure TfmTFOR.miExitNoSaveClick(Sender: TObject);
begin
Close;
end;
procedure TfmTFOR.miExitClick(Sender: TObject);
begin
Lemezre;
Close;
end;
procedure TfmTFOR.miOTerClick(Sender: TObject);
begin
fmOTer:= TfmOTer.Create(Self);
fmOTer.Show;
end;
procedure TfmTFOR.miPORClick(Sender: TObject);
begin
fmPOR:= TfmPOR.Create(Self);
fmPOR.Show;
end;
procedure TfmTFOR.miOORClick(Sender: TObject);
begin
fmOOR:= TfmOOR.Create(Self);
fmOOR.Show;
end;
procedure TfmTFOR.miHORClick(Sender: TObject);
begin
fmHOR:= TfmHOR.Create(Self);
fmHOR.Show;
end;
procedure TfmTFOR.miMentesMintClick(Sender: TObject);
begin
fmMentMint:= TfmMentMint.Create(Self);
fmMentMint.Show;
end;
procedure TfmTFOR.FormCreate(Sender: TObject);
begin
Randomize; DNev:= 'TFOR.tfo'; Lemezrol;
end;
end.
Kódolás (2)
Ebben a szakaszban az adatok tárolásával
ismerkedhetünk meg. Egy minden Unitban használatba veendő Unitba helyeztük el
az adatok leírását, így globális adatokként használja őket a program. A program
korlátait jelentő konstansok is itt foglalnak helyet. A program minden adatát
egyetlen, az ATFOR nevű rekordban
tároljuk, mely a teljes lemezes adatállományt jelenti.
Az
OTer mező tömbindexeinek jelentése:
0..OMax: osztály index
0..TMax: tantárgy index
0:
használaton kívüli
1:
a tantárgy első csoportjának (vagy az egyetlen csoportjának = teljes osztály) az
óraszáma
2:
a tantárgy második csoportjának (mely opcionális) az óraszáma
3:
a tantárgy első csoportjának (vagy az egyetlen csoportjának = teljes osztály) a
pedagógusa
4:
a tantárgy második csoportjának (mely opcionális) a pedagógusa
5:
az első csoport tanterme (opcionális, mert ha nincs megadva, akkor az osztály
osztályterme)
6:
a második csoport tanterme (opcionális, mert ha nincs megadva, akkor valamelyik
üres terem)
A OLeh mező
tömbindexeinek jelentése:
0..HOSz+1: a hét időpontjai
0..2*OMax+1: az
osztályórarend sorai
0 érték: nem lehet óra
1 érték: lehet óra
A TLeh mező
tömbindexeinek jelentése:
0..HOSz+1: a hét időpontjai
0..TMax+1: tantárgyak
0 érték: nem lehet óra
1 érték: lehet óra
A POra mező tömbindexeinek jelentése:
0: használaton kívüli
1: a tanítási óra tantárgya
2: a tanítási óra osztálya
3: a tanítási óra tanterme
4: az óra rögzítésének
minősége:
0:
nincs óra
1:
kézzel rögzített, a gépi betöltő nem módosíthatja
2:
gépi betöltővel rögzített, a gépi betöltő módosíthatja
A HLeh mező
tömbindexeinek jelentése:
0..HOSz+1: a hét időpontjai
0..HMax+1: tantárgyak
0 érték: nem lehet óra
1 érték: lehet óra
Névhivatkozások:
INev: időpont neve (H0-tól
P9-ig, mely nem változtatható meg)
ONev: osztályok neve
OOfo: osztály osztályfőnöke
(pontosabban annak tömbindexe)
OHel: az osztály tanterme
(pontosabban annak tömbindexe)
TNev: tantárgyak neve
PNev: pedagógusok neve
PRov: pedagógus nevének
rövidítése
PBeo: pedagógus beosztása
PKot: pedagógus
kötelező-óraszáma
PNOT: pedagógus nem óratervi
órái
HNev: tantermek neve
Az UAdat Unit listája:
unit UAdat;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, Dialogs;
Const
//nem módosíthatók, rekordhossz megváltozik, a lemezes állomány nem lesz
//olvasható
OMax=32;
PMax=64;
TMax=21;
HMax=64;
NaSz=5;
NOSz=10;
HOSz=NaSz*NOSz;
//módosíthatók:
Nap='HKSCP';
POSz=8;
OSzM=26;
PTTM=32;
Tilt=99;
KetO=999;
Jel='__';
type
St2=String[2];
St3=String[3];
St12=String[12];
St36=String[36];
TfmAdat = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
TTFOR=Record
INev: Array[0..HOSz] Of St2;
ONev: Array[0..OMax] Of St3;
OOfo: Array[0..OMax] Of Word;
OHel: Array[0..OMax] Of Word;
OTer: Array[0..OMax,0..TMax,0..6] Of Word;
//OTer: 1:órasz(1), 2:órasz(2), 3:peda(1), 4:peda(2), 5:terem(1), 6:terem(2)
OLeh: Array[0..HOSz+1,0..2*OMax+1] Of Word;
TNev: Array[0..TMax] Of St3;
TLeh: Array[0..HOSz+1,0..TMax+1] Of Word;
PNev: Array[0..PMax] Of St36;
PRov: Array[0..PMax] Of St3;
PBeo: Array[0..PMax] Of St3;
PKot: Array[0..PMax] Of Word;
PNOT: Array[0..PMax] Of Word;
POra: Array[0..HOSz+1,0..PMax+1,0..4] Of Word;
//POra: 1:tant, 2:oszt, 3:hely, 4:nincs(0)/kézi(1)/gépi(2)
HNev: Array[0..HMax] Of St3;
HLeh: Array[0..HOSz+1,0..HMax+1] Of Word;
End;
var
fmAdat: TfmAdat;
ACol, ARow: Integer;
DNev: String;
FTFOR: File Of TTFOR;
FText: Text;
PHOSz: Array[0..PMax+1] Of Word;
ATFOR: TTFOR;
AIdop, ATant, AOszt, APeda, AHely, MPeda: Word;
NNev: Array[1..5] Of St12=('Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek');
implementation
{$R *.dfm}
end.
Az alapértelmezett adatok feltöltésére, adatmentésre
és adatbetöltésre egy külön Unitot hozunk létre. Ide helyezzük a továbbiakban
esetleg szükséges globális adatokon végzett műveletek, eljárások moduljait is.
Ennek a Unitnak a neve UModul, a
listája pedig:
unit UModul;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, UAdat, Dialogs;
type
TfmModul = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
Procedure Alap;
Function UpONev(Nev: St3): St3;
Function VoltOfo(P: Word): Boolean;
Procedure Lemezre;
Procedure Lemezrol;
Function INevToInd(Nev: St2): Word;
Function ONevToInd(Nev: St3): Word;
Function TNevToInd(Nev: St3): Word;
Function PRovToInd(Nev: St3): Word;
Function TTetToHely(O,T: Word): Word;
Function UresHely(I,H: Word): Boolean;
Function PORBeirt(P,T,O: Word): Word;
Function MaRovid: St4;
var
fmModul: TfmModul;
implementation
{$R *.dfm}
Procedure Alap;
Var I, J, O, P, H: Word;
St: St2;
Begin
With ATFOR Do
Begin
INev[0]:= ''; For I:= 1 To NaSz Do For J:= 0 To NOSz-1 Do
INev[(I-1)*NOSz+J+1]:= Nap[I]+IntToStr(J);
With ATFOR Do
Begin
ONev[0]:= ''; For O:= 1 To OMax Do
ONev[O]:= IntToStr(((O-1) Div POSz+1))+'.'+Chr(96+(O-1) Mod POSz+1);
End;
TNev[ 0]:= '-'; TNev[ 1]:= 'ofő'; TNev[ 2]:= 'mgy'; TNev[ 3]:= 'tör';
TNev[ 4]:= 'tis'; TNev[ 5]:= 'eti'; TNev[ 6]:= 'fil'; TNev[ 7]:= 'an1';
TNev[ 8]:= 'an2'; TNev[ 9]:= 'fra'; TNev[10]:= 'mat'; TNev[11]:= 'inf';
TNev[12]:= 'fiz'; TNev[13]:= 'kém'; TNev[14]:= 'bio'; TNev[15]:= 'föl';
TNev[16]:= 'éne'; TNev[17]:= 'raj'; TNev[18]:= 'tes'; TNev[19]:= 'tán';
TNev[20]:= 'méd'; TNev[21]:= 'szv';
PRov[0]:= '-'; For P:= 1 To PMax Do
PRov[P]:= Chr((P-1) Div 26+65)+Chr((P-1) Mod 26+65)+Chr(97+Random(26));
HNev[0]:= '-'; For I:= 1 To 2 Do For J:= 1 To 32 Do
Begin
St:= IntToStr(J); If J<10 Then St:= '0'+St;
HNev[(I-1)*32+J]:= Chr(64+I)+St;
End;
For I:= 0 To HOSz+1 Do For O:= 0 To 2*OMax+1 Do
If I In [2..7,12..17,22..27,32..37,42..47] Then OLeh[I,O]:= 1
Else OLeh[I,O]:= 0;
For I:= 0 To HOSz+1 Do For H:= 0 To HMax+1 Do
If I In [2..7,12..17,22..27,32..37,42..47] Then HLeh[I,H]:= 1
Else HLeh[I,H]:= 0;
End;
End;
Function UpONev(Nev: St3): St3;
Var St: St3;
Begin
UpONev:= ''; If Nev='' Then Exit;
St:= Nev; St[3]:= UpCase(St[3]); UpONev:= St;
End;
Function VoltOfo(P: Word): Boolean;
Var O: Word;
Begin
VoltOfo:= False; If P=0 Then Exit;
With ATFOR Do
For O:= 1 To OMax Do If (OOfo[O]=P) Or (OTer[O,1,3]=P) Then
Begin VoltOfo:= True; Break End;
End;
Procedure Lemezre;
Begin
AssignFile(FTFOR,DNev); ReWrite(FTFOR);
Write(FTFOR,ATFOR);
CloseFile(FTFOR);
End;
Procedure Lemezrol;
Begin
AssignFile(FTFOR,DNev); {$I-}Reset(FTFOR){$I+};
If IOResult<>0 Then Begin ReWrite(FTFOR); Alap End Else Read(FTFOR,ATFOR);
CloseFile(FTFOR);
End;
Function INevToInd(Nev: St2): Word;
Var I: Word;
Begin
INevToInd:= 0; With ATFOR Do
For I:= 1 To HOSz Do If INev[I]=Nev Then Begin INevToInd:= I; Break End;
End;
Function ONevToInd(Nev: St3): Word;
Var O: Word;
Begin
ONevToInd:= 0; With ATFOR Do
For O:= 1 To OMax Do If ONev[O]=Nev Then Begin ONevToInd:= O; Break End;
End;
Function TNevToInd(Nev: St3): Word;
Var T: Word;
Begin
TNevToInd:= 0; With ATFOR Do
For T:= 1 To TMax Do If TNev[T]=Nev Then Begin TNevToInd:= T; Break End;
End;
Function PRovToInd(Nev: St3): Word;
Var P: Word;
Begin
PRovToInd:= 0; With ATFOR Do
For P:= 1 To PMax Do If PRov[P]=Nev Then Begin PRovToInd:= P; Break End;
End;
Function TTetToHely(O,T: Word): Word;
Var H: Word;
Begin
With ATFOR Do
Begin
H:= OTer[O,T,6];
If H=0 Then H:= OTer[O,T,5];
If H=0 Then H:= OHel[O];
End;
TTetToHely:= H;
End;
Function UresHely(I,H: Word): Boolean;
Var P: Word;
Begin
UresHely:= True;
With ATFOR Do For P:= 1 To PMax Do If POra[I,P,3]=H Then
Begin UresHely:= False; Break End;
End;
Function PORBeirt(P,T,O: Word): Word;
Var I, N: Word;
Begin
N:= 0;
With ATFOR Do For I:= 1 To HOSz Do
If (POra[I,P,1]=T) And (POra[I,P,2]=O) Then Inc(N);
PORBeirt:= N;
End;
Function MaRovid: St4;
Begin
MaRovid:= Copy(DateToStr(Now),6,2)+Copy(DateToStr(Now),9,2);
End;
end.
Kódolás (3)
Most nézzük, hogyan használhatjuk a programot az Óraterv (Osztály tantárgyfelosztás) készítésére.
Mint azt a Programtervben is leírtam, az Óratervi lapon a következők
valósíthatók meg:
-
A tantárgyak neve módosítható a beviteli mező segítségével. A kiválasztott sor
tantárgya írható át. A tantárgy neve maximum 3 karakter lehet. A beírást Enter
billentyűvel kell lezárni. Ha üres stringet adunk meg, akkor az egy ’-’ jelre
módosul.
-
Az alapértelmezett tantárgyak között van egy an1 és egy an2. Ezek az angol,
német és első, valamint az angol, német és második idegen nyelv jelölésére
szolgálnak, arra az esetre, ha az osztályokban nem mindenki az egyik nyelvet
(pl. angolt) tanulja első idegen nyelvként. Ha az egész osztályban pl. angolt
tanul első idegen nyelv, akkor a tantárgy ang-nak illetve ném-nek, egyébként
pedig bárminek átnevezhető.
-
A Óratervi lapon az óratervek, azaz az óraszámok bevitele nyomógombok
segítségével történik. Az Inc feliratúval az óraszámot növelni, a Dec
feliratúval csökkenteni lehet. Ha a heti óraszám 0, akkor rácsban nem jelenik
meg. Mivel az osztályok óraszáma sokban hasonló, illetve azonos lehet, a gyors
feltöltés érdekében van egy ToEnd feliratú gomb, mely megnyomására az aktuális
óra az adott osztálytól kezdődően az utolsó osztályig beíródik. Természetesen,
ha üres mezőn nyomunk ToEnd-et, akkor az törlést jelent. Például a második és
harmadik évfolyamra, úgy lehet könnyen heti 3 órát beállítani, hogy ráállunk a
tantárgy sorában a 2.a osztály oszlopára, ha üres volt háromszor Inc gombot
nyomunk, majd ToEnd, aztán átmegyünk a 4.a oszlopára, Dec háromszor és ToEnd.
Ezzel a módszerrel percek alatt a teljes iskola óraterv elkészíthető.
-
Ha csak teszteljük a programot, akkor a tantárgyfelosztást, azaz az óraszámokhoz
a pedagógusok hozzárendelését a RandomTF gomb segítségével a programra
bízhatjuk. Ekkor nemcsak a tantárgyfelosztás, hanem az osztályok tanterme és
osztályfőnöke és osztályfőnöki órája is automatikusan beállítódik.
-
Ha valós órarendet szeretnénk készíteni, akkor természetesen egyenként kell a
pedagógusokat a tételekhez hozzárendelni. Jobb oldalon három listadoboz
található. A felső a pedagógusok nevét tartalmazza. Ha a rácsban a bevitel helyét
kiválasztjuk, a listán pedig kettőt kattintunk a megfelelő pedagógus nevén,
akkor a hozzárendelés megvalósul. Törlés a lista első (-) elemének
kiválasztásával történik.
-
A középső listadoboz tantermek jeleit tartalmazza, mely segítségével az
osztályokhoz tantermeket lehet rendelni. A tantermek jele az osztályjelek alatt
található. Természetesen ehhez az osztály oszlopát előzőleg ki kell választani.
-
A harmadik (alsó) listadobozban újra teremnevek láthatók. Ennek segítségével az
egyes tanítási tételekhez tantermeket (szaktantermet) rendelhetünk a fentebb
leírt módon. Ez a rácsban nem jelenik meg, de ha ráállunk a tanítási tételre,
akkor a listán kiválasztódik a hozzárendelt tanterem. Ez a visszajelzés nemcsak
a szaktanteremre, hanem a pedagógusra és az osztályok osztálytermére is igaz.
- A
bevitelek sajátossága még az, hogy nem enged két osztálynak ugyanazt az
osztálytermet beírni, illetve nem írhatunk be két ugyanolyan nevű tantárgyat
sem.
Az Óraterv beviteli képernyője:
Az
UOTer Unit listája:
unit UOTer;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms,
UAdat, UModul,
Dialogs, StdCtrls, Grids;
type
TfmOTer = class(TForm)
lbOTer: TLabel;
btKilepes: TButton;
sgTFOR: TStringGrid;
ldPeda: TListBox;
ldHely: TListBox;
btInc: TButton;
btDec: TButton;
btToEnd: TButton;
btRnd: TButton;
lbTant: TLabel;
edTant: TEdit;
ldSzak: TListBox;
lbPedaHelyek: TLabel;
Function VoltHelyNev(St: St3): Boolean;
Function VoltTantNev(St: St3): Boolean;
Procedure OTerKepre;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
procedure sgTFORClick(Sender: TObject);
procedure btIncClick(Sender: TObject);
procedure btDecClick(Sender: TObject);
procedure btToEndClick(Sender: TObject);
procedure btRndClick(Sender: TObject);
procedure ldPedaDblClick(Sender: TObject);
procedure ldHelyDblClick(Sender: TObject);
procedure ldSzakDblClick(Sender: TObject);
procedure edTantKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmOTer: TfmOTer;
implementation
{$R *.dfm}
procedure TfmOTer.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmOTer.btKilepesClick(Sender: TObject);
begin
Close;
end;
Function TfmOTer.VoltHelyNev(St: St3): Boolean;
Var H: Word;
Begin
VoltHelyNev:= False; If (St='-') Or (St='') Then Exit;
With sgTFOR Do For H:= 1 To ColCount-2 Do If St=Cells[H,1] Then
Begin VoltHelyNev:= True; Break End;
End;
Function TfmOTer.VoltTantNev(St: St3): Boolean;
Var T: Word;
Begin
VoltTantNev:= False; If (St='-') Or (St='') Then Exit;
With sgTFOR Do For T:= 1 To RowCount-2 Do If St=Cells[0,T] Then
Begin VoltTantNev:= True; Break End;
End;
procedure TfmOTer.sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
begin
With sgTFOR.Canvas.Brush Do
Begin
If (gdFixed In State) And ((Col=Acol) Or (Row=ARow)) Then
Color:= clYellow Else Color:= clBtnFace;
If gdSelected In State Then Color:= clLime;
If Not((gdSelected In State) Or (gdFixed In State)) Then Color:= clWindow;
End;
sgTFOR.Canvas.TextRect(Rect,Rect.Left+1,Rect.Top,sgTFOR.Cells[Col,Row]);
If gdFocused In State Then sgTFOR.Canvas.DrawFocusRect(Rect);
end;
procedure TfmOTer.sgTFORClick(Sender: TObject);
begin
With sgTFOR Do With ATFOR Do
Begin
If Col=ColCount-1 Then Col:= ColCount-2;
If Row=RowCount-1 Then Row:= RowCount-2;
edTant.Text:= Cells[0,Row]; ACol:= Col; ARow:= Row; RePaint;
With ldPeda Do If Row Mod 2=0 Then
ItemIndex:= OTer[Col,Row Div 2,3] Else
ItemIndex:= OTer[Col,Row Div 2,4];
With ldHely Do ItemIndex:= OHel[Col];
With ldSzak Do If Row Mod 2=0 Then
ItemIndex:= OTer[Col,Row Div 2,5] Else
ItemIndex:= OTer[Col,Row Div 2,6];
End;
end;
procedure TfmOTer.FormCreate(Sender: TObject);
Var O, P, H: Word;
begin
ACol:= 1; ARow:= 2;
With sgTFOR Do With ATFOR Do
Begin
Cells[0,1]:= 'Ter:';
Cells[ColCount-1,0]:= 'Sum'; Cells[0,RowCount-1]:= 'Sum';
For O:= 1 To OMax Do Cells[O,0]:= ONev[O];
End;
With ATFOR Do
Begin
With ldPeda Do For P:= 0 To PMax Do Items.Add(PRov[P]);
With ldHely Do For H:= 0 To HMax Do Items.Add(HNev[H]);
With ldSzak Do For H:= 0 To HMax Do Items.Add(HNev[H]);
End;
OTerKepre; sgTFORClick(Sender);
end;
Procedure TfmOTer.OTerKepre;
Var O, T, S, Sz: Word;
Begin
With sgTFOR Do With ATFOR Do
Begin
For T:= 1 To TMax Do Cells[0,2*T]:= TNev[T];
For O:= 1 To OMax Do
Begin
S:= 0;
For T:= 1 To TMax Do
Begin
Cells[O,1]:= HNev[OHel[O]];
If OTer[O,T,1]>0 Then
Cells[O,2*T ]:= IntToStr(OTer[O,T,1])+':'+
Copy(PRov[OTer[O,T,3]],1,2) Else
Cells[O,2*T ]:= ''; Inc(S,OTer[O,T,1]);
If OTer[O,T,2]>0 Then
Cells[O,2*T+1]:= IntToStr(OTer[O,T,2])+':'+
Copy(PRov[OTer[O,T,4]],1,2) Else
Cells[O,2*T+1]:= ''; Inc(S,OTer[O,T,2]);
End;
Cells[O,RowCount-1]:= IntToStr(S);
End;
Sz:= 0;
For T:= 1 To TMax Do
Begin
S:= 0;
For O:= 1 To OMax Do Inc(S,OTer[O,T,1]);
If S>0 Then Cells[ColCount-1,2*T]:= IntToStr(S) Else
Cells[ColCount-1,2*T]:= ''; Inc(Sz,S);
S:= 0;
For O:= 1 To OMax Do Inc(S,OTer[O,T,2]);
If S>0 Then Cells[ColCount-1,2*T+1]:= IntToStr(S) Else
Cells[ColCount-1,2*T+1]:= ''; Inc(Sz,S);
End;
Cells[ColCount-1,RowCount-1]:= IntToStr(Sz);
End;
End;
procedure TfmOTer.btIncClick(Sender: TObject);
begin
With sgTFOR Do With ATFOR Do
Begin
ATant:= Row Div 2;
If Odd(Row) And (OTer[Col,ATant,1]>0) Then Inc(OTer[Col,ATant,2])
Else Inc(OTer[Col,ATant,1]);
If OTer[Col,ATant,1]>9 Then OTer[Col,ATant,1]:= 9;
If OTer[Col,ATant,2]>9 Then OTer[Col,ATant,2]:= 9;
End;
OTerKepre;
end;
procedure TfmOTer.btDecClick(Sender: TObject);
begin
With sgTFOR Do With ATFOR Do
Begin
ATant:= Row Div 2;
If Odd(Row) And (OTer[Col,ATant,1]>0) Then Dec(OTer[Col,ATant,2])
Else Dec(OTer[Col,ATant,1]);
If OTer[Col,ATant,1]>9 Then OTer[Col,ATant,1]:= 0;
If OTer[Col,ATant,2]>9 Then OTer[Col,ATant,2]:= 0;
End;
OTerKepre
end;
procedure TfmOTer.btToEndClick(Sender: TObject);
Var O: Word;
begin
With sgTFOR Do With ATFOR Do
Begin
ATant:= Row Div 2;
If Not Odd(Row) Then For O:= Col+1 To OMax Do
OTer[O,ATant,1]:= OTer[Col,ATant,1] Else
For O:= Col+1 To OMax Do OTer[O,ATant,2]:= OTer[Col,ATant,2];
End;
OTerKepre;
end;
procedure TfmOTer.btRndClick(Sender: TObject);
Var O, P, T, H: Word;
begin
With ATFOR Do
Begin
For O:= 1 To OMax Do For T:= 1 To TMax Do
For P:= 3 To 6 Do OTer[O,T,P]:= 0;
For O:= 1 To Omax Do Begin OHel[O]:= 0; OOfo[O]:= 0 End;
End;
For P:= 1 To PMax Do PHOSz[P]:= 0;
With ATFOR Do For O:= 1 To OMax Do For T:= 2 To TMax Do
Begin
If OTer[O,T,1]>0 Then
Begin
P:= Random(PMax)+1;
While PHOSz[P]+OTer[O,T,1]>OSzM-1 Do P:= Random(PMax)+1;
Inc(PHOSz[P],OTer[O,T,1]); OTer[O,T,3]:= P;
End;
If OTer[O,T,2]>0 Then
Begin
P:= Random(PMax)+1;
While (PHOSz[P]+OTer[O,T,2]>OSzM-1) Or (OTer[O,T,3]=P) Do
P:= Random(PMax)+1;
Inc(PHOSz[P],OTer[O,T,2]); OTer[O,T,4]:= P;
End;
End;
With sgTFOR Do With ATFOR Do For O:= 1 To OMax Do
Begin
H:= Random(HMax)+1;
While VoltHelyNev(HNev[H]) Do H:= Random(HMax)+1;
OHel[O]:= H; Cells[O,1]:= HNev[H];
P:= Random(PMax)+1;
While VoltOfo(P) Do P:= Random(PMax)+1;
OOfo[O]:= P; OTer[O,1,3]:= P;
End;
OTerKepre; sgTFORClick(Sender);
end;
procedure TfmOTer.ldPedaDblClick(Sender: TObject);
begin
With sgTFOR Do With ldPeda Do With ATFOR Do
Begin
ATant:= Row Div 2; If ATant=1 Then If VoltOfo(ItemIndex) Then Exit;
If Not Odd(Row) And (OTer[Col,ATant,1]>0) Then
OTer[Col,ATant,3]:= ItemIndex;
If Odd(Row) And (OTer[Col,ATant,2]>0) Then OTer[Col,ATant,4]:= ItemIndex;
If Col<ColCount-2 Then Col:= Col+1;
End;
OTerKepre;
end;
procedure TfmOTer.ldHelyDblClick(Sender: TObject);
begin
With sgTFOR Do With ldHely Do If Not VoltHelyNev(Items[ItemIndex]) Then
Begin
Cells[Col,1]:= Items[ItemIndex]; ATFOR.OHel[Col]:= ItemIndex;
If Col<ColCount-2 Then Col:= Col+1;
End;
end;
procedure TfmOTer.ldSzakDblClick(Sender: TObject);
begin
With sgTFOR Do With ldSzak Do With ATFOR Do
Begin
ATant:= Row Div 2;
If Not Odd(Row) And (OTer[Col,ATant,1]>0) Then
OTer[Col,ATant,5]:= ItemIndex;
If Odd(Row) And (OTer[Col,ATant,2]>0) Then OTer[Col,ATant,6]:= ItemIndex;
If Col<ColCount-2 Then Col:= Col+1;
End;
OTerKepre;
end;
procedure TfmOTer.edTantKeyPress(Sender: TObject; var Key: Char);
begin
If Key=#13 Then
With sgTFOR Do With edTant Do If Not VoltTantNev(Text) Then
Begin
If Text='' Then Text:= '-'; Cells[0,2*(Row Div 2)]:= Text;
ATFOR.TNev[Row Div 2]:= Text;
If Row<RowCount-2 Then Row:= Row+1;
End;
end;
end.
Kódolás (4)
Folytassuk a kódolást a géppel segített
órarendkészítéssel, azon belül először a Pedagógus
órarenddel. A Programtervben leírtaknak megfelelően a következőkre lesz
lehetőségünk:
-
A pedagógusok neve módosítható a beviteli mező segítségével. A kiválasztott sorban
található pedagógus neve írható át. A pedagógus neve (itt inkább nevének a
rövidítése) maximum 3 karakter lehet. A beírást Enter billentyűvel kell
lezárni. Ha üres stringet adunk meg, akkor az egy ’-’ jelre módosul. Nem lehet
két pedagógusnak ugyanaz a névrövidítése.
-
Ha egy pedagógust kiválasztunk, (az órarend valamelyik sorába állunk) akkor egy
táblázatban megjelenik a pedagógus tantárgyfelosztása. Azaz, hogy milyen
tantárgyat, melyik osztályban, heti hány órában tanít. A tantárgyfelosztás
táblázatának utolsó sorában jelenjen meg a pedagógus heti kötelező, nem
óratervi és óratervi óráinak száma. A tantárgyfelosztáson mozogva a pedagógus
órarenden aláhúzás karakterek jelennek meg azokban az órákban, ahova a tétel
beírható. Ha egy tétel csoportbontásban szerepel, akkor a jelölés mindkét
pedagógus órarendjében látható, valamint külön megjelenik a másik pedagógus
neve. Ha egy tételből órák vannak beírva, akkor az órarendben a megfelelő óra
lila háttérszínnel jelenik meg.
-
A lehető legtöbb pedagógus órarendjét jelenítsük meg a képernyőn. Ezt úgy érjük
el, hogy minden pedagógus órarend csak egy képernyő sorban fog megjelenni, és a
megjelenő órarend csak az osztály jelét fogja tartalmazni. Ha a tantárgyra is
kíváncsiak vagyunk, akkor kattintsunk a kérdéses órán, így a
tantárgyfelosztáson a megfelelő tétel kiválasztódik, melyből a tétel óraszáma
is látható. Szintén láthatóvá válik a tanterem is.
- Óra
beírásának menete: válasszuk ki az órarendben a pedagógust és azon belül azt
is, hogy mely időpontba szeretnénk órát beírni. Ekkor a tantárgyfelosztás
táblázat a pedagógus tantárgyfelosztását fogja tartalmazni. Válasszuk ki a
beírandó tételt a tantárgyfelosztásban. Ekkor láthatóvá válik, hogy mely
időpontokba írható be a tétel. Nézzük meg, hogy az órarendben a kiválasztott
helyen aláhúzás karakter látható-e, ez jelzi a beírhatóságot. Ha igen, akkor
kettős kattintással a tételből egy óra a kiválasztott időpontra beírásra kerül.
A tantárgyfelosztás felett látható, hogy a tételből hány óra van már Beírva.
Természetesen a tétel óraszámánál több órát nem enged a program beírni.
-
Órát törölni az órarendből úgy kell, hogy egy beírt órán kettőt kattintunk.
-
Ha olyan helyen kattintunk kettőt az órarendben, ahol nincs óra, akkor az az
óra tiltott óra lesz, jele: XX. Ha tiltott órán kattintunk kettőt, akkor a
tiltás megszűnik. Ha egy nap első (0.) óráján kattintunk tiltás beállítása vagy
visszavonása miatt, akkor a teljes napra megtörténik a beállítás illetve
visszavonás, ha a nap minden órája üres volt, vagy tiltott.
-
Mivel a gépi feltöltéskor is ezt a képernyőt (formot) fogjuk használni, a
továbbiakban erre a képernyőre még visszatérünk.
Lássuk a Pedagógus órarend képernyőjét:
A
Pedagógus órarendet az UPOR unit tartalmazza, melynek listája:
unit UPOR;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
UAdat, UModul,
Dialogs, StdCtrls, Grids;
type
TfmPOR = class(TForm)
lbPOR: TLabel;
btKilepes: TButton;
sgTFOR: TStringGrid;
edPeda: TEdit;
lbPeda: TLabel;
sgPTF: TStringGrid;
lbBeirva: TLabel;
lbBeirvaSz: TLabel;
lbMPeda: TLabel;
lbHely: TLabel;
btUpLoad: TButton;
btDelAll: TButton;
lbKeszVege: TLabel;
btRendez: TButton;
lbMax: TLabel;
edMax: TEdit;
edLSz: TEdit;
lbBad: TLabel;
lbBest: TLabel;
edBest: TEdit;
lbStart: TLabel;
edStart: TEdit;
lbStop: TLabel;
edStop: TEdit;
lbH: TLabel;
lbMP: TLabel;
btDelXX: TButton;
edRest: TEdit;
lbR: TLabel;
lbInfo: TLabel;
Function VoltPedaNev(St: St3): Boolean;
Procedure PORKepre;
Procedure PTFKepre(Peda: Word);
Function Utkozes(I,P: Word): Word;
Procedure Utkozesek;
Procedure UtkKepre;
Procedure Csere(I1,I2,P: Word);
Procedure Keveres(Sender: TObject);
Procedure Csoportok;
Function HibaLista: Word;
Procedure KetOra;
Procedure OsztOsz;
Procedure PHetiOSz;
Procedure HORend;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
procedure FormCreate(Sender: TObject);
procedure sgTFORClick(Sender: TObject);
procedure edPedaKeyPress(Sender: TObject; var Key: Char);
procedure sgPTFClick(Sender: TObject);
procedure sgPTFDblClick(Sender: TObject);
procedure sgTFORDblClick(Sender: TObject);
procedure btUpLoadClick(Sender: TObject);
procedure btDelAllClick(Sender: TObject);
procedure btRendezClick(Sender: TObject);
procedure btDelXXClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmPOR: TfmPOR;
Ind, Zero: Array[1..HOSz*PMax,1..2] Of Word;
Lanc: Array[0..PMax+1] Of Word;
PBeir, PUtk, Cso, PCso: Array[0..HOSz+1,0..PMax+1] Of Word;
PPOR: Array[0..HOSz+1,0..PMax+1,0..4] Of Word;
Leh, ULeh: Array[1..HOSz] Of Word;
UtkOsz, OldUtkOSz, PUtkOSz, Rest, Valt: Word;
LSz, LMax: LongInt;
implementation
{$R *.dfm}
procedure TfmPOR.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmPOR.btKilepesClick(Sender: TObject);
begin
Close;
end;
Function TfmPOR.VoltPedaNev(St: St3): Boolean;
Var P: Word;
Begin
VoltPedaNev:= False; If (St='-') Or (St='') Then Exit;
With sgTFOR Do For P:= 1 To RowCount-2 Do If St=Cells[0,P] Then
Begin VoltPedaNev:= True; Break End;
End;
procedure TfmPOR.sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
begin
With sgTFOR.Canvas.Brush Do
Begin
If (gdFixed In State) And ((Col=Acol) Or (Row=ARow)) Then
Color:= clYellow Else Color:= clBtnFace;
If gdSelected In State Then Color:= clLime;
If Not((gdSelected In State) Or (gdFixed In State)) Then
Begin
Case Col Of
2..7,12..17,22..27,32..37,42..47: Color:= RGB(232,232,232);
Else Color:= clWindow;
End;
If PBeir[Col,Row]=1 Then Color:= clFuchsia Else
If PUtk[Col,Row]=KetO Then Color:= RGB($DF,$B0,$20) Else
If PUtk[Col,Row]>0 Then Color:= clRed;
End;
End;
sgTFOR.Canvas.TextRect(Rect,Rect.Left,Rect.Top,sgTFOR.Cells[Col,Row]);
If gdFocused In State Then sgTFOR.Canvas.DrawFocusRect(Rect);
end;
procedure TfmPOR.sgTFORClick(Sender: TObject);
Var I, P, T: Word;
begin
With sgTFOR Do
Begin
If Col=ColCount-1 Then Col:= ColCount-2;
If Row=RowCount-1 Then Row:= RowCount-2;
For I:= 1 To HOSz Do For P:= 1 To PMax Do If Cells[I,P]=Jel
Then Cells[I,P]:= '';
edPeda.Text:= Cells[0,Row]; ACol:= Col; ARow:= Row; RePaint;
APeda:= Row; AIdop:= Col; PTFKepre(Row);
End;
With sgPTF Do With ATFOR Do If POra[AIdop,APeda,1] In [1..TMax] Then
Begin
For T:= 1 To RowCount-2 Do
If (POra[AIdop,APeda,1]=TNevToInd(Cells[0,T])) And
(POra[AIdop,APeda,2]=ONevToInd(Cells[1,T])) Then
Begin Row:= T; Break End;
End;
sgPTF.Repaint; lbMPeda.Repaint; edPeda.Repaint; lbHely.Repaint;
sgPTFClick(Sender);
end;
procedure TfmPOR.FormCreate(Sender: TObject);
Var I, J: Word;
begin
ACol:= 1; ARow:= 1; Valt:= 0; LMax:= 200000; PUtkOSz:= 65000;
For I:= 1 To HOSz*PMax Do For J:= 1 To 2 Do Zero[I,J]:= 0; Ind:= Zero;
For I:= 1 To HOSz Do Leh[I]:= 0; ULeh:= Leh;
With sgTFOR Do With ATFOR Do
Begin
ColWidths[0]:= 25; ColWidths[ColCount-1]:= 24;
Cells[ColCount-1,0]:= 'Sum'; Cells[0,RowCount-1]:= 'Sum';
For I:= 1 To HOSz Do Cells[I,0]:= INev[I];
End;
Csoportok; PORKepre; sgTFORClick(Sender);
With sgPTF Do
Begin
Cells[0,0]:= 'Tant'; Cells[1,0]:= 'Oszt'; Cells[2,0]:= 'Órsz';
End;
end;
Procedure TfmPOR.PORKepre;
Var I, P, S, Sz: Word;
St: St3;
Begin
With sgTFOR Do With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do Cells[I,P]:= '';
For P:= 1 To PMax Do Cells[0,P]:= PRov[P];
For P:= 1 To PMax Do
Begin
S:= 0;
For I:= 1 To HOSz Do
Begin
St:= ONev[POra[I,P,2]]; If Cso[I,P]>0 Then St:= UpONev(St);
If POra[I,P,1]<>Tilt Then
Cells[I,P]:= St Else Cells[I,P]:= 'XX';
If POra[I,P,1] In [1..TMax] Then Inc(S);
End; Cells[ColCount-1,P]:= IntToStr(S);
End;
Sz:= 0;
For I:= 1 To HOSz Do
Begin
S:= 0;
For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
Begin Inc(S); Inc(Sz) End; Cells[I,RowCount-1]:= IntToStr(S);
End; Cells[ColCount-1,RowCount-1]:= IntToStr(Sz);
End;
End;
Procedure TfmPOR.PTFKepre(Peda: Word);
Var O, T, S, Sz: Word;
Begin
With sgPTF Do With ATFOR Do
Begin
S:= 0; Sz:= 0;
For O:= 0 To ColCount-1 Do For T:= 1 To RowCount-2 Do Cells[O,T]:= '';
For O:= 1 To OMax Do For T:= 1 To TMax Do
If OTer[O,T,1]<>0 Then If (OTer[O,T,3]=Peda) Or (OTer[O,T,4]=Peda) Then
Begin
Inc(S); sgPTF.Cells[0,S]:= TNev[T]; sgPTF.Cells[1,S]:= ONev[O];
sgPTF.Cells[2,S]:= IntToStr(OTer[O,T,1]); Inc(Sz,OTer[O,T,1]);
End;
With sgPTF Do
Begin
Cells[0,RowCount-1]:= IntToStr(PKot[Peda]);
Cells[1,RowCount-1]:= IntToStr(PNOT[Peda]);
Cells[2,RowCount-1]:= IntToStr(Sz);
End;
End;
End;
Function TfmPOR.Utkozes(I,P: Word): Word;
Var K, KI, I1: Word;
Begin
With ATFOR Do
Begin
PUtk[I,P]:= 0; Utkozes:= PUtk[I,P]; If POra[I,P,1] In [0,Tilt] Then Exit;
If (POra[I,P,1]<>0) And (OLeh[I,2*POra[I,P,2]-1]=0) Then Inc(PUtk[I,P],2);
For K:= 1 To PMax Do If (K<>P) And (POra[I,K,2]<>0) Then
Begin
If (Cso[I,K]=0) And (POra[I,K,2]=POra[I,P,2]) Then Inc(PUtk[I,P]) Else
If (K<>Cso[I,P]) And (POra[I,K,2]=POra[I,P,2]) Then Inc(PUtk[I,P]);
End;
I1:= NOSz*((I-1) Div NOSz)+1;
For K:= I1 To I1+NOSz-1 Do If (K<>I) And (POra[K,P,1]<>0) Then
If (POra[K,P,1]=POra[I,P,1]) And (POra[K,P,2]=POra[I,P,2]) Then
Inc(PUtk[I,P]);
If OTer[POra[I,P,2],POra[I,P,1],1]=2 Then
Begin
KI:= 0;
For K:= 1 To HOSz Do If (K<>I) Then
If (POra[K,P,1]=POra[I,P,1]) And (POra[K,P,2]=POra[I,P,2]) Then
Begin KI:= K; Break End;
If Abs(((I-1) Div NOsz)-((KI-1) Div NOSz))=1 Then Inc(PUtk[I,P]);
End;
End; Utkozes:= PUtk[I,P];
End;
Procedure TfmPOR.Utkozesek;
Var I, P: Word;
Begin
UtkOsz:= 0;
For I:= 1 To HOSz Do For P:= 1 To PMax Do Inc(UtkOsz,Utkozes(I,P));
End;
Procedure TfmPOR.UtkKepre;
Var I, P, Sz: Word;
Begin
With sgTFOR Do For I:= 1 To HOSz Do
Begin
Sz:= 0; For P:= 1 To PMax Do Inc(Sz,PUtk[I,P]);
Cells[I,RowCount-1]:= IntToStr(Sz);
End;
If Valt= 100 Then Valt:= 1;
If Valt>0 Then With sgPTF do
Begin
Col:= (Valt-1) Mod 3;
Row:= (Valt-1) Div 3+1;
Cells[Col,Row]:= IntToStr(UtkOSz);
End; lbKeszVege.Caption:= IntToStr(UtkOSz);
End;
Procedure TfmPOR.Csere(I1,I2,P: Word);
Var K, Puf: Word;
Lehet: Boolean;
Begin
With ATFOR Do
Begin
If (POra[I1,P,4]=1) Or (POra[I2,P,4]=1) Then Exit;
If (POra[I1,P,1]=POra[I2,P,1]) And (POra[I1,P,2]=POra[I2,P,2]) Then Exit;
If Cso[I1,P]+Cso[I2,P]=0 Then
Begin
Puf:= POra[I1,P,1]; POra[I1,P,1]:= POra[I2,P,1]; POra[I2,P,1]:= Puf;
Puf:= POra[I1,P,2]; POra[I1,P,2]:= POra[I2,P,2]; POra[I2,P,2]:= Puf;
Puf:= POra[I1,P,4]; POra[I1,P,4]:= POra[I2,P,4]; POra[I2,P,4]:= Puf;
Puf:= Cso[I1,P]; Cso[I1,P]:= Cso[I2,P]; Cso[I2,P]:= Puf; Exit;
End Else
Begin
For K:= 0 To PMax Do Lanc[K]:= 0; Lanc[P]:= 1;
Puf:= Cso[I1,P]; K:= 1;
While (Puf<>0) And (K<=PMax) Do
Begin
Lanc[Puf]:= 1;
If Odd(K) Then Puf:= Cso[I2,Puf] Else Puf:= Cso[I1,Puf]; Inc(K);
End;
Puf:= Cso[I2,P]; K:= 1;
While (Puf<>0) And (K<=PMax) Do
Begin
Lanc[Puf]:= 1;
If Odd(K) Then Puf:= Cso[I1,Puf] Else Puf:= Cso[I2,Puf]; Inc(K);
End;
Lehet:= True;
For K:= 1 To PMax Do If Lanc[K]>0 Then
If (POra[I1,K,4]=1) Or (POra[I2,K,4]=1) Then
Begin Lehet:= False; Break End;
If Lehet Then For K:= 1 To PMax Do If Lanc[K]>0 Then
Begin
Puf:= POra[I1,K,1]; POra[I1,K,1]:= POra[I2,K,1]; POra[I2,K,1]:= Puf;
Puf:= POra[I1,K,2]; POra[I1,K,2]:= POra[I2,K,2]; POra[I2,K,2]:= Puf;
Puf:= POra[I1,K,4]; POra[I1,K,4]:= POra[I2,K,4]; POra[I2,K,4]:= Puf;
Puf:= Cso[I1,K]; Cso[I1,K]:= Cso[I2,K]; Cso[I2,K]:= Puf;
End;
End;
End;
End;
Procedure TfmPOR.Keveres(Sender: TObject);
Var K, I1, I2, P: Word;
Begin
If (Rest Mod NaSz)=0 Then btUpLoadClick(Sender) Else With ATFOR Do
For P:= 1 To PMax Do For K:= 1 To 2*(((Rest-1) Mod NaSz)+1) Do
Begin
I1:= Random(HOsz)+1; I2:= Random(HOSz)+1;
If Rest Mod NaSz>2 Then While (POra[I1,P,4]=1) Or (POra[I2,P,4]=1) Do
Begin I1:= Random(HOsz)+1; I2:= Random(HOSz)+1 End Else
While (POra[I1,P,4]=1) Or (POra[I2,P,4]=1) Or
(Cso[I1,P]>0) Or (Cso[I2,P]>0) Do
Begin I1:= Random(HOsz)+1; I2:= Random(HOSz)+1 End;
Csere(I1,I2,P);
End;
End;
Procedure TfmPOR.Csoportok;
Var I, P, k: Word;
Begin
With sgTFOR Do With ATFOR Do
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
For K:= 1 To PMax Do If K<>P Then
If (POra[I,K,1]=POra[I,P,1]) And (POra[I,K,2]=POra[I,P,2]) Then Cso[I,P]:= K;
End;
Function TfmPOR.HibaLista: Word;
Var I, P, K: Word;
Begin
Ind:= Zero; K:= 0; With ATFOR Do For I:= 1 To HOSz Do For P:= 1 To PMax Do
If (PUtk[I,P]>0) And (POra[I,P,4]<>1) Then
Begin Inc(K); Ind[K,1]:= I; Ind[K,2]:= P End; HibaLista:= K;
End;
procedure TfmPOR.edPedaKeyPress(Sender: TObject; var Key: Char);
begin
If Key=#13 Then
With sgTFOR Do With edPeda Do If Not VoltPedaNev(Text) Then
Begin
If Text='' Then Text:= '-'; Cells[0,Row]:= Text; ATFOR.PRov[Row]:= Text;
If Row<RowCount-2 Then Row:= Row+1;
End;
end;
procedure TfmPOR.sgPTFClick(Sender: TObject);
Var I, P, P1, P2, PP, Sz: Word;
Van: Boolean;
begin
With sgPTF Do Begin
If (Valt=0) And (Row=RowCount-1) Then Row:= RowCount-2 End;
MPeda:= 0; Sz:= 0; lbBeirvaSz.Caption:= '0';
For I:= 0 To HOSz Do For P:= 0 To PMax+1 Do PBeir[I,P]:= 0;
With sgTFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do
If Cells[I,P]=Jel Then Cells[I,P]:= ''; P1:= Row;
End;
P2:= 0; PP:= 0;
With sgPTF Do
Begin
ATant:= TNevToInd(Cells[0,Row]); AOszt:= ONevToInd(Cells[1,Row]);
lbHely.Caption:= ATFOR.HNev[TTetToHely(AOszt,ATant)];
End;
With ATFOR Do
If OTer[AOszt,ATant,1]*OTer[AOszt,ATant,2]>0 Then
Begin
If OTer[AOszt,ATant,3]=P1 Then Begin P2:= OTer[AOszt,ATant,4]; PP:= P2 End
Else If OTer[AOszt,ATant,4]=P1 Then
Begin P1:= OTer[AOszt,ATant,3]; PP:= P1; P2:= OTer[AOszt,ATant,4] End;
lbMPeda.Caption:= ATFOR.PRov[PP];
End Else Begin P2:= 0; lbMPeda.Caption:= '- ' End;
With sgPTF Do If Cells[0,Row]<>'' Then With ATFOR Do
Begin
For I:= 1 To HOSz Do
If (TNev[POra[I,P1,1]]= Cells[0,Row]) And (POra[I,P1,2]=AOszt) Then
Begin Inc(Sz); PBeir[I,P1]:= 1; If P2<>0 Then PBeir[I,P2]:= 1 End;
lbBeirvaSz.Caption:= IntToStr(Sz);
If P2=0 Then
Begin
For I:= 1 To HOSz Do If POra[I,P1,1]=0 Then
Begin
Van:= False; For P:= 1 To PMax Do If POra[I,P,2]=AOszt Then
Begin Van:= True; Break End;
If Not Van Then Begin sgTFOR.Cells[I,P1]:= Jel End;
End;
End Else
For I:= 1 To HOSz Do If (POra[I,P1,1]=0) And (POra[I,P2,1]=0) Then
Begin
Van:= False; For P:= 1 To PMax Do If POra[I,P,2]=AOszt Then
Begin Van:= True; Break End; If Not Van Then
Begin sgTFOR.Cells[I,P1]:= Jel; sgTFOR.Cells[I,P2]:= Jel End;
End;
End; MPeda:= PP; sgTFOR.Repaint; lbBeirvaSz.Repaint; lbHely.Repaint;
end;
procedure TfmPOR.sgPTFDblClick(Sender: TObject);
begin
With sgPTF Do If lbBeirvaSz.Caption>=Cells[2,Row] Then Exit;
With sgTFOR Do If Cells[Col,Row]<>Jel Then Exit;
With sgTFOR Do With ATFOR Do
Begin
POra[Col,Row,1]:= TNevToInd(sgPTF.Cells[0,sgPTF.Row]);
POra[Col,Row,2]:= ONevToInd(sgPTF.Cells[1,sgPTF.Row]);
POra[Col,Row,3]:= TTetToHely(POra[Col,Row,2],POra[Col,Row,1]);
POra[Col,Row,4]:= 1;
If MPeda>0 Then
Begin
POra[Col,MPeda,1]:= TNevToInd(sgPTF.Cells[0,sgPTF.Row]);
POra[Col,MPeda,2]:= ONevToInd(sgPTF.Cells[1,sgPTF.Row]);
POra[Col,MPeda,3]:= TTetToHely(POra[Col,MPeda,2],POra[Col,MPeda,1]);
POra[Col,MPeda,4]:= 1;
Cso[Col,APeda]:= MPeda; Cso[Col,MPeda]:= APeda;
End;
If Col<ColCount-2 Then Col:= Col+1;
End; PORKepre; sgPTFClick(Sender);
end;
procedure TfmPOR.sgTFORDblClick(Sender: TObject);
Var I, P, KI: Word;
Mind: Boolean;
begin
With sgTFOR Do With ATFOR Do
Begin
Case POra[Col,Row,1] Of
0: Begin
KI:= NOSz*((Col-1) Div NOSz)+1; Mind:= True;
For I:= KI To KI+NOSz-1 Do If POra[I,Row,1]<>0 Then
Begin Mind:= False; Break End;
If ((Col-1) Mod NOSz=0) And Mind Then
For I:= KI To KI+NOSz-1 Do
Begin POra[I,Row,1]:= Tilt; POra[I,Row,4]:= 1 End
Else Begin POra[Col,Row,1]:= Tilt; POra[Col,Row,4]:= 1 End;
End;
Tilt: Begin
KI:= NOSz*((Col-1) Div NOSz)+1; Mind:= True;
For I:= KI To KI+NOSz-1 Do If POra[I,Row,1]<>Tilt Then
Begin Mind:= False; Break End;
If ((Col-1) Mod NOSz=0) And Mind Then
For I:= KI To KI+NOSz-1 Do
Begin POra[I,Row,1]:= 0; POra[I,Row,4]:= 0 End
Else Begin POra[Col,Row,1]:= 0; POra[Col,Row,4]:= 0 End;
End;
1..TMax: Begin
MPeda:= 0;
For P:= 1 To PMax Do If P<>Row Then
If (POra[Col,P,1]=POra[Col,Row,1]) And
(POra[Col,P,2]=POra[Col,Row,2]) Then
Begin MPeda:= P; Break End;
For I:= 1 To 4 Do POra[Col,Row,I]:= 0;
If MPeda<>0 Then For I:= 1 To 4 Do POra[Col,MPeda,I]:= 0;
End;
End; If Col<ColCount-2 Then Col:= Col+1;
End; PORKepre; sgPTFClick(Sender);
end;
procedure TfmPOR.btDelAllClick(Sender: TObject);
Var I, P, K: Word;
begin
With ATFOR Do For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do
Begin
PBeir[I,P]:= 0; PUtk[I,P]:= 0;
If POra[I,P,4]=2 Then For K:= 0 To 4 Do POra[I,P,K]:= 0;
End; PORKepre;
end;
procedure TfmPOR.btDelXXClick(Sender: TObject);
Var I, P: Word;
begin
With ATFOR Do For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do
If POra[I,P,1]=Tilt Then POra[I,P,1]:= 0; PORKepre;
end;
procedure TfmPOR.btUpLoadClick(Sender: TObject);
Var O, T, P, I, N, S: Word;
begin
Csoportok;
With sgTFOR Do With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,4]<>1 Then
Begin Cso[I,P]:= 0; For N:= 0 To 4 Do POra[I,P,N]:= 0 End;
For O:= 1 To OMax Do For T:= 1 To TMax Do
Begin
APeda:= OTer[O,T,3]; MPeda:= OTer[O,T,4]; I:= Random(HOSz)+1;
If MPeda<>0 Then
Begin
S:= OTer[O,T,1]-PORBeirt(APeda,T,O);
For N:= 1 To S Do
Begin
While (POra[I,APeda,1]<>0) Or (POra[I,MPeda,1]<>0) Do
I:= Random(HOSz)+1;
POra[I,APeda,1]:= T; POra[I,APeda,2]:= O; POra[I,APeda,4]:= 2;
POra[I,MPeda,1]:= T; POra[I,MPeda,2]:= O; POra[I,MPeda,4]:= 2;
Cso[I,APeda]:= MPeda; Cso[I,MPeda]:= APeda;
End;
End Else
If MPeda=0 Then
Begin
S:= OTer[O,T,1]-PORBeirt(APeda,T,O);
For N:= 1 To S Do
Begin
While POra[I,APeda,1]<>0 Do I:= Random(HOsz)+1;
POra[I,APeda,1]:= T; POra[I,APeda,2]:= O; POra[I,APeda,4]:= 2;
End;
End;
End;
End; Utkozesek; PORKepre; UtkKepre;
end;
Procedure TfmPOR.KetOra;
Var P, I, K: Word;
Begin
With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do PUtk[I,P]:= 0;
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
If OTer[POra[I,P,2],POra[I,P,1],1]=2 Then For K:= 1 To HOSz Do
If (POra[I,P,1]=POra[K,P,1]) And (POra[I,P,1]=POra[K,P,1]) Then
PUtk[I,P]:= KetO;
End;
End;
Procedure TfmPOR.OsztOSz;
Var I, P, S: Word;
Begin
With sgTFOR Do For I:= 1 To HOSz Do
Begin
S:= 0; For P:= 1 To PMax Do
If (Cells[I,P]<>'') And (Cells[I,P]<>'XX') Then Inc(S);
Cells[I,RowCount-1]:= IntToStr(S);
End;
End;
Procedure TfmPOR.PHetiOSz;
Var O, T, P: Word;
Begin
For P:= 0 To PMax+1 Do PHOsz[P]:= 0; With ATFOR Do
For O:= 1 To OMax Do For T:= 1 To TMax Do If OTer[O,T,1]>0 Then
Begin
Inc(PHOSz[OTer[O,T,3]],OTer[O,T,1]); Inc(PHOSz[OTer[O,T,4]],OTer[O,T,2]);
End;
End;
Procedure TfmPOR.HORend;
Var I, P, P1, K: Word;
L: Integer;
Begin
With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do
Begin
POra[I,P,3]:= 0; If POra[I,P,1] In [1..TMax] Then
POra[I,P,3]:= TTetToHely(POra[I,P,2],POra[I,P,1]);
End;
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
For P1:= 1 To PMax Do If (P1<>P) And (POra[I,P1,3]=POra[I,P,3]) Then
Begin
AHely:= Pora[I,P1,3]; POra[I,P1,3]:= 0;
For K:= 1 To HMax Div 2+1 Do
Begin
L:= 0; If Odd(K) Then L:= AHely-K; If L<1 Then L:= HMax;
If Not Odd(K) Then L:= AHely+K; If L>HMax Then L:= 1;
If UresHely(I,L) Then POra[I,P1,3]:= L;
End;
End;
End;
End;
procedure TfmPOR.btRendezClick(Sender: TObject);
Var I, I1, P, K, A, Index, RIndex, Ismet, KIsm, VIsm: Word;
Volt: Boolean;
begin
PHetiOSz;
With sgPTF Do
Begin
Row:= RowCount-2; sgPTFClick(Sender);
For I:= 0 To ColCount-1 Do For K:= 1 To RowCount-1 Do Cells[I,K]:= '';
Valt:= 0; RePaint;
End;
PUtkOSz:= 65000; edStart.Text:= TimeToStr(GetTime); edStart.Repaint;
edStop.Text:= ''; edStop.Repaint;
LSz:= 0; Volt:= False; OldUtkOSz:= 0; Ismet:= 0; Rest:= 0;
lbKeszVege.Caption:= ''; Index:= HibaLista;
With ATFOR Do While (Index>0) And (LSz<LMax) Do
Begin
If OldUtkOSz=UtkOSz Then
Begin
Inc(Ismet); If Ismet>2500 Then
Begin
Ismet:= 0; If UtkOSz<=PUtkOSz Then
Begin
PUtkOSz:= UtkOSz;
For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do For K:= 0 To 4 Do
PPOR[I,P,K]:= POra[I,P,K]; PCSO:= CSO;
edBest.Text:= IntToStr(PUtkOSz);
End;
Inc(Rest); Inc(Valt); edRest.Text:= IntToStr(Rest+1); Keveres(Sender);
Utkozesek; PORKepre; UtkKepre; edLSz.Text:= IntToStr(LSz); RePaint;
Index:= HibaLista;
End;
End Else Ismet:= 0; Inc(LSz);
//A<->b típusú csere
If Volt Then Index:= Hibalista; A:= UtkOSz; OldUtkOSz:= A;
RIndex:= Random(Index)+1; I:= Ind[RIndex,1]; P:= Ind[RIndex,2];
For K:= 1 To 2 Do
If (Cso[I,P]=0) Or (OTer[POra[I,P,2],POra[I,P,1],1]<4) Or
(PHOsz[P]<OSzM-4) Then
Begin RIndex:= Random(Index)+1; I:= Ind[RIndex,1]; P:= Ind[RIndex,2] End;
Leh:= ULeh; KIsm:= 0; Leh[I]:= 1;
If UtkOSz<HOSz Then VIsm:= HOSz-UtkOSz Else VIsm:= 2;
While KIsm<VIsm Do
Begin
Inc(KIsm); I1:= Random(HOsz)+1;
While (Leh[I1]=1) Or (I=I1) Do I1:= Random(HOsz)+1;
Leh[I1]:= 1; Csere(I,I1,P); Utkozesek;
If UtkOSz>A Then Begin Csere(I,I1,P); Utkozesek; Volt:= False End
Else Begin KIsm:= HOSz; Volt:= True End;
End;
If LSz Mod 1000=0 Then
Begin
PORKepre; Inc(Valt); UtkKepre; edLSz.Text:= IntToStr(LSz); Repaint;
End;
End;
With ATFOR Do If (UtkOSz>0) And (UtkOSz>=PUtkOSz) Then
Begin
edBest.Text:= IntToStr(PUtkOSz);
For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do For K:= 0 To 4 Do
POra[I,P,K]:= PPOR[I,P,K]; CSO:= PCSO; Utkozesek;
End
Else edBest.Text:= IntToStr(UtkOSz);
PORKepre; UtkKepre; edLSz.Text:= IntToStr(LSz);
With lbKeszVege Do If UtkOSz=0 Then
Begin KetOra; OsztOSz; HORend; Caption:= 'OK' End Else Caption:= 'End';
edStop.Text:= TimeToStr(GetTime); Valt:= 0;
end;
end.
Kódolás (5)
A géppel segített órarendkészítés másik beviteli
felülete az Osztályórarend lesz.
Ennek a felületnek a segítségével hasonló dolgokat végezhetünk, mint Pedagógus
órarenddel:
-
Az osztályok jele módosítható a beviteli mező segítségével. A kiválasztott
sorban található osztály jele írható át. Az osztály jele maximum 3 karakter lehet.
A beírást Enter billentyűvel kell lezárni. Ha üres stringet adunk meg, akkor az
egy ’-’ jelre módosul. Nem lehet két osztálynak ugyanaz a jele.
-
Az osztályok osztályfőnökének bevitelére egy legördülő lista áll rendelkezésre.
Az osztályfőnök neve az órarendben az osztály jele alatt látható.
-
Ha egy osztályt kiválasztunk, (az órarend valamelyik sorába állunk) akkor egy
táblázatban megjelenik az osztály tantárgyfelosztása. Azaz, hogy az egyes
tantárgyakat, ki tanítja, és heti hány órában. A tantárgyfelosztás táblázatának
utolsó sorában jelenjen meg az osztályban hetente tartott összes pedagógus óra.
A tantárgyfelosztáson mozogva az osztályórarenden aláhúzás karakterek jelennek
meg azokban az órákban, ahova a tétel beírható. Ha egy tétel csoportbontásban szerepel,
akkor a jelölés az osztályórarend mindkét sorában látható, valamint külön
megjelenik a másik pedagógus neve. Ha egy tételből órák vannak beírva, akkor az
órarendben a megfelelő óra lila háttérszínnel jelenik meg.
- Az
osztályok órarendjét két sorban jelenítsük meg a képernyőn. A két sorra a
csoportbontás miatt van szükség. A képernyőn csak a pedagógusok nevének
rövidítése fog megjelenni (csoportbontáskor kettő). Ha a tantárgyra is
kíváncsiak vagyunk, akkor kattintsunk a kérdéses órán, így a tantárgyfelosztáson
a megfelelő tétel kiválasztódik, melyből a tétel óraszáma is látható.
-
Óra beírásának menete: válasszuk ki az órarendben az osztályt és azon belül azt
is, hogy mely időpontba szeretnénk órát beírni. Ekkor a tantárgyfelosztás
táblázat a kiválasztott osztály tantárgyfelosztását fogja tartalmazni.
Válasszuk ki a beírandó tételt a tantárgyfelosztásban. Ekkor láthatóvá válik,
hogy mely időpontokba írható be a tétel. Nézzük meg, hogy az órarendben a
kiválasztott helyen aláhúzás karakter látható-e, ez jelzi a beírhatóságot. Ha
igen, akkor kettős kattintással a tételből egy óra a kiválasztott időpontra
beírásra kerül. A tantárgyfelosztás felett látható, hogy a tételből hány óra
van már Beírva. Természetesen a tétel óraszámánál több órát nem enged a program
beírni.
-
Órát törölni az órarendből úgy kell, hogy egy beírt órán kettőt kattintunk.
-
Ha olyan helyen kattintunk kettőt az órarendben, ahol nincs óra, akkor az az
óra tiltott óra lesz, melyet az órarend fehér háttérszínnel jelöl, míg a
megengedett órák jelölése szürke háttérszínnel történik. Ha tiltott órán
kattintunk kettőt, akkor a tiltás megszűnik. Ha több osztályra szeretnénk
tiltást beállítani vagy megszüntetni, akkor álljunk egy olyan osztályra és
órára, amelyiktől, és amelyik órára a beállítás vonatkozik, kettős kattintással
állítsuk be a szükséges állapotot, lépjünk vissza a kérdéses helyre, majd
nyomjuk meg a ToEnd nyomógombot, melynek hatására a kérdéses osztálytól az
utolsó osztályig a beállítás érvényes lesz. (Hasonlóan az óratervben alkalmazható
ToEnd feltöltéshez.) Az órarendből látható, hogy az első évfolyamnak C6 és P6
órája, a második évfolyamnak P6, míg a negyedik évfolyamnak C6 órája nem lehet.
Lássuk az Osztályórarend képernyőjét:
Az
Osztályórarendet az UOOR unit tartalmazza, melynek listája:
unit UPOR;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, UAdat, UModul,
Dialogs, StdCtrls, Grids;
type
TfmPOR = class(TForm)
lbPOR: TLabel;
btKilepes: TButton;
sgTFOR: TStringGrid;
edPeda: TEdit;
lbPeda: TLabel;
sgPTF: TStringGrid;
lbBeirva: TLabel;
lbBeirvaSz: TLabel;
lbMPeda: TLabel;
lbHely: TLabel;
btUpLoad: TButton;
btDelAll: TButton;
lbKeszVege: TLabel;
btRendez: TButton;
lbMax: TLabel;
edMax: TEdit;
edLSz: TEdit;
lbBad: TLabel;
lbBest: TLabel;
edBest: TEdit;
lbStart: TLabel;
edStart: TEdit;
lbStop: TLabel;
edStop: TEdit;
lbH: TLabel;
lbMP: TLabel;
btDelXX: TButton;
edRest: TEdit;
lbR: TLabel;
lbInfo: TLabel;
Function VoltPedaNev(St: St3): Boolean;
Procedure PORKepre;
Procedure PTFKepre(Peda: Word);
Function Utkozes(I,P: Word): Word;
Procedure Utkozesek;
Procedure UtkKepre;
Procedure Csere(I1,I2,P: Word);
Procedure Keveres(Sender: TObject);
Procedure Csoportok;
Function HibaLista: Word;
Procedure KetOra;
Procedure OsztOsz;
Procedure PHetiOSz;
Procedure HORend;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
procedure FormCreate(Sender: TObject);
procedure sgTFORClick(Sender: TObject);
procedure edPedaKeyPress(Sender: TObject; var Key: Char);
procedure sgPTFClick(Sender: TObject);
procedure sgPTFDblClick(Sender: TObject);
procedure sgTFORDblClick(Sender: TObject);
procedure btUpLoadClick(Sender: TObject);
procedure btDelAllClick(Sender: TObject);
procedure btRendezClick(Sender: TObject);
procedure btDelXXClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmPOR: TfmPOR;
Ind, Zero: Array[1..HOSz*PMax,1..2] Of Word;
Lanc: Array[0..PMax+1] Of Word;
PBeir, PUtk, Cso, PCso: Array[0..HOSz+1,0..PMax+1] Of Word;
PPOR: Array[0..HOSz+1,0..PMax+1,0..4] Of Word;
Leh, ULeh: Array[1..HOSz] Of Word;
UtkOsz, OldUtkOSz, PUtkOSz, Rest, Valt: Word;
LSz, LMax: LongInt;
implementation
{$R *.dfm}
procedure TfmPOR.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmPOR.btKilepesClick(Sender: TObject);
begin
Close;
end;
Function TfmPOR.VoltPedaNev(St: St3): Boolean;
Var P: Word;
Begin
VoltPedaNev:= False; If (St='-') Or (St='') Then Exit;
With sgTFOR Do For P:= 1 To RowCount-2 Do If St=Cells[0,P] Then
Begin VoltPedaNev:= True; Break End;
End;
procedure TfmPOR.sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
begin
With sgTFOR.Canvas.Brush Do
Begin
If (gdFixed In State) And ((Col=Acol) Or (Row=ARow)) Then
Color:= clYellow Else Color:= clBtnFace;
If gdSelected In State Then Color:= clLime;
If Not((gdSelected In State) Or (gdFixed In State)) Then
Begin
Case Col Of
2..7,12..17,22..27,32..37,42..47: Color:= RGB(232,232,232);
Else Color:= clWindow;
End;
If PBeir[Col,Row]=1 Then Color:= clFuchsia Else
If PUtk[Col,Row]=KetO Then Color:= RGB($DF,$B0,$20) Else
If PUtk[Col,Row]>0 Then Color:= clRed;
End;
End;
sgTFOR.Canvas.TextRect(Rect,Rect.Left,Rect.Top,sgTFOR.Cells[Col,Row]);
If gdFocused In State Then sgTFOR.Canvas.DrawFocusRect(Rect);
end;
procedure TfmPOR.sgTFORClick(Sender: TObject);
Var I, P, T: Word;
begin
With sgTFOR Do
Begin
If Col=ColCount-1 Then Col:= ColCount-2;
If Row=RowCount-1 Then Row:= RowCount-2;
For I:= 1 To HOSz Do For P:= 1 To PMax Do If Cells[I,P]=Jel
Then Cells[I,P]:= '';
edPeda.Text:= Cells[0,Row]; ACol:= Col; ARow:= Row; RePaint;
APeda:= Row; AIdop:= Col; PTFKepre(Row);
End;
With sgPTF Do With ATFOR Do If POra[AIdop,APeda,1] In [1..TMax] Then
Begin
For T:= 1 To RowCount-2 Do
If (POra[AIdop,APeda,1]=TNevToInd(Cells[0,T])) And
(POra[AIdop,APeda,2]=ONevToInd(Cells[1,T])) Then
Begin Row:= T; Break End;
End;
sgPTF.Repaint; lbMPeda.Repaint; edPeda.Repaint; lbHely.Repaint;
sgPTFClick(Sender);
end;
procedure TfmPOR.FormCreate(Sender: TObject);
Var I, J: Word;
begin
ACol:= 1; ARow:= 1; Valt:= 0; LMax:= 200000; PUtkOSz:= 65000;
For I:= 1 To HOSz*PMax Do For J:= 1 To 2 Do Zero[I,J]:= 0; Ind:= Zero;
For I:= 1 To HOSz Do Leh[I]:= 0; ULeh:= Leh;
With sgTFOR Do With ATFOR Do
Begin
ColWidths[0]:= 25; ColWidths[ColCount-1]:= 24;
Cells[ColCount-1,0]:= 'Sum'; Cells[0,RowCount-1]:= 'Sum';
For I:= 1 To HOSz Do Cells[I,0]:= INev[I];
End;
Csoportok; PORKepre; sgTFORClick(Sender);
With sgPTF Do
Begin
Cells[0,0]:= 'Tant'; Cells[1,0]:= 'Oszt'; Cells[2,0]:= 'Órsz';
End;
end;
Procedure TfmPOR.PORKepre;
Var I, P, S, Sz: Word;
St: St3;
Begin
With sgTFOR Do With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do Cells[I,P]:= '';
For P:= 1 To PMax Do Cells[0,P]:= PRov[P];
For P:= 1 To PMax Do
Begin
S:= 0;
For I:= 1 To HOSz Do
Begin
St:= ONev[POra[I,P,2]]; If Cso[I,P]>0 Then St:= UpONev(St);
If POra[I,P,1]<>Tilt Then
Cells[I,P]:= St Else Cells[I,P]:= 'XX';
If POra[I,P,1] In [1..TMax] Then Inc(S);
End; Cells[ColCount-1,P]:= IntToStr(S);
End;
Sz:= 0;
For I:= 1 To HOSz Do
Begin
S:= 0;
For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
Begin Inc(S); Inc(Sz) End; Cells[I,RowCount-1]:= IntToStr(S);
End; Cells[ColCount-1,RowCount-1]:= IntToStr(Sz);
End;
End;
Procedure TfmPOR.PTFKepre(Peda: Word);
Var O, T, S, Sz: Word;
Begin
With sgPTF Do With ATFOR Do
Begin
S:= 0; Sz:= 0;
For O:= 0 To ColCount-1 Do For T:= 1 To RowCount-2 Do Cells[O,T]:= '';
For O:= 1 To OMax Do For T:= 1 To TMax Do
If OTer[O,T,1]<>0 Then If (OTer[O,T,3]=Peda) Or (OTer[O,T,4]=Peda) Then
Begin
Inc(S); sgPTF.Cells[0,S]:= TNev[T]; sgPTF.Cells[1,S]:= ONev[O];
sgPTF.Cells[2,S]:= IntToStr(OTer[O,T,1]); Inc(Sz,OTer[O,T,1]);
End;
With sgPTF Do
Begin
Cells[0,RowCount-1]:= IntToStr(PKot[Peda]);
Cells[1,RowCount-1]:= IntToStr(PNOT[Peda]);
Cells[2,RowCount-1]:= IntToStr(Sz);
End;
End;
End;
Function TfmPOR.Utkozes(I,P: Word): Word;
Var K, KI, I1: Word;
Begin
With ATFOR Do
Begin
PUtk[I,P]:= 0; Utkozes:= PUtk[I,P]; If POra[I,P,1] In [0,Tilt] Then Exit;
If (POra[I,P,1]<>0) And (OLeh[I,2*POra[I,P,2]-1]=0) Then Inc(PUtk[I,P],2);
For K:= 1 To PMax Do If (K<>P) And (POra[I,K,2]<>0) Then
Begin
If (Cso[I,K]=0) And (POra[I,K,2]=POra[I,P,2]) Then Inc(PUtk[I,P]) Else
If (K<>Cso[I,P]) And (POra[I,K,2]=POra[I,P,2]) Then Inc(PUtk[I,P]);
End;
I1:= NOSz*((I-1) Div NOSz)+1;
For K:= I1 To I1+NOSz-1 Do If (K<>I) And (POra[K,P,1]<>0) Then
If (POra[K,P,1]=POra[I,P,1]) And (POra[K,P,2]=POra[I,P,2]) Then
Inc(PUtk[I,P]);
If OTer[POra[I,P,2],POra[I,P,1],1]=2 Then
Begin
KI:= 0;
For K:= 1 To HOSz Do If (K<>I) Then
If (POra[K,P,1]=POra[I,P,1]) And (POra[K,P,2]=POra[I,P,2]) Then
Begin KI:= K; Break End;
If Abs(((I-1) Div NOsz)-((KI-1) Div NOSz))=1 Then Inc(PUtk[I,P]);
End;
End; Utkozes:= PUtk[I,P];
End;
Procedure TfmPOR.Utkozesek;
Var I, P: Word;
Begin
UtkOsz:= 0;
For I:= 1 To HOSz Do For P:= 1 To PMax Do Inc(UtkOsz,Utkozes(I,P));
End;
Procedure TfmPOR.UtkKepre;
Var I, P, Sz: Word;
Begin
With sgTFOR Do For I:= 1 To HOSz Do
Begin
Sz:= 0; For P:= 1 To PMax Do Inc(Sz,PUtk[I,P]);
Cells[I,RowCount-1]:= IntToStr(Sz);
End;
If Valt= 100 Then Valt:= 1;
If Valt>0 Then With sgPTF do
Begin
Col:= (Valt-1) Mod 3;
Row:= (Valt-1) Div 3+1;
Cells[Col,Row]:= IntToStr(UtkOSz);
End; lbKeszVege.Caption:= IntToStr(UtkOSz);
End;
Procedure TfmPOR.Csere(I1,I2,P: Word);
Var K, Puf: Word;
Lehet: Boolean;
Begin
With ATFOR Do
Begin
If (POra[I1,P,4]=1) Or (POra[I2,P,4]=1) Then Exit;
If (POra[I1,P,1]=POra[I2,P,1]) And (POra[I1,P,2]=POra[I2,P,2]) Then Exit;
If Cso[I1,P]+Cso[I2,P]=0 Then
Begin
Puf:= POra[I1,P,1]; POra[I1,P,1]:= POra[I2,P,1]; POra[I2,P,1]:= Puf;
Puf:= POra[I1,P,2]; POra[I1,P,2]:= POra[I2,P,2]; POra[I2,P,2]:= Puf;
Puf:= POra[I1,P,4]; POra[I1,P,4]:= POra[I2,P,4]; POra[I2,P,4]:= Puf;
Puf:= Cso[I1,P]; Cso[I1,P]:= Cso[I2,P]; Cso[I2,P]:= Puf; Exit;
End Else
Begin
For K:= 0 To PMax Do Lanc[K]:= 0; Lanc[P]:= 1;
Puf:= Cso[I1,P]; K:= 1;
While (Puf<>0) And (K<=PMax) Do
Begin
Lanc[Puf]:= 1;
If Odd(K) Then Puf:= Cso[I2,Puf] Else Puf:= Cso[I1,Puf]; Inc(K);
End;
Puf:= Cso[I2,P]; K:= 1;
While (Puf<>0) And (K<=PMax) Do
Begin
Lanc[Puf]:= 1;
If Odd(K) Then Puf:= Cso[I1,Puf] Else Puf:= Cso[I2,Puf]; Inc(K);
End;
Lehet:= True;
For K:= 1 To PMax Do If Lanc[K]>0 Then
If (POra[I1,K,4]=1) Or (POra[I2,K,4]=1) Then
Begin Lehet:= False; Break End;
If Lehet Then For K:= 1 To PMax Do If Lanc[K]>0 Then
Begin
Puf:= POra[I1,K,1]; POra[I1,K,1]:= POra[I2,K,1]; POra[I2,K,1]:= Puf;
Puf:= POra[I1,K,2]; POra[I1,K,2]:= POra[I2,K,2]; POra[I2,K,2]:= Puf;
Puf:= POra[I1,K,4]; POra[I1,K,4]:= POra[I2,K,4]; POra[I2,K,4]:= Puf;
Puf:= Cso[I1,K]; Cso[I1,K]:= Cso[I2,K]; Cso[I2,K]:= Puf;
End;
End;
End;
End;
Procedure TfmPOR.Keveres(Sender: TObject);
Var K, I1, I2, P: Word;
Begin
If (Rest Mod NaSz)=0 Then btUpLoadClick(Sender) Else With ATFOR Do
For P:= 1 To PMax Do For K:= 1 To 2*(((Rest-1) Mod NaSz)+1) Do
Begin
I1:= Random(HOsz)+1; I2:= Random(HOSz)+1;
If Rest Mod NaSz>2 Then While (POra[I1,P,4]=1) Or (POra[I2,P,4]=1) Do
Begin I1:= Random(HOsz)+1; I2:= Random(HOSz)+1 End Else
While (POra[I1,P,4]=1) Or (POra[I2,P,4]=1) Or
(Cso[I1,P]>0) Or (Cso[I2,P]>0) Do
Begin I1:= Random(HOsz)+1; I2:= Random(HOSz)+1 End;
Csere(I1,I2,P);
End;
End;
Procedure TfmPOR.Csoportok;
Var I, P, k: Word;
Begin
With sgTFOR Do With ATFOR Do
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
For K:= 1 To PMax Do If K<>P Then
If (POra[I,K,1]=POra[I,P,1]) And (POra[I,K,2]=POra[I,P,2]) Then Cso[I,P]:= K;
End;
Function TfmPOR.HibaLista: Word;
Var I, P, K: Word;
Begin
Ind:= Zero; K:= 0; With ATFOR Do For I:= 1 To HOSz Do For P:= 1 To PMax Do
If (PUtk[I,P]>0) And (POra[I,P,4]<>1) Then
Begin Inc(K); Ind[K,1]:= I; Ind[K,2]:= P End; HibaLista:= K;
End;
procedure TfmPOR.edPedaKeyPress(Sender: TObject; var Key: Char);
begin
If Key=#13 Then
With sgTFOR Do With edPeda Do If Not VoltPedaNev(Text) Then
Begin
If Text='' Then Text:= '-'; Cells[0,Row]:= Text; ATFOR.PRov[Row]:= Text;
If Row<RowCount-2 Then Row:= Row+1;
End;
end;
procedure TfmPOR.sgPTFClick(Sender: TObject);
Var I, P, P1, P2, PP, Sz: Word;
Van: Boolean;
begin
With sgPTF Do Begin
If (Valt=0) And (Row=RowCount-1) Then Row:= RowCount-2 End;
MPeda:= 0; Sz:= 0; lbBeirvaSz.Caption:= '0';
For I:= 0 To HOSz Do For P:= 0 To PMax+1 Do PBeir[I,P]:= 0;
With sgTFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do
If Cells[I,P]=Jel Then Cells[I,P]:= ''; P1:= Row;
End;
P2:= 0; PP:= 0;
With sgPTF Do
Begin
ATant:= TNevToInd(Cells[0,Row]); AOszt:= ONevToInd(Cells[1,Row]);
lbHely.Caption:= ATFOR.HNev[TTetToHely(AOszt,ATant)];
End;
With ATFOR Do
If OTer[AOszt,ATant,1]*OTer[AOszt,ATant,2]>0 Then
Begin
If OTer[AOszt,ATant,3]=P1 Then Begin P2:= OTer[AOszt,ATant,4]; PP:= P2 End
Else If OTer[AOszt,ATant,4]=P1 Then
Begin P1:= OTer[AOszt,ATant,3]; PP:= P1; P2:= OTer[AOszt,ATant,4] End;
lbMPeda.Caption:= ATFOR.PRov[PP];
End Else Begin P2:= 0; lbMPeda.Caption:= '- ' End;
With sgPTF Do If Cells[0,Row]<>'' Then With ATFOR Do
Begin
For I:= 1 To HOSz Do
If (TNev[POra[I,P1,1]]= Cells[0,Row]) And (POra[I,P1,2]=AOszt) Then
Begin Inc(Sz); PBeir[I,P1]:= 1; If P2<>0 Then PBeir[I,P2]:= 1 End;
lbBeirvaSz.Caption:= IntToStr(Sz);
If P2=0 Then
Begin
For I:= 1 To HOSz Do If POra[I,P1,1]=0 Then
Begin
Van:= False; For P:= 1 To PMax Do If POra[I,P,2]=AOszt Then
Begin Van:= True; Break End;
If Not Van Then Begin sgTFOR.Cells[I,P1]:= Jel End;
End;
End Else
For I:= 1 To HOSz Do If (POra[I,P1,1]=0) And (POra[I,P2,1]=0) Then
Begin
Van:= False; For P:= 1 To PMax Do If POra[I,P,2]=AOszt Then
Begin Van:= True; Break End; If Not Van Then
Begin sgTFOR.Cells[I,P1]:= Jel; sgTFOR.Cells[I,P2]:= Jel End;
End;
End; MPeda:= PP; sgTFOR.Repaint; lbBeirvaSz.Repaint; lbHely.Repaint;
end;
procedure TfmPOR.sgPTFDblClick(Sender: TObject);
begin
With sgPTF Do If lbBeirvaSz.Caption>=Cells[2,Row] Then Exit;
With sgTFOR Do If Cells[Col,Row]<>Jel Then Exit;
With sgTFOR Do With ATFOR Do
Begin
POra[Col,Row,1]:= TNevToInd(sgPTF.Cells[0,sgPTF.Row]);
POra[Col,Row,2]:= ONevToInd(sgPTF.Cells[1,sgPTF.Row]);
POra[Col,Row,3]:= TTetToHely(POra[Col,Row,2],POra[Col,Row,1]);
POra[Col,Row,4]:= 1;
If MPeda>0 Then
Begin
POra[Col,MPeda,1]:= TNevToInd(sgPTF.Cells[0,sgPTF.Row]);
POra[Col,MPeda,2]:= ONevToInd(sgPTF.Cells[1,sgPTF.Row]);
POra[Col,MPeda,3]:= TTetToHely(POra[Col,MPeda,2],POra[Col,MPeda,1]);
POra[Col,MPeda,4]:= 1;
Cso[Col,APeda]:= MPeda; Cso[Col,MPeda]:= APeda;
End;
If Col<ColCount-2 Then Col:= Col+1;
End; PORKepre; sgPTFClick(Sender);
end;
procedure TfmPOR.sgTFORDblClick(Sender: TObject);
Var I, P, KI: Word;
Mind: Boolean;
begin
With sgTFOR Do With ATFOR Do
Begin
Case POra[Col,Row,1] Of
0: Begin
KI:= NOSz*((Col-1) Div NOSz)+1; Mind:= True;
For I:= KI To KI+NOSz-1 Do If POra[I,Row,1]<>0 Then
Begin Mind:= False; Break End;
If ((Col-1) Mod NOSz=0) And Mind Then
For I:= KI To KI+NOSz-1 Do
Begin POra[I,Row,1]:= Tilt; POra[I,Row,4]:= 1 End
Else Begin POra[Col,Row,1]:= Tilt; POra[Col,Row,4]:= 1 End;
End;
Tilt: Begin
KI:= NOSz*((Col-1) Div NOSz)+1; Mind:= True;
For I:= KI To KI+NOSz-1 Do If POra[I,Row,1]<>Tilt Then
Begin Mind:= False; Break End;
If ((Col-1) Mod NOSz=0) And Mind Then
For I:= KI To KI+NOSz-1 Do
Begin POra[I,Row,1]:= 0; POra[I,Row,4]:= 0 End
Else Begin POra[Col,Row,1]:= 0; POra[Col,Row,4]:= 0 End;
End;
1..TMax: Begin
MPeda:= 0;
For P:= 1 To PMax Do If P<>Row Then
If (POra[Col,P,1]=POra[Col,Row,1]) And
(POra[Col,P,2]=POra[Col,Row,2]) Then
Begin MPeda:= P; Break End;
For I:= 1 To 4 Do POra[Col,Row,I]:= 0;
If MPeda<>0 Then For I:= 1 To 4 Do POra[Col,MPeda,I]:= 0;
End;
End; If Col<ColCount-2 Then Col:= Col+1;
End; PORKepre; sgPTFClick(Sender);
end;
procedure TfmPOR.btDelAllClick(Sender: TObject);
Var I, P, K: Word;
begin
With ATFOR Do For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do
Begin
PBeir[I,P]:= 0; PUtk[I,P]:= 0;
If POra[I,P,4]=2 Then For K:= 0 To 4 Do POra[I,P,K]:= 0;
End; PORKepre;
end;
procedure TfmPOR.btDelXXClick(Sender: TObject);
Var I, P: Word;
begin
With ATFOR Do For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do
If POra[I,P,1]=Tilt Then POra[I,P,1]:= 0; PORKepre;
end;
procedure TfmPOR.btUpLoadClick(Sender: TObject);
Var O, T, P, I, N, S: Word;
begin
Csoportok;
With sgTFOR Do With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,4]<>1 Then
Begin Cso[I,P]:= 0; For N:= 0 To 4 Do POra[I,P,N]:= 0 End;
For O:= 1 To OMax Do For T:= 1 To TMax Do
Begin
APeda:= OTer[O,T,3]; MPeda:= OTer[O,T,4]; I:= Random(HOSz)+1;
If MPeda<>0 Then
Begin
S:= OTer[O,T,1]-PORBeirt(APeda,T,O);
For N:= 1 To S Do
Begin
While (POra[I,APeda,1]<>0) Or (POra[I,MPeda,1]<>0) Do
I:= Random(HOSz)+1;
POra[I,APeda,1]:= T; POra[I,APeda,2]:= O; POra[I,APeda,4]:= 2;
POra[I,MPeda,1]:= T; POra[I,MPeda,2]:= O; POra[I,MPeda,4]:= 2;
Cso[I,APeda]:= MPeda; Cso[I,MPeda]:= APeda;
End;
End Else
If MPeda=0 Then
Begin
S:= OTer[O,T,1]-PORBeirt(APeda,T,O);
For N:= 1 To S Do
Begin
While POra[I,APeda,1]<>0 Do I:= Random(HOsz)+1;
POra[I,APeda,1]:= T; POra[I,APeda,2]:= O; POra[I,APeda,4]:= 2;
End;
End;
End;
End; Utkozesek; PORKepre; UtkKepre;
end;
Procedure TfmPOR.KetOra;
Var P, I, K: Word;
Begin
With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do PUtk[I,P]:= 0;
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
If OTer[POra[I,P,2],POra[I,P,1],1]=2 Then For K:= 1 To HOSz Do
If (POra[I,P,1]=POra[K,P,1]) And (POra[I,P,1]=POra[K,P,1]) Then
PUtk[I,P]:= KetO;
End;
End;
Procedure TfmPOR.OsztOSz;
Var I, P, S: Word;
Begin
With sgTFOR Do For I:= 1 To HOSz Do
Begin
S:= 0; For P:= 1 To PMax Do
If (Cells[I,P]<>'') And (Cells[I,P]<>'XX') Then Inc(S);
Cells[I,RowCount-1]:= IntToStr(S);
End;
End;
Procedure TfmPOR.PHetiOSz;
Var O, T, P: Word;
Begin
For P:= 0 To PMax+1 Do PHOsz[P]:= 0; With ATFOR Do
For O:= 1 To OMax Do For T:= 1 To TMax Do If OTer[O,T,1]>0 Then
Begin
Inc(PHOSz[OTer[O,T,3]],OTer[O,T,1]); Inc(PHOSz[OTer[O,T,4]],OTer[O,T,2]);
End;
End;
Procedure TfmPOR.HORend;
Var I, P, P1, K: Word;
L: Integer;
Begin
With ATFOR Do
Begin
For I:= 1 To HOSz Do For P:= 1 To PMax Do
Begin
POra[I,P,3]:= 0; If POra[I,P,1] In [1..TMax] Then
POra[I,P,3]:= TTetToHely(POra[I,P,2],POra[I,P,1]);
End;
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,1] In [1..TMax] Then
For P1:= 1 To PMax Do If (P1<>P) And (POra[I,P1,3]=POra[I,P,3]) Then
Begin
AHely:= Pora[I,P1,3]; POra[I,P1,3]:= 0;
For K:= 1 To HMax Div 2+1 Do
Begin
L:= 0; If Odd(K) Then L:= AHely-K; If L<1 Then L:= HMax;
If Not Odd(K) Then L:= AHely+K; If L>HMax Then L:= 1;
If UresHely(I,L) Then POra[I,P1,3]:= L;
End;
End;
End;
End;
procedure TfmPOR.btRendezClick(Sender: TObject);
Var I, I1, P, K, A, Index, RIndex, Ismet, KIsm, VIsm: Word;
Volt: Boolean;
begin
PHetiOSz;
With sgPTF Do
Begin
Row:= RowCount-2; sgPTFClick(Sender);
For I:= 0 To ColCount-1 Do For K:= 1 To RowCount-1 Do Cells[I,K]:= '';
Valt:= 0; RePaint;
End;
PUtkOSz:= 65000; edStart.Text:= TimeToStr(GetTime); edStart.Repaint;
edStop.Text:= ''; edStop.Repaint;
LSz:= 0; Volt:= False; OldUtkOSz:= 0; Ismet:= 0; Rest:= 0;
lbKeszVege.Caption:= ''; Index:= HibaLista;
With ATFOR Do While (Index>0) And (LSz<LMax) Do
Begin
If OldUtkOSz=UtkOSz Then
Begin
Inc(Ismet); If Ismet>2500 Then
Begin
Ismet:= 0; If UtkOSz<=PUtkOSz Then
Begin
PUtkOSz:= UtkOSz;
For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do For K:= 0 To 4 Do
PPOR[I,P,K]:= POra[I,P,K]; PCSO:= CSO;
edBest.Text:= IntToStr(PUtkOSz);
End;
Inc(Rest); Inc(Valt); edRest.Text:= IntToStr(Rest+1); Keveres(Sender);
Utkozesek; PORKepre; UtkKepre; edLSz.Text:= IntToStr(LSz); RePaint;
Index:= HibaLista;
End;
End Else Ismet:= 0; Inc(LSz);
//A<->b típusú csere
If Volt Then Index:= Hibalista; A:= UtkOSz; OldUtkOSz:= A;
RIndex:= Random(Index)+1; I:= Ind[RIndex,1]; P:= Ind[RIndex,2];
For K:= 1 To 2 Do
If (Cso[I,P]=0) Or (OTer[POra[I,P,2],POra[I,P,1],1]<4) Or
(PHOsz[P]<OSzM-4) Then
Begin RIndex:= Random(Index)+1; I:= Ind[RIndex,1]; P:= Ind[RIndex,2] End;
Leh:= ULeh; KIsm:= 0; Leh[I]:= 1;
If UtkOSz<HOSz Then VIsm:= HOSz-UtkOSz Else VIsm:= 2;
While KIsm<VIsm Do
Begin
Inc(KIsm); I1:= Random(HOsz)+1;
While (Leh[I1]=1) Or (I=I1) Do I1:= Random(HOsz)+1;
Leh[I1]:= 1; Csere(I,I1,P); Utkozesek;
If UtkOSz>A Then Begin Csere(I,I1,P); Utkozesek; Volt:= False End
Else Begin KIsm:= HOSz; Volt:= True End;
End;
If LSz Mod 1000=0 Then
Begin
PORKepre; Inc(Valt); UtkKepre; edLSz.Text:= IntToStr(LSz); Repaint;
End;
End;
With ATFOR Do If (UtkOSz>0) And (UtkOSz>=PUtkOSz) Then
Begin
edBest.Text:= IntToStr(PUtkOSz);
For I:= 0 To HOSz+1 Do For P:= 0 To PMax+1 Do For K:= 0 To 4 Do
POra[I,P,K]:= PPOR[I,P,K]; CSO:= PCSO; Utkozesek;
End
Else edBest.Text:= IntToStr(UtkOSz);
PORKepre; UtkKepre; edLSz.Text:= IntToStr(LSz);
With lbKeszVege Do If UtkOSz=0 Then
Begin KetOra; OsztOSz; HORend; Caption:= 'OK' End Else Caption:= 'End';
edStop.Text:= TimeToStr(GetTime); Valt:= 0;
end;
end.
Kódolás (6)
Folytassuk a kódolást a Tanteremórarenddel. Ezen a felületen a következő beavatkozások
lehetségesek:
-
Az tantermek jele módosítható a beviteli mező segítségével. A kiválasztott
sorban található tanterem jele írható át. Az tanterem jele maximum 3 karakter
lehet. A beírást Enter billentyűvel kell lezárni. Ha üres stringet adunk meg,
akkor az egy ’-’ jelre módosul. Nem lehet két tanteremnek ugyanaz a jele.
-
Minden tanterem órarendje egyetlen sorban jelenik meg a képernyőn. Az órát
leíró azonosítókból csak a pedagógus neve látható. Ha a teljes tétel leírását
meg szeretnénk tudni, akkor kattintani kell a kérdéses órán, aminek hatására a
képernyő jobb oldalán az megjelenik (tantárgy, osztály, pedagógus).
-
Mivel a gépi betöltő a bizonytalan tantermű tételekhez csak az órarend
elkészítése végén keres tantermet, lehet, hogy a kézi betöltés ideje alatt még
két pedagógus (azaz tétel) is kerülhet egy tanterembe, ugyanarra az időpontra.
Ezeket a helyeket az órarendben lila háttérszín jelöli. Egy ilyen helyre
kattintva a tétel részletezésekor két pedagógus nevét látjuk, a másodikat piros
színnel.
-
Ha a tanteremórarenden kettőt kattintunk, akkor a következők történhetnek: ha
az adott helyen nem volt bejegyzés, akkor a terem időponttiltása ellenkezőjére
változik (ha nem volt tiltott, akkor tiltott lesz, ha tiltott volt, akkor nem
lesz tiltás). A tiltott óra háttérszíne fehér, a nem tiltotté szürke. Itt is
lehetőség van (az óraterv és az osztályórarendhez hasonlóan) a ToEnd gomb
segítségéve egy adott időpontban az aktuális tanteremtől az utolsó tanteremig a
tiltás beállítására illetve feloldására. Ha pedig volt pedagógusnév az
órarendben, akkor a megfelelő tételnek, a kiválasztott időpontra nem lesz
beosztott tanterme. A tanteremórarend lapon további beavatkozásra nincs
(egyelőre) lehetőség.
A Tanteremórarend képernyője:
A
Tanteremórarendet az UHOR Unit tartalmazza, melynek listája:
unit UHOR;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms,
UAdat, UModul, Dialogs, StdCtrls, Grids;
type
TfmHOR = class(TForm)
lbHOR: TLabel;
btKilepes: TButton;
sgTFOR: TStringGrid;
edHely: TEdit;
lbHely: TLabel;
lbTant: TLabel;
lbOszt: TLabel;
lbPeda: TLabel;
lbMPeda: TLabel;
btToEnd: TButton;
Function VoltHelyNev(St: St3): Boolean;
Procedure HORKepre;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure sgTFORDblClick(Sender: TObject);
procedure sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
procedure FormCreate(Sender: TObject);
procedure sgTFORClick(Sender: TObject);
procedure edHelyKeyPress(Sender: TObject; var Key: Char);
procedure btToEndClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmHOR: TfmHOR;
HUtkz: Array[0..HOSz+1,0..HMax+1] Of Word;
implementation
{$R *.dfm}
procedure TfmHOR.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmHOR.btKilepesClick(Sender: TObject);
begin
Close;
end;
Function TfmHOR.VoltHelyNev(St: St3): Boolean;
Var H: Word;
Begin
VoltHelyNev:= False; If (St='-') Or (St='') Then Exit;
With sgTFOR Do For H:= 1 To RowCount-2 Do If St=Cells[0,H] Then
Begin VoltHelyNev:= True; Break End;
End;
procedure TfmHOR.sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
begin
With sgTFOR.Canvas.Brush Do
Begin
If (gdFixed In State) And ((Col=Acol) Or (Row=ARow)) Then
Color:= clYellow Else Color:= clBtnFace;
If gdSelected In State Then Color:= clLime;
If Not((gdSelected In State) Or (gdFixed In State)) Then With ATFOR Do
Begin
If HLeh[Col,Row]=1 Then Color:= RGB(232,232,232) Else Color:= clWindow;
If HUtkz[Col,Row]=1 Then Color:= clFuchsia;
End;
End;
sgTFOR.Canvas.TextRect(Rect,Rect.Left+1,Rect.Top,sgTFOR.Cells[Col,Row]);
If gdFocused In State Then sgTFOR.Canvas.DrawFocusRect(Rect);
end;
procedure TfmHOR.FormCreate(Sender: TObject);
Var I: Word;
begin
ACol:= 1; ARow:= 1;
With sgTFOR Do With ATFOR Do
Begin
ColWidths[0]:= 25; ColWidths[ColCount-1]:= 24;
Cells[ColCount-1,0]:= 'Sum'; Cells[0,RowCount-1]:= 'Sum';
For I:= 1 To HOSz Do Cells[I,0]:= INev[I];
End;
HORKepre; sgTFORClick(Sender);
end;
Procedure TfmHOR.HORKepre;
Var I, P, H, S: Word;
Begin
With sgTFOR Do With ATFOR Do
Begin
For I:= 1 To HOSz Do For H:= 1 To HMax Do Cells[I,H]:= '';
For I:= 0 To HOSz+1 Do For H:= 0 To HMax+1 Do HUtkz[I,H]:= 0;
For H:= 1 To HMax Do Cells[0,H]:= HNev[H];
For P:= 1 To PMax Do For I:= 1 To HOSz Do
If POra[I,P,1] In [1..TMax] Then
Begin
If Cells[I,POra[I,P,3]]='' Then Cells[I,POra[I,P,3]]:= PNev[P] Else
HUtkz[I,POra[I,P,3]]:= 1;
End;
For I:= 1 To HOSz Do
Begin
S:= 0; For H:= 1 To HMax Do If Cells[I,H]<>'' Then Inc(S);
Cells[I,RowCount-1]:= IntToStr(S);
End;
For H:= 1 To HMax Do
Begin
S:= 0; For I:= 1 To HOSz Do If Cells[I,H]<>'' Then Inc(S);
Cells[ColCount-1,H]:= IntToStr(S);
End;
S:= 0; For I:= 1 To HOSz Do Inc(S,StrToInt(Cells[I,RowCount-1]));
Cells[ColCount-1,RowCount-1]:= IntToStr(S);
End;
End;
procedure TfmHOR.sgTFORClick(Sender: TObject);
Var P: Word;
begin
With sgTFOR Do With ATFOR Do
Begin
If Col=ColCount-1 Then Col:= ColCount-2;
If Row=RowCount-1 Then Row:= RowCount-2;
edHely.Text:= Cells[0,Row]; ACol:= Col; ARow:= Row; RePaint;
APeda:= PNevToInd(Cells[Col,Row]); AIdop:= Col;
lbTant.Caption:= TNev[POra[AIdop,APeda,1]];
If POra[AIdop,APeda,2]<>0 Then
lbOszt.Caption:= ONev[POra[AIdop,APeda,2]] Else lbOszt.Caption:= '-';
lbPeda.Caption:= PNev[APeda];
lbMPeda.Caption:= '-';
If HUtkz[Col,Row]=1 Then
For P:= 1 To PMax Do If P<>APeda Then If POra[Col,P,3]=Row Then
Begin lbMPeda.Caption:= PNev[P]; Break End;
End;
end;
procedure TfmHOR.edHelyKeyPress(Sender: TObject; var Key: Char);
begin
If Key=#13 Then
With sgTFOR Do With edHely Do If Not VoltHelyNev(Text) Then
Begin
If Text='' Then Text:= '-'; Cells[0,Row]:= Text; ATFOR.HNev[Row]:= Text;
If Row<RowCount-2 Then Row:= Row+1;
End;
end;
procedure TfmHOR.sgTFORDblClick(Sender: TObject);
begin
With sgTFOR Do With ATFOR Do
Begin
If Cells[Col,Row]='' Then HLeh[Col,Row]:= 1-HLeh[Col,Row] Else
POra[Col,PNevToInd(Cells[Col,Row]),3]:= 0;
If Col<ColCount-2 Then Col:= Col+1;
End;
HORKepre;
end;
procedure TfmHOR.btToEndClick(Sender: TObject);
Var H: Word;
begin
With sgTFOR Do With ATFOR Do
Begin
If Row=RowCount-2 Then Exit;
For H:= Row+1 To HMax Do HLeh[Col,H]:= HLeh[Col,Row];
RePaint;
End;
end;
end.
Kódolás (7)
Térjünk vissza a Pedagógus
órarendre. A program legizgalmasabb része, a gépi órarend generálás
következik. A gépi feltöltésre átalakított Pedagógus órarend formja, melyen
néhány óra kézzel lett beírva, valamint a tiltások be vannak állítva:
A kibővített képernyő
új elemeinek magyarázata:
-
DelAll nyomógomb: megnyomva az órarend gépi betöltővel beírt órái törlődnek.
-
DelXX nyomógomb: az órarend foglalt óráinak foglaltsága megszűnik.
-
UpLoad nyomógomb: az órarendben még nem szereplő órák bekerülnek az órarendbe.
Helyük véletlen lesz, de a csoportbontásos órák egy időpontban lesznek.
-
Max: utáni beviteli mezőbe beírhatjuk, hogy maximálisan hány iterációs lépést
engedünk végrehajtani megállás nélkül a rendező algoritmusnak.
-
< Sort > nyomógomb: ezzel a gombbal indíthatjuk a rendezést.
-
A következő Edit mezőben jelenik meg, hogy hányadik lépésben jár az algoritmus
(minden ezrediket írja ki és ekkor frissíti a képernyőt).
-
R: utáni mezőben jelenik meg, hogy hányszor történt jelentős visszalépés (vagy újrakezdés)
a rendezésben.
-
Bad: utáni címke tartalma az utolsó frissítéskor érvényes hibapontok száma. Ez
a rendezés során nem nőhet és a pontszámítási eljárás miatt csak páros lehet.
Ezen a helyen jelenik meg az algoritmus végén az OK felírat, ha sikerült a
rendezés, ha pedig nem (ütközéses maradt az órarend), akkor End feíratot
láthatjuk.
-
Best: utáni mezőben a mentett legjobb órarend hibapontjainak számát láthatjuk.
Ha nem sikerül a teljes rendezés, akkor ezt az órarendet látjuk az algoritmus leállása
után.
-
Start: utáni mezőben a rendezés kezdő időpontja látható.
-
Stop: utáni mezőben a rendezés befejezésének időpontját láthatjuk.
-
Rendezés közben a pedagógus tantárgyfelosztása helyén az ezer lépésenkénti
hibapont-értékek jelennek meg, sorfolytonosan. Ha vége a rendezésnek és
kattintunk az órarenden, akkor újra a tantárgyfelosztás látható.
A képernyő az UpLoad megnyomása után, amikor minden
óra véletlen helyre bekerül az órarendbe:
Leolvasható a képernyőről a 2266 ütközési szám. A
piros háttérrel rendelkező helyek a hibásak. Vagy nem megengedett helyen vannak
(olyan időpontban, amikor az osztálynak már nem lehet órája), vagy ütköznek
(két pedagógus van egy osztályban, de nem csoportbontás miatt), vagy kétórás
tantárgy és egymás utáni napon van a két óra, vagy egyszerűen csak két
ugyanolyan óra van egy napon. A csoportbontásos órák az osztály jelben
nagybetűvel van jelölve.
Másfél perc alatt elkészült az órarend, ehhez 21228
lépésre volt szükség. Ezt egyetlen menetben, visszalépés nélkül sikerült
előállítani. Ez természetesn nem mindig van így. A jelentős visszalépést
jelentős számú cserét, minden ötödik visszalépés pedig teljes újratöltést
jelent. Az újrakezdések kezdőszámai a tantárgyfelosztás táblázatából lehetne
kiolvasni. Most csak a minden ezredik lépés utáni hibapontszámok sorozatát
látjuk ebben a táblázatban. Az órarendben az arany háttérszínnel jelölt órák
heti óraszáma kettő (így könnyebben ellenőrizhető, hogy kétórás tárgyakat nem
tesz két egymás utáni napra).
Nézzük
meg, hogy ez az órarend hogyan néz ki Osztályórarendben:
Most
pedig lássuk, milyen lett a Teremórarend:
Egy
másik feltöltés, ahol
A generáláshos most három perc és 41125
lépésre volt szükség. A generálás kétszer lépet vissza, újrakezdési ütközési
számok: 188 és 316.
Ezen az utóbbi fejlesztés nyomait láthatjuk az előző
állapothoz képest. Ha olyan tanterem, sorában állunk, amely valamely osztálynak
a tanterme, akkor az osztály neve megjelenik a táblázat felett (pl.: 1.a). A
következő változás: jobb oldalt megjelent egy táblázat, melyben azokat az órákat
láthatjuk, amelyekhez nincs tanterem hozzárendelve. Most csak a bemutatás
kedvéért töröltem három óra tantermét az 1.a osztályban. Ha a teremhiány
valamely nem üres során duplán kattintunk, akkor a teremórarendbe beírhatjuk az
érintett órát, feltéve, ha a kiválasztott terem a kérdéses időpontban üres
volt.
A másik fejlesztés az Up és Down feliratú gombokkal
használhatók. Az Up gomb megnyomására a program fölfelé (az első termek felé)
keres üres helyet, és ha talál, akkor ebbe a terembe áthelyezi a kiválasztott
órát. A Downn ellenkezőleg, az utolsó termek felé keres üres helyet, és ha van,
akkor oda helyezi át az órát. Így tanteremcseréket is megvalósíthatunk, ha egy
időpontban van legalább egy üres terem.
Az UHOR megváltozott listája:
unit UHOR;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms,
UAdat, UModul,
Dialogs, StdCtrls, Grids;
type
TfmHOR = class(TForm)
lbHOR: TLabel;
btKilepes: TButton;
sgTFOR: TStringGrid;
edHely: TEdit;
lbHely: TLabel;
lbTant: TLabel;
lbOszt: TLabel;
lbPeda: TLabel;
lbMPeda: TLabel;
btToEnd: TButton;
lbHiany: TLabel;
sgHiany: TStringGrid;
btUp: TButton;
btDown: TButton;
lbOsztaly: TLabel;
Function VoltHelyNev(St: St3): Boolean;
Function HToOszt(H: Word): Word;
Procedure HORKepre;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure sgTFORDblClick(Sender: TObject);
procedure sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
procedure FormCreate(Sender: TObject);
procedure sgTFORClick(Sender: TObject);
procedure edHelyKeyPress(Sender: TObject; var Key: Char);
procedure btToEndClick(Sender: TObject);
procedure btUpClick(Sender: TObject);
procedure btDownClick(Sender: TObject);
procedure sgHianyDblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmHOR: TfmHOR;
HUtkz: Array[0..HOSz+1,0..HMax+1] Of Word;
implementation
{$R *.dfm}
procedure TfmHOR.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmHOR.btKilepesClick(Sender: TObject);
begin
Close;
end;
Function TfmHOR.VoltHelyNev(St: St3): Boolean;
Var H: Word;
Begin
VoltHelyNev:= False; If (St='-') Or (St='') Then Exit;
With sgTFOR Do For H:= 1 To RowCount-2 Do If St=Cells[0,H] Then
Begin VoltHelyNev:= True; Break End;
End;
Function TfmHOR.HToOszt(H: Word): Word;
Var O: Word;
Begin
HToOszt:= 0; If H=0 Then Exit; With ATFOR Do
For O:= 1 To OMax Do If OHel[O]=H Then Begin HToOszt:= O; Break End;
End;
procedure TfmHOR.sgTFORDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
begin
With sgTFOR.Canvas.Brush Do
Begin
If (gdFixed In State) And ((Col=Acol) Or (Row=ARow)) Then
Color:= clYellow Else Color:= clBtnFace;
If gdSelected In State Then Color:= clLime;
If Not((gdSelected In State) Or (gdFixed In State)) Then With ATFOR Do
Begin
If HLeh[Col,Row]=1 Then Color:= RGB(232,232,232) Else Color:= clWindow;
If HUtkz[Col,Row]=1 Then Color:= clFuchsia;
End;
End;
sgTFOR.Canvas.TextRect(Rect,Rect.Left+1,Rect.Top,sgTFOR.Cells[Col,Row]);
If gdFocused In State Then sgTFOR.Canvas.DrawFocusRect(Rect);
end;
procedure TfmHOR.FormCreate(Sender: TObject);
Var I: Word;
begin
ACol:= 1; ARow:= 1;
With sgTFOR Do With ATFOR Do
Begin
ColWidths[0]:= 25; ColWidths[ColCount-1]:= 24;
Cells[ColCount-1,0]:= 'Sum'; Cells[0,RowCount-1]:= 'Sum';
For I:= 1 To HOSz Do Cells[I,0]:= INev[I];
End;
With sgHiany Do
Begin
Cells[0,0]:= 'Idő';
Cells[1,0]:= 'Ped';
Cells[2,0]:= 'Tan';
Cells[3,0]:= 'Osz';
End;
HORKepre; sgTFORClick(Sender);
end;
Procedure TfmHOR.HORKepre;
Var I, P, H, S: Word;
Begin
With sgTFOR Do With ATFOR Do
Begin
For I:= 1 To HOSz Do For H:= 1 To HMax Do Cells[I,H]:= '';
For I:= 0 To HOSz+1 Do For H:= 0 To HMax+1 Do HUtkz[I,H]:= 0;
For H:= 1 To HMax Do Cells[0,H]:= HNev[H];
For P:= 1 To PMax Do For I:= 1 To HOSz Do
If POra[I,P,1] In [1..TMax] Then
Begin
If Cells[I,POra[I,P,3]]='' Then Cells[I,POra[I,P,3]]:= PRov[P] Else
HUtkz[I,POra[I,P,3]]:= 1;
End;
For I:= 1 To HOSz Do
Begin
S:= 0; For H:= 1 To HMax Do If Cells[I,H]<>'' Then Inc(S);
Cells[I,RowCount-1]:= IntToStr(S);
End;
For H:= 1 To HMax Do
Begin
S:= 0; For I:= 1 To HOSz Do If Cells[I,H]<>'' Then Inc(S);
Cells[ColCount-1,H]:= IntToStr(S);
End;
S:= 0; For I:= 1 To HOSz Do Inc(S,StrToInt(Cells[I,RowCount-1]));
Cells[ColCount-1,RowCount-1]:= IntToStr(S);
End;
With sgHiany Do
For I:= 0 To ColCount-1 Do For S:= 1 To RowCount-1 Do Cells[I,S]:= '';
S:= 0;
With sgHiany Do With ATFOR Do
For I:= 1 To HOSz Do For P:= 1 To PMax Do
If (POra[I,P,1] In [1..TMax]) And (POra[I,P,3]=0) Then
Begin
Inc(S);
Cells[0,S]:= INev[I];
Cells[1,S]:= PRov[P];
Cells[2,S]:= TNev[POra[I,P,1]];
Cells[3,S]:= ONev[POra[I,P,2]];
End;
End;
procedure TfmHOR.sgTFORClick(Sender: TObject);
Var P: Word;
begin
With sgTFOR Do With ATFOR Do
Begin
If Col=ColCount-1 Then Col:= ColCount-2;
If Row=RowCount-1 Then Row:= RowCount-2;
edHely.Text:= Cells[0,Row]; ACol:= Col; ARow:= Row; RePaint;
APeda:= PRovToInd(Cells[Col,Row]); AIdop:= Col;
lbTant.Caption:= TNev[POra[AIdop,APeda,1]];
LbOsztaly.Caption:= ONev[HToOszt(Row)];
If POra[AIdop,APeda,2]<>0 Then
lbOszt.Caption:= ONev[POra[AIdop,APeda,2]] Else lbOszt.Caption:= '-';
lbPeda.Caption:= PRov[APeda];
lbMPeda.Caption:= '-';
If HUtkz[Col,Row]=1 Then
For P:= 1 To PMax Do If P<>APeda Then If POra[Col,P,3]=Row Then
Begin lbMPeda.Caption:= PRov[P]; Break End;
End;
end;
procedure TfmHOR.edHelyKeyPress(Sender: TObject; var Key: Char);
begin
If Key=#13 Then
With sgTFOR Do With edHely Do If Not VoltHelyNev(Text) Then
Begin
If Text='' Then Text:= '-'; Cells[0,Row]:= Text; ATFOR.HNev[Row]:= Text;
If Row<RowCount-2 Then Row:= Row+1;
End;
end;
procedure TfmHOR.sgTFORDblClick(Sender: TObject);
begin
With sgTFOR Do With ATFOR Do
Begin
If Cells[Col,Row]='' Then HLeh[Col,Row]:= 1-HLeh[Col,Row] Else
POra[Col,PRovToInd(Cells[Col,Row]),3]:= 0;
If Col<ColCount-2 Then Col:= Col+1;
End;
HORKepre;
end;
procedure TfmHOR.btToEndClick(Sender: TObject);
Var H: Word;
begin
With sgTFOR Do With ATFOR Do
Begin
If Row=RowCount-2 Then Exit;
For H:= Row+1 To HMax Do HLeh[Col,H]:= HLeh[Col,Row];
RePaint;
End;
end;
procedure TfmHOR.btUpClick(Sender: TObject);
Var S: Word;
begin
With sgTFOR Do With ATFOR Do
Begin
If (Cells[Col,Row]='') Or (Row=1) Then Exit;
APeda:= PRovToInd(Cells[Col,Row]); S:= Row;
If S>1 Then
Begin
While (Cells[Col,S-1]<>'') And (S>1) Do Dec(S); Dec(S);
If (S>0) And (Cells[Col,S]='') Then
Begin POra[Col,APeda,3]:= S; Row:= S End;
End;
End;
HORKepre;
end;
procedure TfmHOR.btDownClick(Sender: TObject);
Var S: Word;
begin
With sgTFOR Do With ATFOR Do
Begin
If (Cells[Col,Row]='') Or (Row=RowCount-2) Then Exit;
APeda:= PRovToInd(Cells[Col,Row]); S:= Row;
If S<RowCount-2 Then
Begin
While (Cells[Col,S+1]<>'') And (S<RowCount-2) Do Inc(S); Inc(S);
If (S<RowCount-1) And (Cells[Col,S]='') Then
Begin POra[Col,APeda,3]:= S; Row:= S End;
End;
End;
HORKepre;
end;
procedure TfmHOR.sgHianyDblClick(Sender: TObject);
begin
With sgHiany Do With ATFOR Do
Begin
If Cells[0,Row]='' Then Exit;
AIdop:= INevToInd(Cells[0,Row]);
If sgTFOR.Cells[AIdop,sgTFOR.Row]<>'' Then Exit;
APeda:= PRovToInd(Cells[1,Col]);
POra[AIdop,APeda,3]:= sgTFOR.Row;
End;
HORKepre;
end;
end.
Kódolás (8)
A gépi órarendkészítés
Az általam ismert gépi algoritmusok közül az ütközésmentesítő algoritmust építettem
be a programba. Azért esett a választás erre az algoritmusra, mert gyors,
könnyen kódolható és a végén esetleg maradó hibák ellenére az elkészített
órarendet gyakorlatilag változtatás nélkül használni lehet, hiszen csak az
fordulhat elő, hogy osztályok szerint nem lesz tömör az órarend, vagyis néhány
óra nincs az engedélyezett időkeretben. Azt, hogy könnyen tömöríthető-e az így
elkészült órarend, mindig a konkrét órarendnél kell megvizsgálni. A próbafuttatások
alatt egyébként legalább 95%-ban a generálást a program teljesen be tudta
fejezni.
A generálás első lépéseként a tantárgyfelosztás és az
előkészített órarend alapján a még be nem írt órákat az UpLoad megnyomására a
program elhelyezi az órarendben. Természetesen az elhelyezéskor figyeli a
csoportbontásokat, olyan helyre teszi a bontott órákat, hol mindkét pedagógus
ráér. Mivel egy tételből csak részórák is elhelyezhetők a kézi betöltés idején,
a gépi betöltő először megállapítja, hogy hány óra nincs még beírva, és csak
annyit helyez el az órarendben, amennyi kézzel még nem volt beírva. Egyébként a
beírási helyeket véletlenszerűen választja, hiszen ekkor nincs semmi
prekoncepció az órák végleges helyét illetően. Mivel a véletlen választásnál
egyáltalán nem figyel egy másik, már beírt tételre, természetes, hogy ütközéses
órarend áll elő ebben a fázisban. Erre a véletlen feltöltésre a csoportbontás
miatt csak akkor van lehetőség, ha az órarendben vannak olyan időpontok is,
amelyekre nem, vagy csak kivételes esetekben kerül véglegesen tanóra (ilyenek a
0. és a 7.-9. órák).
Az ütközések büntetőpontjait a program a
következőképpen számolja: minden pedagógusnak, minden órájára összeszámolja,
hogy hány osztállyal van ütközésben. Ebből származik a büntetőpontok első része.
A második hiba, amivel számol az algoritmus, a nem megengedett helyen lévő óra,
melynek büntetési tétele két pont. A harmadik típusú hiba a kétórás tárgyakra
vonatkozik. Ha egy kétórás tantárgy két órája egymás utáni napon van, akkor azért
is büntetőpont jár. Ezen típusú pontok összege adja egy adott óra hibapontját,
a teljes órarendét pedig az egyes órák hibapontjainak az összege. Mivel az
ütközés kölcsönös, a nem megengedett hely miatt két pont jár, a kétórás
tantárgy rossz elhelyezés esetén szintén két hibapontot kaphat, a teljes
hibapontok száma biztosan páros. A konkrét órarendben így az 1192 darab óra
véletlen elhelyezésekor 2200-2400 hibapont keletkezik. A rendező algoritmusnak
ezt kell a nullára csökkenteni.
Az általam
használt ütközésmentesítő algoritmus a következő lépésekből áll:
1.
megállapítja a teljes órarend hibapontjainak számát,
2.
véletlenül kiválaszt egy hibaponttal rendelkező órát,
3.
véletlenül választ egy másik időpontot a 2. pontban kiválasztott pedagógusnál,
4.
felcseréli a két órát,
5.
újra megállapítja a teljes órarend hibapontjainak számát,
A lépések
részletezése:
6.
Természetes a nulla hibapont csak kívánatos eset. Könnyen meglehet, hogy ennek
elérése csak értelmetlenül hosszú futási idő esetén lehetséges. Ennek a
problémának a kezelésére két megoldás van beépítve az algoritmusba. Az egyik
azt figyeli, hogy hány lépésen keresztül nem változott az órarend összesített
hibapontja. Ha ez az érték több ezerre rúg, akkor véletlen választásokkal
megkeveri az órarendet a program, természetesen ezzel jelentősen megnövelve az
ütközések számát, ugyanakkor egy reménybeli megoldás közelében maradva. Minél
többször kell visszalépnie az algoritmusnak a látszólagos leállás miatt, annál
nagyobb lépésszámban kever. Ha az ilyen visszalépések száma eléri a hatot,
akkor egy teljes feltöltéssel a kezdeti állapotnak megfelelő helyzetből indul
újra a rendezés. A másik korlátot egy maximális lépésszám jelenti, ha ezt eléri
az algoritmus, akkor leáll. Ez alapértelmezésben 200000, mely természetesen az
algoritmus elején megváltoztatható. Nem biztos azonban, hogy ekkor (a maximális
lépésszám elérésekor) a teljes algoritmus során létrejött órarendek közül a
legjobbal dolgozik a program. Ennek a problémának megoldása az, hogy minden
visszalépésnél megnézi a program, nem jobb-e az aktuális órarend az eddig
mentetteknél, mert ha igen, akkor ezt jegyzi meg, és ha a végén nem nulla
hibapont miatt áll le a generálás, akkor ezt adja vissza a megoldásként.
7.
Ebben a lépésben nem követeljük meg, hogy jobb állapot jöjjön létre az
elfogadáshoz. A tapasztalatok azt mutatják, hogy ha ezt tennénk, akkor
15-25%-os hibapontérték környékén az algoritmus leállna, a végcél nem lenne
elérhető.
Hogy értékelni tudjuk az algoritmus hatékonyságát,
összesítsük a beírt órákat és nézzük meg, hány százaléka csoportbontásos, mert
azt hiszem ezek az értékek elég magasak:
Összes óraszám osztályok
szerint: 8*28+8*29+8*30+8*29 = 928 – 100%
Egyedi óraszám osztályok
szerint: 664 – 71,5%.
Csoportbontásos óra osztályok
szerint: 264 – 28,5%.
Összes óraszám pedagógusok
szerint: 1192 – 100%.
Egyedi pedagógus óraszám: 664 – 55,7%.
Csoportbontásos pedagógus
óraszám: 528 –44,3%.
Az ütközésmentesítő algoritmus a leírt
hibapontszámítás mellett, alapból védekezik az ellen, hogy a csoportbontásos
órákat sokat mozgassa. Az algoritmus elején még inkább, de később egyáltalán
nem nyúl hozzájuk. Ha egy csoportbontásos óra a végén kint marad a nem
megengedett időpontokra, akkor az keverés (visszalépés) nélkül már nem szokott
a megengedett időpontokra visszakerülni. Ezért ha nagy gond van a végén, akkor
olyan nagy visszalépésre van szükség, melyben a csoportbontásos órák keverése
is megvalósul.
A másik jellegzetessége az algoritmusnak, hogy a
végére általában olyan hibapontos órák maradnak, melyek a nem megengedett
időpontokból származnak, így az órarend még hibapont esetén is ütközésmentes,
ha tehát mégis megengedünk ilyen időpontokban órákat, akkor azonnal használható
még az ilyen, az algoritmus szerint hibás órarend is.
Kódolás (9)
Az elkészült órarendek használhatóságát nagyban
meghatározza az, hogy a program milyen dokumentumokat tud előállítani, adatait milyen
nyomtatható formába tudja ölteni. A programot kétféle dokumentum előállítására
tesszük alkalmassá. Gondolva az internetre is, minden egyedi órarendet Html
oldalon fogunk megjeleníteni. Az összesített órarendeket célszerű nagyméretű
táblázatokba helyezni, így erre az XLS formátum a kézenfekvő megoldás. A
pedagógusoknak az összesített tantárgyfelosztáshoz szükséges további adatait és
a dokumentumok előállítására alkalmas környezetet egy külön formon, az
fmMentMint nevűn helyeztem el. Ennek futtatási képe:
Az egyedi órarendek nyomtatásakor
Pedagógus esetén az előválasztás a táblázat megfelelő sorának kiválasztásával
történik. Az egyedi osztály- és tanteremórarend esetén a listadobozok
segítségével állíthatjuk be a kívánt elemet. Arra is van lehetőség, hogy az
egyedi órarendek mindegyikét egy menetben a program elkészítse. Ez a funkció a
P-All, T-All, O-All és H-All feliratú nyomógombok segítéségével érhető el. Az
összesített XLS táblázatokban minden kiválasztás szerinti elem szerepel.
A nyomógombok feliratának magyarázata:
-
Peda –> Html: a kiválasztott pedagógus órarendje,
-
P–All: minden pedagógusnak az egyedi órarendje,
-
Tant –> Html: a kiválasztott tantárgy órarendje,
-
T–All: minden tantárgy az egyedi órarendje,
-
Oszt –> Html: a kiválasztott osztály órarendje,
-
O–All: minden osztálynak az egyedi órarendje,
-
Hely –> Html: a kiválasztott tanterem órarendje,
-
H–All: minden tanterem egyedi órarendje,
-
PTF –> XLS: pedagógusok iskolai szintű összesített tantárgyfelosztása,
-
POR –> XLS: pedagógusok órarendje,
-
OOR –> XLS: osztályok órarendje,
-
HOR –> XLS: tantermek órarendje,
-
TOR –> XLS: tantárgyak órarendje.
Az UMentMint listája (még a mentések kidolgozása
nélkül):
unit UMentMint;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, UAdat, UModul,
Dialogs, StdCtrls, Grids;
type
TfmMentMint = class(TForm)
lbMentMint: TLabel;
btKilepes: TButton;
sgPeda: TStringGrid;
lbPeda: TLabel;
lbEgyedi: TLabel;
lbOsszes: TLabel;
ldOszt: TListBox;
ldHely: TListBox;
btPedaHtml: TButton;
btOsztHtml: TButton;
btHelyHtml: TButton;
btPTFXLS: TButton;
btPORXLS: TButton;
btOORXLS: TButton;
btHORXLS: TButton;
btTORXLS: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure sgPedaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmMentMint: TfmMentMint;
implementation
{$R *.dfm}
procedure TfmMentMint.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmMentMint.btKilepesClick(Sender: TObject);
Var I: Word;
Kod: Integer;
begin
With sgPeda Do With ATFOR Do
For I:= 1 To PMax Do
Begin
PNev[I]:= Cells[1,I];
PRov[I]:= Cells[2,I];
PBeo[I]:= Cells[3,I];
Val(Cells[4,I],PKot[I],Kod);
Val(Cells[5,I],PNOT[I],Kod);
End;
Close;
end;
procedure TfmMentMint.FormCreate(Sender: TObject);
Var I: Word;
begin
With sgPeda Do With ATFOR Do
Begin
ColWidths[0]:= 24;
ColWidths[1]:= 160;
RowCount:= PMax+1;
Cells[1,0]:= 'Pedagógus';
Cells[2,0]:= 'NévRöv';
Cells[3,0]:= 'Beosztás';
Cells[4,0]:= 'KötÓra';
Cells[5,0]:= 'NemÓratervi';
For I:= 1 To PMax Do
Begin
Cells[0,I]:= IntToStr(I)+'.';
Cells[1,I]:= PNev[I];
Cells[2,I]:= PRov[I];
Cells[3,I]:= PBeo[I];
Cells[4,I]:= IntToStr(PKot[I]);
Cells[5,I]:= IntToStr(PNOT[I]);
End;
End;
With ldOszt Do With ATFOR Do
Begin
For I:= 0 To OMax Do Items.Add(ONev[I]);
ItemIndex:= 0;
End;
With ldHely Do With ATFOR Do
Begin
For I:= 0 To HMax Do Items.Add(HNev[I]);
ItemIndex:= 0;
End;
end;
procedure TfmMentMint.sgPedaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If Key=13 Then With sgPeda Do If Row<RowCount-1 Then Row:= Row+1;
end;
end.
Kódolás (10)
Elkészültek
az egyedi órarendeket tartalmazó kimenetek. Egy pedagógus órarendje Html
formátumban:
Egy
tantárgy órarendje Html formátumban:
Egy
osztály órarendje Html formátumban:
Egy
terem órarendje Html formátumban:
A
megváltozott UMentMint Unit listája:
unit UMentMint;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms,
UAdat, UModul,
Dialogs, StdCtrls, Grids;
type
TfmMentMint = class(TForm)
lbMentMint: TLabel;
btKilepes: TButton;
sgPeda: TStringGrid;
lbPeda: TLabel;
lbEgyedi: TLabel;
lbOsszes: TLabel;
ldOszt: TListBox;
ldHely: TListBox;
btPedaHtml: TButton;
btOsztHtml: TButton;
btHelyHtml: TButton;
btPTFXLS: TButton;
btPORXLS: TButton;
btOORXLS: TButton;
btHORXLS: TButton;
btTORXLS: TButton;
btPAll: TButton;
btOAll: TButton;
btHAll: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure sgPedaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure btPedaHtmlClick(Sender: TObject);
procedure ldOsztClick(Sender: TObject);
procedure ldHelyClick(Sender: TObject);
procedure btOsztHtmlClick(Sender: TObject);
procedure btHelyHtmlClick(Sender: TObject);
procedure btPAllClick(Sender: TObject);
procedure btOAllClick(Sender: TObject);
procedure btHAllClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmMentMint: TfmMentMint;
O: Array[0..NaSz,0..2*NOSz] Of St12;
implementation
{$R *.dfm}
procedure TfmMentMint.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmMentMint.btKilepesClick(Sender: TObject);
Var I: Word;
Kod: Integer;
begin
With sgPeda Do With ATFOR Do
For I:= 1 To PMax Do
Begin
PNev[I]:= Cells[1,I];
PRov[I]:= Cells[2,I];
PBeo[I]:= Cells[3,I];
Val(Cells[4,I],PKot[I],Kod);
Val(Cells[5,I],PNOT[I],Kod);
End;
Close;
end;
procedure TfmMentMint.FormCreate(Sender: TObject);
Var I: Word;
begin
With sgPeda Do With ATFOR Do
Begin
ColWidths[0]:= 24;
ColWidths[1]:= 160;
RowCount:= PMax+1;
Cells[1,0]:= 'Pedagógus';
Cells[2,0]:= 'NévRöv';
Cells[3,0]:= 'Beosztás';
Cells[4,0]:= 'KötÓra';
Cells[5,0]:= 'NemÓratervi';
For I:= 1 To PMax Do
Begin
Cells[0,I]:= IntToStr(I)+'.';
Cells[1,I]:= PNev[I];
Cells[2,I]:= PRov[I];
Cells[3,I]:= PBeo[I];
Cells[4,I]:= IntToStr(PKot[I]);
Cells[5,I]:= IntToStr(PNOT[I]);
End;
End;
With ldOszt Do With ATFOR Do
Begin
For I:= 0 To OMax Do Items.Add(ONev[I]);
ItemIndex:= 0;
End;
With ldHely Do With ATFOR Do
Begin
For I:= 0 To HMax Do Items.Add(HNev[I]);
ItemIndex:= 0;
End;
btOsztHtml.Enabled:= False; btHelyHtml.Enabled:= False;
end;
procedure TfmMentMint.sgPedaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If Key=13 Then With sgPeda Do If Row<RowCount-1 Then Row:= Row+1;
end;
procedure TfmMentMint.btPedaHtmlClick(Sender: TObject);
Var I, J: Word;
begin
For I:= 0 To NaSz Do For J:= 0 To 2*NOSz Do O[I,J]:= '-'; APeda:= sgPeda.Row;
O[0,0]:= '*'; For I:= 1 To NaSz Do O[I,0]:= NNev[I];
For J:= 0 To NOSz-1 Do O[0,J+1]:= IntToStr(J)+'.';
With ATFOR Do For I:= 1 To HOSz Do
Case POra[I,APeda,1] Of
1..TMax: O[(I-1) Div NOSz+1,(I-1) Mod NOSz+1]:= TNev[POra[I,APeda,1]]+'-'+
ONev[POra[I,APeda,2]]+'-'+
HNev[POra[I,APeda,3]];
Tilt: O[(I-1) Div NOSz+1,(I-1) Mod NOSz+1]:= 'XX';
End;
With ATFOR Do
Begin
DNev:= PRov[APeda]+'.html';
AssignFile(FText,DNev); ReWrite(FText);
WriteLn(FText, '<HTML>','<BODY>');
WriteLn(FText, '<p align=center>',
'<Font size=6>',
'<u>','<b>',PNev[APeda],' (',PRov[APeda],')','</b>','</u>',
'</Font>','</p>');
WriteLn(FText, '<p align=center>',
'<Font face=courier>');
WriteLn(FText, '<TABLE border=1 cellpadding=5 cellspacing=0>');
For J:= 0 To NOSz Do
Begin
WriteLn(FText,'<tr>');
For I:= 0 To NaSz Do
Begin
Case J Of
0: Write(FText, '<th>');
1: If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
2..7: Begin
If I=0 Then Write(FText, '<th') Else Write(FText, '<td');
Write(FText, ' bgcolor=#ddeeff>');
End;
Else
Begin
If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
End;
End;
WriteLn(FText,O[I,J]);
If J=0 Then Write(FText, '</th>') Else Write(FText, '</td>');
End;
WriteLn(FText,'</tr>');
End;
WriteLn(FText,'</table>','</font>','</p>');
WriteLn(FText,'<br>','<br>');
WriteLn(FText,'<font size=1 color=blue>');
WriteLn(FText,'<center>');
WriteLn(FText,'<u>','Created by TFOR System (GM-Soft) ',
DateToStr(Now),'-',TimeToStr(Time),
'</u></center>');
WriteLn(FText,'</Body></HTML>');
CloseFile(Ftext);
End;
end;
procedure TfmMentMint.ldOsztClick(Sender: TObject);
begin
With ldOszt Do btOsztHtml.Enabled:= ItemIndex>0;
end;
procedure TfmMentMint.ldHelyClick(Sender: TObject);
begin
With ldHely Do btHelyHtml.Enabled:= ItemIndex>0;
end;
procedure TfmMentMint.btOsztHtmlClick(Sender: TObject);
Var I, J, P: Word;
begin
For I:= 0 To NaSz Do For J:= 0 To 2*NOSz Do O[I,J]:= '-';
With ldOszt Do AOszt:= ItemIndex;
O[0,0]:= '*'; For I:= 1 To NaSz Do O[I,0]:= NNev[I];
For J:= 0 To NOSz-1 Do O[0,2*J+1]:= IntToStr(J)+'.';
With ATFOR Do For I:= 1 To HOSz Do For P:= 1 To PMax Do
If POra[I,P,2]=AOszt Then
If O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]='-' Then
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]:= TNev[POra[I,P,1]]+'-'+
PRov[P]+'-'+
HNev[POra[I,P,3]] Else
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+2]:= TNev[POra[I,P,1]]+'-'+
PRov[P]+'-'+
HNev[POra[I,P,3]];
With ldOszt Do With ATFOR Do
Begin
DNev:= ONev[AOszt]+'.html';
AssignFile(FText,DNev); ReWrite(FText);
WriteLn(FText, '<HTML>','<BODY>');
WriteLn(FText, '<p align=center>',
'<Font size=6>',
'<u>','<b>',ONev[AOszt],' (Ofő: ',PNev[OOfo[AOSzt]],')',
'</b>','</u>',
'</Font>','</p>');
WriteLn(FText, '<p align=center>',
'<Font face=courier>');
WriteLn(FText, '<TABLE border=1 cellpadding=5 cellspacing=0>');
For J:= 0 To 2*NOSz Do
Begin
WriteLn(FText,'<tr>');
For I:= 0 To NaSz Do
Begin
Case J Of
0: Write(FText, '<th>');
1..2: If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
3..14: Begin
If I=0 Then Write(FText, '<th') Else Write(FText, '<td');
Write(FText, ' bgcolor=#ddeeff>');
End;
Else
Begin
If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
End;
End;
WriteLn(FText,O[I,J]);
If J=0 Then Write(FText, '</th>') Else Write(FText, '</td>');
End;
WriteLn(FText,'</tr>');
End;
WriteLn(FText,'</table>','</font>','</p>');
WriteLn(FText,'<br>','<br>');
WriteLn(FText,'<font size=1 color=blue>');
WriteLn(FText,'<center>');
WriteLn(FText,'<u>','Created by TFOR System (GM-Soft) ',
DateToStr(Now),'-',TimeToStr(Time),
'</u></center>');
WriteLn(FText,'</Body></HTML>');
CloseFile(Ftext);
End;
end;
procedure TfmMentMint.btHelyHtmlClick(Sender: TObject);
Var I, J, P: Word;
begin
For I:= 0 To NaSz Do For J:= 0 To 2*NOSz Do O[I,J]:= '-';
With ldHely Do AHely:= ItemIndex;
O[0,0]:= '*'; For I:= 1 To NaSz Do O[I,0]:= NNev[I];
For J:= 0 To NOSz-1 Do O[0,J+1]:= IntToStr(J)+'.';
With ATFOR Do For I:= 1 To HOSz Do For P:= 1 To PMax Do
If POra[I,P,3]=AHely Then
O[(I-1) Div NOSz+1,(I-1) Mod NOSz+1]:= TNev[POra[I,P,1]]+'-'+
ONev[POra[I,P,2]]+'-'+
PRov[P];
With ATFOR Do
Begin
DNev:= HNev[AHely]+'.html';
AssignFile(FText,DNev); ReWrite(FText);
WriteLn(FText, '<HTML>','<BODY>');
WriteLn(FText, '<p align=center>',
'<Font size=6>',
'<u>','<b>',HNev[AHely],'</b>','</u>',
'</Font>','</p>');
WriteLn(FText, '<p align=center>',
'<Font face=courier>');
WriteLn(FText, '<TABLE border=1 cellpadding=5 cellspacing=0>');
For J:= 0 To NOSz Do
Begin
WriteLn(FText,'<tr>');
For I:= 0 To NaSz Do
Begin
Case J Of
0: Write(FText, '<th>');
1: If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
2..7: Begin
If I=0 Then Write(FText, '<th') Else Write(FText, '<td');
Write(FText, ' bgcolor=#ddeeff>');
End;
Else
Begin
If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
End;
End;
WriteLn(FText,O[I,J]);
If J=0 Then Write(FText, '</th>') Else Write(FText, '</td>');
End;
WriteLn(FText,'</tr>');
End;
WriteLn(FText,'</table>','</font>','</p>');
WriteLn(FText,'<br>','<br>');
WriteLn(FText,'<font size=1 color=blue>');
WriteLn(FText,'<center>');
WriteLn(FText,'<u>','Created by TFOR System (GM-Soft) ',
DateToStr(Now),'-',TimeToStr(Time),
'</u></center>');
WriteLn(FText,'</Body></HTML>');
CloseFile(Ftext);
End;
end;
procedure TfmMentMint.btPAllClick(Sender: TObject);
Var P: Word;
begin
With sgPeda Do For P:= 1 To PMax Do
Begin Row:= P; btPedaHtmlClick(Sender) End;
end;
procedure TfmMentMint.btOAllClick(Sender: TObject);
Var O: Word;
begin
With ldOszt Do For O:= 1 To OMax Do
Begin ItemIndex:= O; btOsztHtmlClick(Sender) End;
end;
procedure TfmMentMint.btHAllClick(Sender: TObject);
Var H: Word;
begin
With ldHely Do For H:= 1 To HMax Do
Begin ItemIndex:= H; btHelyHtmlClick(Sender) End;
end;
end.
Kódolás (11)
Lassan a kódolás végére érünk. Elkészült a pedagógusok
tantárgyfelosztása az intézményi összesítéssel. Mint ahogy azt fentebb leírtam,
egy ekkora táblázat megjelenítésére az Excel a legkézenfekvőbb. A 12 oldalnyi
táblázatnak az első 33 sora:
A 12. oldal, mely a lista
végét tartalmazza, valamint az intézmény szintű összeszést:
Az
egyes pedagógusok tantárgyfelosztásának utolsó sorában (Össz: -al kezdődik) a
következő számértékek találhatók:
- a pedagógus teljes heti
óraszáma (óratervi és nem óratervi órák összege),
- a pedagógus nem óratervi
óráinak száma,
- a pedagógus óratervi (a
TFOR által beírandó) óráinak száma (a felette lévő tanítási tételek óraszámának
összege),
- a pedagógus
kötelező-óráinak száma,
- a pedagógus túlórája.
Az intézményi összesenben ugyanezek az órák vannak
összesítve. A túlóra összesítésében a negatív túlórákat nem összegzi.
Ugyancsak elkészült a pedagógusok összesített
órarendjének Excel táblázatba való mentése. Ez szintén 12 oldal terjedelmű. A
formázásnál a fő óráknak (1.-6.) megfelelő cellák háttérszínét, valamint minden
második pedagógusnak az órarendjét barackszínnel jelöltük a könnyebb
olvashatóság kevéért. Egymás melleti A4-es lapok száma három és a lista olyan
hosszú, hogy négy A4-es lapra fér el (3*4=12 lap). A balfelső sarok így néz ki:
Az
előző terület 70%-os megjelenítésben:
Az
osztályok órarendjének Excel táblázatba való mentése:
Ugyanez 70%-os
megjelenítésben:
Végül a Teremórarend:
Ugyanez 70%-os
megjelenítésben:
Természetesen
az UMentMint listája ismét változott, íme:
unit UMentMint;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
aphics, Controls, Forms, UAdat, UModul,
Dialogs, StdCtrls, Grids, OleServer, Excel97, ActiveX, ExcelXP;
type
TfmMentMint = class(TForm)
lbMentMint: TLabel;
btKilepes: TButton;
sgPeda: TStringGrid;
lbPeda: TLabel;
lbEgyedi: TLabel;
lbOsszes: TLabel;
ldOszt: TListBox;
ldHely: TListBox;
btPedaHtml: TButton;
btOsztHtml: TButton;
btHelyHtml: TButton;
btPTFXLS: TButton;
btPORXLS: TButton;
btOORXLS: TButton;
btHORXLS: TButton;
btPAll: TButton;
btOAll: TButton;
btHAll: TButton;
svExAlk: TExcelApplication;
svExMFuzet: TExcelWorkbook;
svExMLap: TExcelWorksheet;
btMentes: TButton;
btTantHtml: TButton;
btTAll: TButton;
ldTant: TListBox;
Procedure Mentes;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btKilepesClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure sgPedaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure btPedaHtmlClick(Sender: TObject);
procedure ldOsztClick(Sender: TObject);
procedure ldHelyClick(Sender: TObject);
procedure btOsztHtmlClick(Sender: TObject);
procedure btHelyHtmlClick(Sender: TObject);
procedure btPAllClick(Sender: TObject);
procedure btOAllClick(Sender: TObject);
procedure btHAllClick(Sender: TObject);
procedure btPTFXLSClick(Sender: TObject);
procedure btPORXLSClick(Sender: TObject);
procedure btOORXLSClick(Sender: TObject);
procedure btHORXLSClick(Sender: TObject);
procedure btMentesClick(Sender: TObject);
procedure ldTantClick(Sender: TObject);
procedure btTantHtmlClick(Sender: TObject);
procedure btTAllClick(Sender: TObject);
procedure sgPedaClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmMentMint: TfmMentMint;
O: Array[0..NaSz,0..2*NOSz] Of St36;
implementation
{$R *.dfm}
Procedure TfmMentMint.Mentes;
Var I: Word;
Kod: Integer;
Begin
With sgPeda Do With ATFOR Do
For I:= 1 To PMax Do
Begin
PNev[I]:= Cells[1,I];
PRov[I]:= Cells[2,I];
PBeo[I]:= Cells[3,I];
Val(Cells[4,I],PKot[I],Kod);
Val(Cells[5,I],PNOT[I],Kod);
End;
End;
procedure TfmMentMint.btMentesClick(Sender: TObject);
begin
Mentes;
end;
procedure TfmMentMint.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfmMentMint.btKilepesClick(Sender: TObject);
begin
Mentes;
Close;
end;
procedure TfmMentMint.FormCreate(Sender: TObject);
Var I, O, P, T, H, S: Word;
begin
With sgPeda Do With ATFOR Do
Begin
ColWidths[0]:= 24;
ColWidths[1]:= 150;
RowCount:= PMax+1;
Cells[1,0]:= 'Pedagógus';
Cells[2,0]:= 'NévRöv';
Cells[3,0]:= 'Beosztás';
Cells[4,0]:= 'KötÓra';
Cells[5,0]:= 'NemÓrat';
Cells[6,0]:= 'Óratervi';
For P:= 1 To PMax Do
Begin
S:= 0;
Cells[0,P]:= IntToStr(P)+'.';
Cells[1,P]:= PNev[P];
Cells[2,P]:= PRov[P];
Cells[3,P]:= PBeo[P];
Cells[4,P]:= IntToStr(PKot[P]);
Cells[5,P]:= IntToStr(PNOT[P]);
For I:= 1 To HOSz Do If POra[I,P,2]>0 Then Inc(S);
Cells[6,P]:= IntToStr(S);
End;
End;
With ldTant Do With ATFOR Do
Begin
For T:= 0 To TMax Do Items.Add(TNev[T]);
ItemIndex:= 0;
End;
With ldOszt Do With ATFOR Do
Begin
For O:= 0 To OMax Do Items.Add(ONev[O]);
ItemIndex:= 0;
End;
With ldHely Do With ATFOR Do
Begin
For H:= 0 To HMax Do Items.Add(HNev[H]);
ItemIndex:= 0;
End;
btTantHtml.Enabled:= False;
btOsztHtml.Enabled:= False;
btHelyHtml.Enabled:= False;
end;
procedure TfmMentMint.sgPedaClick(Sender: TObject);
begin
With sgPeda Do If Col=6 Then Col:= 5;
end;
procedure TfmMentMint.sgPedaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If Key=13 Then With sgPeda Do If Row<RowCount-1 Then Row:= Row+1;
end;
procedure TfmMentMint.btPedaHtmlClick(Sender: TObject);
Var I, J: Word;
begin
For I:= 0 To NaSz Do For J:= 0 To 2*NOSz Do O[I,J]:= '-'; APeda:= sgPeda.Row;
O[0,0]:= '*'; For I:= 1 To NaSz Do O[I,0]:= NNev[I];
For J:= 0 To NOSz-1 Do O[0,J+1]:= IntToStr(J)+'.';
With ATFOR Do For I:= 1 To HOSz Do
Case POra[I,APeda,1] Of
1..TMax: O[(I-1) Div NOSz+1,(I-1) Mod NOSz+1]:= TNev[POra[I,APeda,1]]+'-'+
ONev[POra[I,APeda,2]]+'-'+
HNev[POra[I,APeda,3]];
Tilt: O[(I-1) Div NOSz+1,(I-1) Mod NOSz+1]:= 'XX';
End;
With ATFOR Do
Begin
DNev:= PRov[APeda]+'.html';
AssignFile(FText,DNev); ReWrite(FText);
WriteLn(FText, '<HTML>','<BODY>');
WriteLn(FText, '<p align=center>',
'<Font size=6>',
'<u>','<b>',PNev[APeda],' (',PRov[APeda],')','</b>','</u>',
'</Font>','</p>');
WriteLn(FText, '<p align=center>',
'<Font face=courier>');
WriteLn(FText, '<TABLE border=1 cellpadding=5 cellspacing=0>');
For J:= 0 To NOSz Do
Begin
WriteLn(FText,'<tr>');
For I:= 0 To NaSz Do
Begin
Case J Of
0: Write(FText, '<th>');
1: If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
2..7: Begin
If I=0 Then Write(FText, '<th') Else Write(FText, '<td');
Write(FText, ' bgcolor=#ddeeff>');
End;
Else
Begin
If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
End;
End;
WriteLn(FText,O[I,J]);
If J=0 Then Write(FText, '</th>') Else Write(FText, '</td>');
End;
WriteLn(FText,'</tr>');
End;
WriteLn(FText,'</table>','</font>','</p>');
WriteLn(FText,'<br>','<br>');
WriteLn(FText,'<font size=1 color=blue>');
WriteLn(FText,'<center>');
WriteLn(FText,'<u>','Created by TFOR System (GM-Soft) ',
DateToStr(Now),'-',TimeToStr(Time),
'</u></center>');
WriteLn(FText,'</Body></HTML>');
CloseFile(Ftext);
End;
end;
procedure TfmMentMint.ldTantClick(Sender: TObject);
begin
With ldTant Do btTantHtml.Enabled:= ItemIndex>0;
end;
procedure TfmMentMint.ldOsztClick(Sender: TObject);
begin
With ldOszt Do btOsztHtml.Enabled:= ItemIndex>0;
end;
procedure TfmMentMint.ldHelyClick(Sender: TObject);
begin
With ldHely Do btHelyHtml.Enabled:= ItemIndex>0;
end;
procedure TfmMentMint.btTantHtmlClick(Sender: TObject);
Var I, J, P: Word;
begin
For I:= 0 To NaSz Do For J:= 0 To 2*NOSz Do O[I,J]:= '-';
With ldTant Do ATant:= ItemIndex;
O[0,0]:= '*'; For I:= 1 To NaSz Do O[I,0]:= NNev[I];
For J:= 0 To NOSz-1 Do O[0,2*J+1]:= IntToStr(J)+'.';
With ATFOR Do For I:= 1 To HOSz Do For P:= 1 To PMax Do
If POra[I,P,1]=ATant Then
If O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]='-' Then
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]:= ONev[POra[I,P,2]]+',' Else
Begin
If Length(O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1])<20 Then
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]:=
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]+ONev[POra[I,P,2]]+',' Else
If O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+2]='-' Then
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+2]:= ONev[POra[I,P,2]]+',' Else
If Length(O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+2])<20 Then
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+2]:=
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+2]+ONev[POra[I,P,2]]+',';
End;
With ATFOR Do
Begin
DNev:= TNev[ATant]+'.html';
AssignFile(FText,DNev); ReWrite(FText);
WriteLn(FText, '<HTML>','<BODY>');
WriteLn(FText, '<p align=center>',
'<Font size=6>',
'<u>','<b>',TNev[ATant],
'</b>','</u>',
'</Font>','</p>');
WriteLn(FText, '<p align=center>',
'<Font face=courier>');
WriteLn(FText, '<TABLE border=1 cellpadding=5 cellspacing=0>');
For J:= 0 To 2*NOSz Do
Begin
WriteLn(FText,'<tr>');
For I:= 0 To NaSz Do
Begin
Case J Of
0: Write(FText, '<th>');
1..2: If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
3..14: Begin
If I=0 Then Write(FText, '<th') Else Write(FText, '<td');
Write(FText, ' bgcolor=#ddeeff>');
End;
Else
Begin
If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
End;
End;
WriteLn(FText,O[I,J]);
If J=0 Then Write(FText, '</th>') Else Write(FText, '</td>');
End;
WriteLn(FText,'</tr>');
End;
WriteLn(FText,'</table>','</font>','</p>');
WriteLn(FText,'<br>','<br>');
WriteLn(FText,'<font size=1 color=blue>');
WriteLn(FText,'<center>');
WriteLn(FText,'<u>','Created by TFOR System (GM-Soft) ',
DateToStr(Now),'-',TimeToStr(Time),
'</u></center>');
WriteLn(FText,'</Body></HTML>');
CloseFile(Ftext);
End;
end;
procedure TfmMentMint.btOsztHtmlClick(Sender: TObject);
Var I, J, P: Word;
begin
For I:= 0 To NaSz Do For J:= 0 To 2*NOSz Do O[I,J]:= '-';
With ldOszt Do AOszt:= ItemIndex;
O[0,0]:= '*'; For I:= 1 To NaSz Do O[I,0]:= NNev[I];
For J:= 0 To NOSz-1 Do O[0,2*J+1]:= IntToStr(J)+'.';
With ATFOR Do For I:= 1 To HOSz Do For P:= 1 To PMax Do
If POra[I,P,2]=AOszt Then
If O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]='-' Then
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+1]:= TNev[POra[I,P,1]]+'-'+
PRov[P]+'-'+
HNev[POra[I,P,3]] Else
O[(I-1) Div NOSz+1,2*((I-1) Mod NOSz)+2]:= TNev[POra[I,P,1]]+'-'+
PRov[P]+'-'+
HNev[POra[I,P,3]];
With ATFOR Do
Begin
DNev:= ONev[AOszt]+'.html';
AssignFile(FText,DNev); ReWrite(FText);
WriteLn(FText, '<HTML>','<BODY>');
WriteLn(FText, '<p align=center>',
'<Font size=6>',
'<u>','<b>',ONev[AOszt],' (Ofő: ',PNev[OOfo[AOSzt]],')',
'</b>','</u>',
'</Font>','</p>');
WriteLn(FText, '<p align=center>',
'<Font face=courier>');
WriteLn(FText, '<TABLE border=1 cellpadding=5 cellspacing=0>');
For J:= 0 To 2*NOSz Do
Begin
WriteLn(FText,'<tr>');
For I:= 0 To NaSz Do
Begin
Case J Of
0: Write(FText, '<th>');
1..2: If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
3..14: Begin
If I=0 Then Write(FText, '<th') Else Write(FText, '<td');
Write(FText, ' bgcolor=#ddeeff>');
End;
Else
Begin
If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
End;
End;
WriteLn(FText,O[I,J]);
If J=0 Then Write(FText, '</th>') Else Write(FText, '</td>');
End;
WriteLn(FText,'</tr>');
End;
WriteLn(FText,'</table>','</font>','</p>');
WriteLn(FText,'<br>','<br>');
WriteLn(FText,'<font size=1 color=blue>');
WriteLn(FText,'<center>');
WriteLn(FText,'<u>','Created by TFOR System (GM-Soft) ',
DateToStr(Now),'-',TimeToStr(Time),
'</u></center>');
WriteLn(FText,'</Body></HTML>');
CloseFile(Ftext);
End;
end;
procedure TfmMentMint.btHelyHtmlClick(Sender: TObject);
Var I, J, P: Word;
begin
For I:= 0 To NaSz Do For J:= 0 To 2*NOSz Do O[I,J]:= '-';
With ldHely Do AHely:= ItemIndex;
O[0,0]:= '*'; For I:= 1 To NaSz Do O[I,0]:= NNev[I];
For J:= 0 To NOSz-1 Do O[0,J+1]:= IntToStr(J)+'.';
With ATFOR Do For I:= 1 To HOSz Do For P:= 1 To PMax Do
If POra[I,P,3]=AHely Then
O[(I-1) Div NOSz+1,(I-1) Mod NOSz+1]:= TNev[POra[I,P,1]]+'-'+
ONev[POra[I,P,2]]+'-'+
PRov[P];
With ATFOR Do
Begin
DNev:= HNev[AHely]+'.html';
AssignFile(FText,DNev); ReWrite(FText);
WriteLn(FText, '<HTML>','<BODY>');
WriteLn(FText, '<p align=center>',
'<Font size=6>',
'<u>','<b>',HNev[AHely],'</b>','</u>',
'</Font>','</p>');
WriteLn(FText, '<p align=center>',
'<Font face=courier>');
WriteLn(FText, '<TABLE border=1 cellpadding=5 cellspacing=0>');
For J:= 0 To NOSz Do
Begin
WriteLn(FText,'<tr>');
For I:= 0 To NaSz Do
Begin
Case J Of
0: Write(FText, '<th>');
1: If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
2..7: Begin
If I=0 Then Write(FText, '<th') Else Write(FText, '<td');
Write(FText, ' bgcolor=#ddeeff>');
End;
Else
Begin
If I=0 Then Write(FText, '<th>') Else Write(FText, '<td>');
End;
End;
WriteLn(FText,O[I,J]);
If J=0 Then Write(FText, '</th>') Else Write(FText, '</td>');
End;
WriteLn(FText,'</tr>');
End;
WriteLn(FText,'</table>','</font>','</p>');
WriteLn(FText,'<br>','<br>');
WriteLn(FText,'<font size=1 color=blue>');
WriteLn(FText,'<center>');
WriteLn(FText,'<u>','Created by TFOR System (GM-Soft) ',
DateToStr(Now),'-',TimeToStr(Time),
'</u></center>');
WriteLn(FText,'</Body></HTML>');
CloseFile(Ftext);
End;
end;
procedure TfmMentMint.btPAllClick(Sender: TObject);
Var P: Word;
begin
With sgPeda Do For P:= 1 To PMax Do
Begin Row:= P; btPedaHtmlClick(Sender) End;
end;
procedure TfmMentMint.btTAllClick(Sender: TObject);
Var T: Word;
begin
With ldTant Do For T:= 1 To TMax Do
Begin ItemIndex:= T; btTantHtmlClick(Sender) End;
end;
procedure TfmMentMint.btOAllClick(Sender: TObject);
Var O: Word;
begin
With ldOszt Do For O:= 1 To OMax Do
Begin ItemIndex:= O; btOsztHtmlClick(Sender) End;
end;
procedure TfmMentMint.btHAllClick(Sender: TObject);
Var H: Word;
begin
With ldHely Do For H:= 1 To HMax Do
Begin ItemIndex:= H; btHelyHtmlClick(Sender) End;
end;
procedure TfmMentMint.btPTFXLSClick(Sender: TObject);
Var O, P, T, S, OTSz, TOTSz, TNOT, TOSz, TKot, TTul: Word;
LCID: Integer;
Ws: String;
begin
GetDir(0,Ws);
LCID:= GetUserDefaultLCID;
With svExAlk Do
Begin
Connect; Visible[LCID]:= True; DisplayAlerts[LCID]:= False;
svExMFuzet.ConnectTo(WorkBooks.Add(TOleEnum(xlWBATWorkSheet),LCID));
End;
With svExMLap Do With ATFOR Do
Begin
ConnectTo(svExMFuzet.Worksheets[1] As _WorkSheet);
PageSetup.Orientation:= 1;
Range['A1','A1'].Select;
With Cells Do
Begin
Item[1,2].Value:= 'Pedagógus:';
With Range['B1','B1'] Do Begin Select; Font.Bold:= True End;
TOTSz:= 0; TNOT:= 0; TOSz:= 0; TKot:= 0; TTul:= 0;
S:= 1;
For P:= 1 To PMax Do
Begin
OTSz:= 0;
Inc(S);
With Range['A'+IntToStr(S),'A'+IntToStr(S)] Do
Begin Select; NumberFormat:='@' End;
Item[S,1].Value:= IntToStr(P)+'.';
Item[S,2].Value:= PNev[P];
Item[S,3].Value:= PRov[P];
Item[S,4].Value:= PBeo[P];
Item[S,5].Value:= 'Össz';
Item[S,6].Value:= 'Köt';
Item[S,7].Value:= 'Túl';
With Range['A'+IntToStr(S),'G'+IntToStr(S)] Do
Begin Select; Font.Bold:= True End;
For O:= 1 To OMax Do For T:= 1 To TMax Do
Begin
If OTer[O,T,3]=P Then
Begin
Inc(S);
Item[S,3]:= TNev[T]; Item[S,4]:= ONev[O]; Item[S,5]:= OTer[O,T,1];
Inc(OTSz,OTer[O,T,1]);
End;
If OTer[O,T,4]=P Then
Begin
Inc(S);
Item[S,3]:= TNev[T]; Item[S,4]:= ONev[O]; Item[S,5]:= OTer[O,T,2];
Inc(OTSz,OTer[O,T,2]);
End;
End;
Inc(S);
With Range['A'+IntToStr(S),'G'+IntToStr(S)] Do
Begin Select; Font.Bold:= True End;
Item[S,2]:= 'Össz:';
With Range['B'+IntToStr(S),'B'+IntToStr(S)] Do
Begin Select; HorizontalAlignment:= xlHAlignRight End;
Item[S,3]:= PNOT[P]+OTSz; Inc(TOSz,PNOT[P]+OTSz);
Item[S,4]:= PNOT[P]; Inc(TNOT,PNOT[P]);
Item[S,5]:= OTSz; Inc(TOTSz,OTSz);
Item[S,6]:= PKot[P]; Inc(TKot,PKot[P]);
Item[S,7]:= PNOT[P]+OTSz-PKot[P];
If PNOT[P]+OTSz-PKot[P]>0 Then Inc(TTul,PNOT[P]+OTSz-PKot[P]);
End;
With Range['A1','G'+IntToStr(S)] Do
Begin Select; Borders.LineStyle:= xlContinuous End;
Inc(S,2);
With Range['A'+IntToStr(S),'G'+IntToStr(S+8)] Do
Begin Select; Font.Bold:= True End;
Item[S,2]:= 'Intézményi összesen:';
Inc(S); Item[S,2]:= 'Teljes óraszám:'; Item[S,3]:= TOSz;
Inc(S); Item[S,2]:= 'Nem óratervi órák:'; Item[S,3]:= TNOT;
Inc(S); Item[S,2]:= 'Óratervi órák:'; Item[S,3]:= TOTSz;
Inc(S); Item[S,2]:= 'Kötelező órák száma:'; Item[S,3]:= TKot;
Inc(S); Item[S,2]:= 'Túlórák száma:'; Item[S,3]:= TTul;
Inc(S,2); Item[S,2]:= DateToStr(Now);
End;
svExMLap.Cells.EntireColumn.AutoFit;
Range['A1','A1'].Select;
SaveAs(Ws+'\PTF-'+MaRovid);
End;
svExMLap.Disconnect;
svExMFuzet.Disconnect;
svExAlk.Quit;
svExAlk.Disconnect;
end;
procedure TfmMentMint.btPORXLSClick(Sender: TObject);
Var I, P, J, S: Word;
LCID: Integer;
Ws: String;
begin
GetDir(0,Ws);
LCID:= GetUserDefaultLCID;
With svExAlk Do
Begin
Connect; Visible[LCID]:= True; DisplayAlerts[LCID]:= False;
svExMFuzet.ConnectTo(WorkBooks.Add(TOleEnum(xlWBATWorkSheet),LCID));
End;
With svExMLap Do With ATFOR Do
Begin
ConnectTo(svExMFuzet.Worksheets[1] As _WorkSheet);
PageSetup.Orientation:= 1;
With Range['B2','AY2'] Do Begin Select; NumberFormat:='@' End;
Range['A1','A1'].Select;
With Cells Do
Begin
Item[2,1].Value:= 'Ped:';
For I:= 1 To NaSz Do
Begin
Item[1,(I-1)*NOSz+2].Value:= NNev[I];
For J:= 0 To NOSz-1 Do Item[2,(I-1)*NOSz+2+J].Value:= IntToStr(J)+'.';
End;
S:= 2;
For P:= 1 To PMax Do
Begin
Inc(S); Item[S,1].Value:= PNev[P];
For I:= 1 To HOSz Do If POra[I,P,1] In [1..TMax] Then
Item[S,I+1].Value:= TNev[POra[I,P,1]] Else Item[S,I+1]:= '-';
Inc(S); Item[S,1].Value:= PRov[P];
For I:= 1 To HOSz Do If POra[I,P,2] In [1..OMax] Then
Item[S,I+1].Value:= ONev[POra[I,P,2]] Else Item[S,I+1]:= '-';
Inc(S); Item[S,1].Value:= PBeo[P];
For I:= 1 To HOSz Do If POra[I,P,3] In [1..HMax] Then
Item[S,I+1].Value:= HNev[POra[I,P,3]] Else Item[S,I+1]:= '-';
End;
End;
With Range['A1','AY2'] Do
Begin
Select;
Font.Bold:= True;
HorizontalAlignment:= xlHAlignCenter;
End;
With Range['A1','A'+IntToStr(3*PMax+2)] Do
Begin
Select;
Font.Bold:= True;
End;
With Range['A3','AY'+IntToStr(3*PMax+2)] Do
Begin
Select;
Borders.LineStyle:= xlContinuous;
End;
With svExMLap.Application Do
Begin
Range['B1','K1'].MergeCells:= True;
Range['L1','U1'].MergeCells:= True;
Range['V1','AE1'].MergeCells:= True;
Range['AF1','AO1'].MergeCells:= True;
Range['AP1','AY1'].MergeCells:= True;
Cells.EntireColumn.AutoFit;
For P:= 1 To PMax Do If (P Mod 2)=1 Then
Range['A'+IntToStr(3*P),
'AY'+IntToStr(3*P+2)].Interior.ColorIndex:= 40;
Range['C3','H'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['M3','R'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['W3','AB'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['AG3','AL'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['AQ3','AV'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
End;
Range['A1','A1'].Select;
SaveAs(Ws+'\POR-'+MaRovid);
End;
svExMLap.Disconnect;
svExMFuzet.Disconnect;
svExAlk.Quit;
svExAlk.Disconnect;
end;
procedure TfmMentMint.btOORXLSClick(Sender: TObject);
Var I, O, P, J, S: Word;
LCID: Integer;
Ws: String;
begin
GetDir(0,Ws);
LCID:= GetUserDefaultLCID;
With svExAlk Do
Begin
Connect; Visible[LCID]:= True; DisplayAlerts[LCID]:= False;
svExMFuzet.ConnectTo(WorkBooks.Add(TOleEnum(xlWBATWorkSheet),LCID));
End;
With svExMLap Do With ATFOR Do
Begin
ConnectTo(svExMFuzet.Worksheets[1] As _WorkSheet);
PageSetup.Orientation:= 1;
With Range['B2','AY2'] Do Begin Select; NumberFormat:='@' End;
Range['A1','A1'].Select;
With Cells Do
Begin
Item[2,1].Value:= 'Oszt:';
For I:= 1 To NaSz Do
Begin
Item[1,(I-1)*NOSz+2].Value:= NNev[I];
For J:= 0 To NOSz-1 Do Item[2,(I-1)*NOSz+2+J].Value:= IntToStr(J)+'.';
End;
S:= 2;
For O:= 1 To OMax Do
Begin
Inc(S); Item[S,1].Value:= ONev[O];
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,2]=O Then
If Item[S,I+1].Value='' Then
Begin
Item[S, I+1].Value:= TNev[POra[I,P,1]];
Item[S+1,I+1].Value:= PRov[P];
Item[S+2,I+1].Value:= HNev[POra[I,P,3]];
End Else
Begin
Item[S+3,I+1].Value:= TNev[POra[I,P,1]];
Item[S+4,I+1].Value:= PRov[P];
Item[S+5,I+1].Value:= HNev[POra[I,P,3]];
End;
Inc(S,5);
End;
End;
With Range['A1','AY2'] Do
Begin
Select;
Font.Bold:= True;
HorizontalAlignment:= xlHAlignCenter;
End;
With Range['A1','A'+IntToStr(6*OMax+2)] Do
Begin
Select;
Font.Bold:= True;
End;
With Range['A3','AY'+IntToStr(6*OMax+2)] Do
Begin
Select;
Borders.LineStyle:= xlContinuous;
End;
With svExMLap.Application Do
Begin
Range['B1','K1'].MergeCells:= True;
Range['L1','U1'].MergeCells:= True;
Range['V1','AE1'].MergeCells:= True;
Range['AF1','AO1'].MergeCells:= True;
Range['AP1','AY1'].MergeCells:= True;
Cells.EntireColumn.AutoFit;
For O:= 1 To OMax Do If (O Mod 2)=1 Then
Range['A'+IntToStr(6*O-3),
'AY'+IntToStr(6*O+2)].Interior.ColorIndex:= 40;
Range['C3','H'+IntToStr(6*OMax+2)].Interior.ColorIndex:= 40;
Range['M3','R'+IntToStr(6*OMax+2)].Interior.ColorIndex:= 40;
Range['W3','AB'+IntToStr(6*OMax+2)].Interior.ColorIndex:= 40;
Range['AG3','AL'+IntToStr(6*OMax+2)].Interior.ColorIndex:= 40;
Range['AQ3','AV'+IntToStr(6*OMax+2)].Interior.ColorIndex:= 40;
End;
Range['A1','A1'].Select;
SaveAs(Ws+'\OOR-'+MaRovid);
End;
svExMLap.Disconnect;
svExMFuzet.Disconnect;
svExAlk.Quit;
svExAlk.Disconnect;
end;
procedure TfmMentMint.btHORXLSClick(Sender: TObject);
Var I, H, P, J, S: Word;
LCID: Integer;
Ws: String;
begin
GetDir(0,Ws);
LCID:= GetUserDefaultLCID;
With svExAlk Do
Begin
Connect; Visible[LCID]:= True; DisplayAlerts[LCID]:= False;
svExMFuzet.ConnectTo(WorkBooks.Add(TOleEnum(xlWBATWorkSheet),LCID));
End;
With svExMLap Do With ATFOR Do
Begin
ConnectTo(svExMFuzet.Worksheets[1] As _WorkSheet);
PageSetup.Orientation:= 1;
With Range['B2','AY2'] Do Begin Select; NumberFormat:='@' End;
Range['A1','A1'].Select;
With Cells Do
Begin
Item[2,1].Value:= 'Hely:';
For I:= 1 To NaSz Do
Begin
Item[1,(I-1)*NOSz+2].Value:= NNev[I];
For J:= 0 To NOSz-1 Do Item[2,(I-1)*NOSz+2+J].Value:= IntToStr(J)+'.';
End;
S:= 2;
For H:= 1 To HMax Do
Begin
Inc(S); Item[S,1].Value:= HNev[H];
For I:= 1 To HOSz Do For P:= 1 To PMax Do If POra[I,P,3]=H Then
Begin
Item[S, I+1].Value:= TNev[POra[I,P,1]];
Item[S+1,I+1].Value:= ONev[POra[I,P,2]];
Item[S+2,I+1].Value:= PRov[P];
End;
Inc(S,2);
End;
End;
With Range['A1','AY2'] Do
Begin
Select;
Font.Bold:= True;
HorizontalAlignment:= xlHAlignCenter;
End;
With Range['A1','A'+IntToStr(3*PMax+2)] Do
Begin
Select;
Font.Bold:= True;
End;
With Range['A3','AY'+IntToStr(3*PMax+2)] Do
Begin
Select;
Borders.LineStyle:= xlContinuous;
End;
With svExMLap.Application Do
Begin
Range['B1','K1'].MergeCells:= True;
Range['L1','U1'].MergeCells:= True;
Range['V1','AE1'].MergeCells:= True;
Range['AF1','AO1'].MergeCells:= True;
Range['AP1','AY1'].MergeCells:= True;
Cells.EntireColumn.AutoFit;
For P:= 1 To PMax Do If (P Mod 2)=1 Then
Range['A'+IntToStr(3*P),
'AY'+IntToStr(3*P+2)].Interior.ColorIndex:= 40;
Range['C3','H'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['M3','R'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['W3','AB'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['AG3','AL'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
Range['AQ3','AV'+IntToStr(3*PMax+2)].Interior.ColorIndex:= 40;
End;
Range['A1','A1'].Select;
SaveAs(Ws+'\HOR-'+MaRovid);
End;
svExMLap.Disconnect;
svExMFuzet.Disconnect;
svExAlk.Quit;
svExAlk.Disconnect;
end;
end.
2011. november 20. (The end.)