Delphi Gebruikersgroep

 

Home    Up

treeview of tweedimensionaal array van tlist

hier is een uitgebreid vraagje... 

ik ben een staffing programma aan het schrijven voor een callcenter en nu zit ik met het volgende probleem: 

ik heb een aantal agents per team, en die kunnen voorkeuren opgeven. 
dat kunnen ze doen op halve uren nauwkeurig en voor zeven dagen ( de dagen in de week) 
dat levert dus uiteindelijk een hoop voorkeuren op, die je daarna anders moet indelen om ze af te zetten tegen het aantal
agents dat je nodig hebt per half uur. 
om dat te doen wil ik elke agent binnen het benodigde team aflopen en in een grote lijst met alle intervallen in een week
hun agentnummer toevoegen voor elk interval dat ze volgens hun voorkeuren beschikbaar zijn. 

zoals je begrijpt betekenet dat dat de lijst met intervallen al 7*48 is bijna 350 plaatsen bevat, maar daar moeten dus nog
op elke positie een x aantal nummers in kunnen worden geplaatst. 

Ik heb eerst gedacht aan een tweedimensionaal array van tlist's maar dat gaat een hoop geheugen vreten. 
Daarna heb ik het geprobeerd met een treeview met op de eerste laag de dagen van de week en op de tweede laag 48 knopen
voor de 48 intervallen. maar het probleem is dat je de knoppen moet gaan doorlopen tot je de juiste knoop tegenkomt, maar
hoe verder je komt, hoe meer agents je gehad hebt, hoe voller de treeview. het vervelende is dat als je de knopen gaat
doorlopen, alle knopen worden doorlopen, dus ook de knopen die gevuld zijn met agent nummers. ik gebruik nu het volgende
om de juiste knoop te vinden: 


[code] 
function TdmMain.LookupNodeWithDayAndInterval(a: TTreeView;day,interval: integer):TTreeNode; 
var i:Integer; 
AfterDay: boolean; 
begin 
Result:=nil; 
AfterDay:=False; 
for i:=0 to a.items.count-1 do 
begin 
if(a.Items[i].Text=IntToStr(day))and (integer(a.Items[i].data)=-1) then 
AfterDay:=true; 
if(a.Items[i].Text=IntToStr(Interval))and (integer(a.Items[i].data)=-2) and AfterDay then 
begin 
Result:=a.Items[i]; 
Break; 
end; 
end; 
end; 
[/code] 


input zijn de treeview met de knopen voor de dagen en intervallen en het nummer van de dag en het interval. 
ik heb alle knopen op het niveau van de dagen een data gegeven van -1 
en de knopen op het niveau van de intervallen een data gegeven van -2 

de procedure waarvanuit deze wordt aangeroepen is: 


[code]procedure TdmMain.GetAgentsAvailableOnTeam(CurrentQueriedTeam: integer;a: TTreeView); 
var off,nopref: array[1..7] of boolean; 
min,max: array[1..7] of Integer; 
i,day,interval,minval,maxval: integer; 
parentNode: TTreeNode; 
begin 
for i:=1 to 7 do 
begin 
off[i]:=false; 
nopref[i]:=false; 
min[i]:=0; 
max[i]:=0; 
end; 
a.items.BeginUpdate; 
with dsqAgent.DataSet do 
begin 
First; 
while not EOF do 
begin 
if aqAgentAgentTeamID.AsInteger=CurrentQueriedTeam then 
begin 
LoadAgentPrefs(IntToStr(aqAgentAgentID.AsInteger),min,max,off,nopref); 
for day:=1 to 7 do 
if not(off[day-1]) then 
begin 
if nopref[day-1] then 
begin 
minval:=1; 
maxval:=48; 
end 
else 
begin 
minval:=min[day-1]; 
maxval:=max[day-1] 
end; 
for interval:=minval to maxval do 
begin 
parentNode:=LookupNodeWithDayAndInterval(a, day, interval); 
a.Items.AddChild(parentNode,aqAgentAgentID.AsString); 
end; 
end; 
end; 
Next; 
end; 
end; 
a.Items.EndUpdate; 
end; 
[/code] 


de arrays off en nopref worden gebruikt voor de eventuele voorkeuren voor een vrije dag of een dag waarvoor de agent
geen voorkeuren heeft. 

day geeft het nummer van de dag en 
interval geeft het nummer van het interval 

minval en maxval worden gebruikt om voor iedere dag de geprefereerde begin en eindtijd op te slaan. 

loadagentprefs wordt gebruikt om de voorkeuren uit de db te halen, maar alleen als die er zijn, ze worden namelijk pas
opgeslagen als ze worden ingevoerd. 
nadat de prefs zijn geladen wordt voor minval tot maxval het nummer van de huidige agent in de treeview ingevoegd. 
probleem: 
er gaat iets gigantisch mis..... 
de treeview wordt wel gevuld, maar niet correct. 

vraag: 
iemand betere ideeen om dit op te slaan, of een idee wat hier fout gaat? 

alvast bedankt!! 

(al was het alleen al voor de moeite om dit door te spitten ) 

--

hallo benno, kijk [url=http://gathering.tweakers.net/showtopic.php/288672/1]hier[/url] ff voor een discussie over dit
probleem, meedenkers zijn altijd welkom, post maar gewoon hier verder... 

thx 

--

Walter, 

Ik heb je code niet precies bekeken, dus mogelijk schiet ik helemaal mis (werk eigenlijk ook nooit met een treeview
maar goed), maar als ik je goed begrijp wil je een structuur opbouwen per dag in half uur blokken, en dat dan 7 dagen
per week. Per beschikbaar blok kunnen 0 of meer mensen hun voorkeur opgeven. 

Ik weet niet of het voor jou zou werken, maar ik zou als het om het presenteren gaat, de data pas uit de database halen
als ik een bepaalde voorkeur moet laten zien. Bijvoorbeeld op maandag van 12-12.30 dan zou ik de data uit de database
plukken en laten zien op het moment dat je de tree opent voor dat moment. In principe zou de database daar snel genoeg
voor moeten zijn. 

Als je de data in je geheugen moet hebben, bijvoorbeeld om snel een aantal controles los te laten of een of andere
scheduling routine, dan zou je bijvoorbeeld met een array kunnen werken per operator. 

Dus een tabel met een regel van 7*48=350 bits (=44 byte). 
Per operator krijg je dan een regel van 44 bytes. Stel dat je 100 operators moet plannen in je geheugen dan praat je
over een datastructuur van 4K (dat paste zelf nog op mijn ZX81 van 20 jaar geleden....). Heeft een operator een voorkeur
dan zet je het bitje hoog, heeft de operator geen voorkeur, dan zet je het bitje laag. 

Stel dat je die bitjes plaats in blokken van 8 bits (bv een char) dan kun je heel snel zien of in dat blok niemand een
voorkeur heeft door de blokken te anden (binaire and). Als daar 0 uitkomt 
heeft niemand een voorkeur in die periode. 

Wat betreft een treeview, zover ik weet is het niet handig om de hele tree vooraf op te bouwen omdat dat dan langzaam
en log kan worden. De toepassingen die ik heb gezien bouwen allemaal hun detail pas op op het moment dat je de betreffende
node opent. 

Hopelijk heb ik je niet nog verder van huis geholpen, maar mogelijk is deze insteek wel een begin naar je oplossing. 

Benno 

--

wat ik ook nog wilde vragen benno, hoe zou je dat moeten doen dan, met die bits? voorzover ik weet is het enige aan
bits dat delphi aankan een string met enen en nullen. 

kun je misschien ff een ciode voorbeeldje geven... 

--

Voorbeeldje: 

Var test : array[0..43] of byte; { array van 44 bytes } 

Nu wil ik in het eerste byte bit 1 hoog hebben (LSB= bit0): 

test[0] := $02; { Nu staat hier dus in %0000 0010 } 

Nu wil ik ook bit 2 hoog maken: 

test[0] := test[0] OR $04; { Test[0] is nu dus 0000 0110 } 

Nu wil ik bit 1 laag maken en bit 2 hoog laten: 

test[0] := test[0] AND $FD; { test[0] is nu dus 0000 0010 } 

Dus in feite ga je gewoon binair tellen. 
1 and 1 = 1 
1 and 0 of 0 and 1 = 0 

Als je Or gebruikt worden alle bitjes die nog niet 1 waren 1, bitjes die al 1 waren blijven 1. 

Een andere hele leuke is de XOR. 
AB Result 
00 0 
01 1 
10 1 
11 0 

In jouw voorbeeld zou je dus per supervisor een array zoals test maken, met in de halfuur blokken die hij wil een 1
en verder 0. 

Wil je nu van alle supervisors zien of er iemand een voorkeur heeft in een byte, kun je in een loop gewoon de betreffende
bytes met OR vergelijken. Als het uiteindelijke resultaat 0 is, heeft dus niemand een voorkeur opgegeven. 

Door met een masker te werken kun je hetzelfde doen voor 1 halfuurblok. Stel je wilt over alle supervisors weten of
iemand in het eerste byte in bit 3 een voorkeur heeft gegeven. Je zou dan een 2 dimensonale array maken: 

var test : array[1..aansupvisor][0..43] of byte; 
Teller : Integer; 
result : Byte; 

result := 0; 
for teller := 1 to aantsupervisor do result := Result OR test[teller][0]; 
IF (result AND $02) = 0 
Then 'Geen enkele voorkeur'; 

Je kunt dus heel handig met maskers van alles uitfilteren. 

Ik hoop dat je er iets mee kan, anders geef je maar weer een gil. 

Benno