08. februar 2009 - 16:57
#1
Selv om du denne gang har lagt dit spørgsmål under kategorien Visual Basic, og dermed indikerer, at du ønsker en "kode"-løsning, vil jeg alligevel foreslå dig at lave en database-baseret løsning i stedet.
Jeg vil foreslå dig, at oprette to tabeller:
1) En tabel med ugedage og arbejdstidspunkter.
2) En tabel med alle datoer for de næste mange år frem i tiden.
1) Opret en tabel UgeArbejdstider (Dagsnr, Type, Starttid, Sluttid):
1, 'OB2', #00:00:00#, #05:59:59#
1, 'N', #06:00:00#, #18:59:59#
1, 'OB1, #19:00:00#, #23:59:59#
2, 'OB1', #00:00:00#, #05:59:59#
2, 'N', #06:00:00#, #18:59:59#
2, 'OB1, #19:00:00#, #23:59:59#
3, 'OB1', #00:00:00#, #05:59:59#
3, 'N', #06:00:00#, #18:59:59#
3, 'OB1, #19:00:00#, #23:59:59#
4, 'OB1', #00:00:00#, #05:59:59#
4, 'N', #06:00:00#, #18:59:59#
4, 'OB1, #19:00:00#, #23:59:59#
5, 'OB1', #00:00:00#, #05:59:59#
5, 'N', #06:00:00#, #18:59:59#
5, 'OB1, #19:00:00#, #23:59:59#
6, 'OB1', #00:00:00#, #18:59:59#
6, 'OB2, #19:00:00#, #23:59:59#
7, 'OB2, #00:00:00#, #23:59:59#
hvor Mandag har ugedag nr. 1, tirsdag nr. 2 osv.
2) Opret en tabel med alle årets dage (datoer). Det behøver ikke at være så stort et arbejde, som det måske i første omgang kunne se ud til at være. Og når arbejdet først er gjort, kan denne tabel bruges i mange sammenhænge, så det er en god investering.
Opret i første omgang en lille tabel, som Tal09 med ét felt Tal, som bare indeholder tallene fra 0 til 9 (du skal indtaste disse manuelt).
Opret nu en tom tabel Datoer som indeholder ét felt: Dato
Tricket er nu, at du kan bruge den lille tabel med tallene fra 0 til 9 til at danne datoerne. Opret en indsætningsforespørgsel:
INSERT INTO Datoer
SELECT DateAdd("d",t1.Tal*1000+t2.Tal*100+t3.Tal*10+t4.Tal, #01-01-2008#)
FROM Tal09 t1, Tal09 t2, Tal09 t3, Tal09 t4
WHERE DateAdd("d",t1.Tal*1000+t2.Tal*100+t3.Tal*10+t4.Tal, #01-01-2008#) < #01-01-2020#
Du vil nu have en en tabel Datoer, som indeholder alle datoer fra 1. januar 2008 til 31. december 2019. Det er altid en afvejning om man vil have mange eller få datoer i tabellen, for naturligvis tager forespørgsler længere tid jo flere rows der er i tabellen.
Hvis du vil, kan du nu slette den lille tabel med tallene fra 0 til 9 igen.
Du kan nu kombinere de tre tabeller Grund, UgeArbejdstider og Datoer i en forespørgsel, som specificerer den brugte tid:
SELECT Grund.StartDag, Grund.StartKI, Grund.SlutDag, Grund.SlutKI, Datoer.DATO, Weekday([Dato],2) AS Ugedag, UgeArbejdstider.Type, UgeArbejdstider.StartTid, UgeArbejdstider.SlutTid, IIf(Datoer.Dato=Grund.StartDag And Grund.StartKI Between UgeArbejdstider.Starttid And UgeArbejdstider.Sluttid,Grund.StartKI,UgeArbejdstider.Starttid) AS StartTidspunkt, IIf(Datoer.dato=Grund.SlutDag And Grund.SlutKI Between UgeArbejdstider.Starttid And UgeArbejdstider.Sluttid,Grund.SlutKI,UgeArbejdstider.Sluttid) AS Sluttidspunkt, DateDiff("n",IIf(Datoer.Dato=Grund.StartDag And Grund.StartKI Between UgeArbejdstider.Starttid And UgeArbejdstider.Sluttid,Grund.StartKI,UgeArbejdstider.Starttid),IIf(Datoer.dato=Grund.SlutDag And Grund.SlutKI Between UgeArbejdstider.Starttid And UgeArbejdstider.Sluttid,Grund.SlutKI,UgeArbejdstider.Sluttid)) AS Minutter
FROM Grund, Datoer, UgeArbejdstider
WHERE (((Datoer.DATO)>Grund.StartDag And (Datoer.DATO)<Grund.SlutDag) And ((Weekday([Dato],2))=UgeArbejdstider.Ugedag)) Or (((Datoer.DATO)=Grund.StartDag) And ((UgeArbejdstider.SlutTid)>=Grund.StartKI) And ((Weekday([Dato],2))=UgeArbejdstider.Ugedag)) Or (((Datoer.DATO)=Grund.SlutDag) And ((UgeArbejdstider.StartTid)<=Grund.SlutKI) And ((Weekday([Dato],2))=UgeArbejdstider.Ugedag))
ORDER BY Grund.StartDag, Grund.StartKI, Datoer.DATO, UgeArbejdstider.StartTid;
Jeg ved godt, at der er lidt mange felter i den forespørgsel, men det er for at du bedre kan tjekke om resultatet er rigtigt.
Held og lykke