[DELPHI] ?-je voor mensen met zin om te lezen...

Pagina: 1
Acties:

  • 9900578Heck
  • Registratie: Juli 2001
  • Laatst online: 21-07 09:24
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;

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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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;

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 :D )

Verwijderd

Eerlijk gezegd snap ik er geen bal van...
maar een screenshot zou het wel iets verduidelijken...

Verwijderd

Doorgespit, maar volgens mij pak je 't met die treeview nodeloos ingewikkeld aan...
Je hebt een beperkt aantal agents (mag ik aannemen), en een beperkt aantal 30-minuten in een week (350??? is 't een 24-uurs callcenter?), dan is een 2-dimensionale array, of wat je zelf al zei: een TList van TLists, een overzichtelijker aanpak.

Hoe je vervolgens komt tot een zo goed mogelijke verdeling, tja... Daar zijn boeken over volgeschreven.
Zoek bv. maar 's op "Travelling Salesman"... ;)

  • 9900578Heck
  • Registratie: Juli 2001
  • Laatst online: 21-07 09:24
Dat had ik dus ook al gedacht om een tlist van tlists te maken maar dat gaat best veel geheugen vreten als dat voor 350 intervallen moet. (en ja het is een 24-uurs callcenter)
het is op dit moment nog geen echt 24-uurs center maar toch al van 8.00u 's morgens tot 0.00u 's avonds, maar het moet wel kunne dat lijnen 24 uur per dag open gaan.

het aantal agents is wel eindig, maar niet bekend.
als er een nieuw project komt met bv 100 agents moet dat ook kunnen....

edit:

vicz: - wat voor een screenshot had je willen zien?
- en wat snap je niet?

  • EWS99
  • Registratie: Maart 2001
  • Laatst online: 13:33
Tja, ik zou zeggen, gebruik die treeview voor bijvoorbeeld maar 1 week. De rest sla je op schijf op. Scheelt een hoop ruimte. De vraag is of een treeview wel het juiste component is om datgene wat jij wilt, weer te geven. Ik heb zelf weinig verstand van databases (met grids), maar misschien is dat een idee?
Kweetut anders ok nie

Hier had uw advertentie kunnen staan!


  • 9900578Heck
  • Registratie: Juli 2001
  • Laatst online: 21-07 09:24
Op woensdag 10 oktober 2001 20:55 schreef hardrocker het volgende:
Tja, ik zou zeggen, gebruik die treeview voor bijvoorbeeld maar 1 week. De rest sla je op schijf op. Scheelt een hoop ruimte...
het gaat niet om een week met datums ( dus bv 10 september tot 17 september) maar om een theoretische week. zal zo wel ff een screenshotje posten...

Verwijderd

Op woensdag 10 oktober 2001 20:44 schreef 9900578Heck het volgende:
Dat had ik dus ook al gedacht om een tlist van tlists te maken maar dat gaat best veel geheugen vreten als dat voor 350 intervallen moet. (en ja het is een 24-uurs callcenter)

het aantal agents is wel eindig, maar niet bekend.
Maak er dan een TList van AgentPrefs of zo, iets van:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface

type
  TWeekPrefs = array[0..6, 0..47] of byte;

  TAgentPrefs = class
    AgentID: integer;
    WeekPrefs: TWeekPrefs;
  end;

  TAgentPrefList = class(TList)
  private
    function GetItem(Index: integer): TAgentPrefs;
  public
    property Items[Index: integer]: TAgentPrefs read GetItem; default;
  end;

implementation

function TAgentPrefList.GetItem(Index: integer): TAgentPrefs;
begin
  Result := nil;
  if (Index >= 0) and (Index < Count) then
    Result := TAgentPrefs(inherited Items[Index]);
end;

En dat dan naar eigen smaak uitbouwen. Zal uiteindelijk minder geheugen gaan kosten dan jouw treeview, en beter te onderhouden zijn, vermoed ik.

  • 9900578Heck
  • Registratie: Juli 2001
  • Laatst online: 21-07 09:24
Op woensdag 10 oktober 2001 21:15 schreef Afterlife het volgende:

[..]

Maak er dan een TList van AgentPrefs of zo, iets van:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface

type
  TWeekPrefs = array[0..6, 0..47] of byte;

  TAgentPrefs = class
    AgentID: integer;
    WeekPrefs: TWeekPrefs;
  end;

  TAgentPrefList = class(TList)
  private
    function GetItem(Index: integer): TAgentPrefs;
  public
    property Items[Index: integer]: TAgentPrefs read GetItem; default;
  end;

implementation

function TAgentPrefList.GetItem(Index: integer): TAgentPrefs;
begin
  Result := nil;
  if (Index >= 0) and (Index < Count) then
    Result := TAgentPrefs(inherited Items[Index]);
end;

En dat dan naar eigen smaak uitbouwen. Zal uiteindelijk minder geheugen gaan kosten dan jouw treeview, en beter te onderhouden zijn, vermoed ik.
als ik dit goed begrijp doe jij het precies andersom, maar ik denk dat ik er wel iets mee kan.

ter verduidelijking:
ik moet dus per interval het aantal en de namen (in dit geval nummers) van de agents hebben die dat interval tussen hun prefs hebben zitten.
dus als jan(agent nr. 6024) en piet(agent nr. 6025) allebei maandag van 12 -13 u willen werken, dan komt er bij prefs[0,24] (dag 0 en interval 24)
en bij prefs[0,25] (dag 0 en interval 25) een lijstje van twee nummers te staan, namelijk 6024 en 6025.

Verwijderd

Op woensdag 10 oktober 2001 21:22 schreef 9900578Heck het volgende:
als ik dit goed begrijp doe jij het precies andersom, maar ik denk dat ik er wel iets mee kan.
Is inderdaad precies andersom, lijkt me logischer.
Op deze manier is 't veel gemakkelijker om die objectstructuur uit te breiden zodat 'ie bv. vragen als "wie hebben voorkeur voor maandag- en dinsdagochtend en vinden 't niet erg om ook woensdagochtend te werken?" aankan.

offtopic:
Ben nu weg, maar ik hou 't topic in de gaten... Succes! :)

  • 9900578Heck
  • Registratie: Juli 2001
  • Laatst online: 21-07 09:24
heb ff een screenshotje geplaatst van het voorkeurenscherm van agents, bekijk em Afbeeldingslocatie: http://www.phoenixnet.5u.com/ss1.jpg

ik heb al een algo-tje geschreven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
procedure TdmMain.GetAgentsAvailableOnTeam(CurrentQueriedTeam: integer;var a: TDay);
var off,nopref: array[1..7] of boolean;
    min,max:   array[1..7] of Integer;
    i,j,minval,maxval:  integer;
begin
  // maak alle lists aan en maak ze leeg
  for i:=1 to 7 do
    for j:=1 to 48 do
    begin
    a[i,j]:=tStringList.Create;
    a[i,j].Clear;
    end;
  with dsqAgent.DataSet do
  begin
    First;
    while not EOF do
    begin
    if aqAgentAgentTeamID.AsInteger=CurrentQueriedTeam then
    begin
      // check the hours within the working hours for this agent
      CheckForPrefHours(minVal,maxVal,aqAgentAgentID.AsInteger);
      // if the prefs are not in the database
      if not dmMain.LoadAgentPrefs(IntToStr(aqAgentAgentID.AsInteger),min,max,off,nopref) then
      // set standard prefs
        for i:=1 to 7 do
        for j:=minVal to maxVal do
          a[i,j].Add(IntToStr(aqAgentAgentID.AsInteger))
      else
      begin
      // load prefs from db
        for i:=1 to 7 do
        if off[i] then  // day off?
          break
        else
          if nopref[i] then    // then maybe no prefs??
            for j:=1 to 48 do
            a[i,j].Add(IntToStr(aqAgentAgentID.AsInteger))
          else           // then fill pref intervals
            for j:=min[i] to max[i] do
            a[i,j].add(IntToStr(aqAgentAgentID.AsInteger));

      end;
    end;
    next;
    end;
  end;
end;

het type tDay is zo gedefinieerd:
code:
1
2
3
  TAgents = TStringList;
  TInterval = array[0..47] of TAgents;
  TDay = array[0..6] of TInterval;

maar ook hier gaat wat mis. hij schijnt niets te accepteren als a[i,j].add('bladiebla')
dus alle statements waarbij je het element aanspreekt als tlist. Maar hij accepteert wel de creates die ik uitvoer op de a[i,j]'s.
:? :? :? :? :? :? :? :? :? :?

iemand een ideetje?
Pagina: 1