Hej ! Ifall du använde MSSQL så vore det kanske möjligt att kolla detta i databasen med en trigger, men inte med Access. Kan du inte bara skapa två unika index som innehåller Följande fråga plockar ut bokningar av en reperatör under en angiven period: "Följande fråga plockar ut bokningar av en reperatör under en angiven period:" Följande fråga plockar ut bokningar av en reperatör under en angiven period(där jobbet är påbörjat och avslutat under den perioden) För att kolla ifall den önskade bokningen sammanfaller med någon befintlig bokning får du kolla efter alla bokningar där: Vad jag försökte uppnå med min fråga är att just slippa alla dessa vilkor. Men kanse förväxlade start- och sluttid när jag skrev frågan ovan. Jag fick göra lite som du sa.... Smidig metod. Den måste jag komma ihåg. :) Jag tror du har rätt. Eftersom det annars leder till konkreta fel när man kokar efter eller för en existerande bokning.Bokningstabell
Om man har en tabell i Access för att t.ex. spara Besiktingsbokningar till bilen och som innehåller:
ReparatörID, KundID, StartTid, SlutTid och Datum
Hur går man då tillväga för att man inte ska kunna boka en Reparatör på samma tid och samma datum flera gånger.
Och man ska ju inte heller kunna boka en kund samma tid och samma datum flera gånger.
Kan man på något sätt fixa det direkt i databasen eller ska man kolla igenom det i datasetet som man i mitt fall har i C#.
Eller ska man dela tabellen på något vis?
ReparatörID och KundID är kopplat till en tabel som håller alla personuppgifterna.
mvh
/RickySv: Bokningstabell
Kolla ifall det finns några poster som krockar innan du lägger in posten i databasen. Ställ en fråga som räknar hur många poster som överlappar tiden, och där antingen reparatören eller kunden är samma.Sv: Bokningstabell
ReparatörID, Datum, StartTid
respektive
KundID, Datum, StartTid ?
Får ju iofs ett exception vid insert men...
/JohanSv: Bokningstabell
<code>
lngReparatörID = 1456
vFrom = CDate("2004-05-14 12:00")
vTo = CDate("2004-05-14 12:00")
strSQL = "SELECT Null" & vbCrLf & _
"FROM Bokningar" & vbCrLf & _
"WHERE Bokningar.ReparatörID = " & lngReparatörID & " AND NOT (StartTid > #" & vTo & "# OR SlutTid < #" & vFrom & "#)"
</code>
Om rs är EOF saknas bokningar under angiven period.Sv: Bokningstabell
Det där kan väl ändå inte stämma????
Kolla koden nedan, en reparetör har en bokning mellan 12:00 och 13:00. Då skall din kod mao plocka ut alla bokningar mellan 08:00 och 17:00?? Hur många bokningar får du upp om du kör scriptet nedan tror du?
<code>
create table #Bokningar (ReparatörID int, StartTid datetime, SlutTid datetime)
insert into #bokningar values (1460, '2004-05-14 12:00', '2004-05-14 13:00' )
declare @lngReparatörID int
set @lngReparatörID = 1460
declare @toTime datetime
declare @endTime datetime
set @toTime = '2004-05-14 08:00'
set @endTime = '2004-05-14 17:00'
SELECT *
FROM #Bokningar bok
WHERE Bok.ReparatörID = @lngReparatörID
AND NOT (StartTid > @toTime OR SlutTid < @endTime)
drop table #Bokningar
</code>Sv: Bokningstabell
<code>
SELECT *
FROM #Bokningar bok
WHERE Bok.ReparatörID = @lngReparatörID
AND (StartTid > @toTime and SlutTid < @endTime)
</code>
Plockar ut bokningar som påbörjas under perioden(dvs de kan ha en senare sluttid).
<code>
SELECT *
FROM #Bokningar bok
WHERE Bok.ReparatörID = @lngReparatörID
AND (StartTid > @toTime and StartTid < @endTime)
</code>Sv: Bokningstabell
(NyStartTid<StartTid and NySlutTid>StartTid) or (NyStartTid<SlutTid and NySlutTid>SlutTid) or (NyStartTid>StartTid and NySlutTid<SlutTid)
Detta hanterar alla sätt som tiderna kan överlappa varandra på.Sv: Bokningstabell
Om vi vill plocka ut bokningar som infaller under en period kan man göra det på två sätt. Försöka skriva vilkor som Guffa och hantera alla kombinationer för att kontrollera om det infaller i angiven period.
Eller så kan man göra det lätta sättet: Uteslutningsmetoden!
Istället för att kontrollera om en bokning infaller under en period. Är det lättare att kontrollera om den infaller utanför perioden:
Bokning ligger tidigare än perioden:
BokningSlut < PeriodStart
Bokning ligger efter perioden:
BokningStart > PeriodSlut
Detta ger vilkoret:
WHERE (BokningSlut < PeriodStart) OR (BokningStart > PeriodSlut)
Men vi söker ju om bokningen ligger i intervallet. Varför kontrollerar vi då om den ligger utaför?
Enkel logik: Ligger den INTE utanför, måste den ligga innanför. Nyckelordet är att invertera vilkoret.
Detta ger vilkoret:
WHERE NOT ((BokningSlut < PeriodStart) OR (BokningStart > PeriodSlut))
Låt oss testa logiken konkret med följande bokningar:
---+--------------------------
Pos|0----5---10---15---20---25
---+--------------------------
1 |0----5
2 |0--------10
3 |0-------------15
4 |0------------------20
5 |0-----------------------25
6 | 5------------------25
7 | 10-------------25
8 | 15--------25
9 | 20---25
Låt oss kontrollera vilka bokningar som ligger mellan 7 och 12.
Vi börjar med att kontrollera om BokningSlut(Högersiffra) är mindre än 7. Vi kan då uteluta pos: 1
Vi kontrollera därefter om BokningStart(vänstersiffra) är större än 12. Vi kan då uteluta pos: 8 och 9
Svar: bokningar 2, 3, 4, 5, 6 och 7 infaller under perioden 7 och 12
Detta var väl mycket lätt sätta att kontrollera vilka bokningar som infaller under en period.Sv: Bokningstabell
Fick skicka in frågor i tabellen för att se om det var OK att lägga bokningen...
/RickySv: Bokningstabell
Jag funderade på om man direkt kan härleda det villkoret genom att förenkla mitt villkor med booleks algebra?
Jag började titta på det, på skoj, och såg att när man inverterar (BokningSlut > PeriodStart) så får man (BokningSlut <= PeriodStart), inte (BokningSlut < PeriodStart).
Det fick mig att tänka på att man måste använda den här formen:
WHERE NOT ((BokningSlut <= PeriodStart) OR (BokningStart >= PeriodSlut))
Annars så kommer man inte att kunna boka angränsande tider.
Exempel:
Det finns en tid bokad från 12.00 till 13.00.
Man vill boka en tid mellan 11.00 och 12.00.
BokningSlut är då lika med PeriodStart, men tiderna överlappar inte varandra, alltså måste tiden gå att boka.
Nu ska jag se om jag minns tillräckligt av boolsk algebra för att härleda villkoret, också. :)Sv: Bokningstabell
T.Ex. :
Adam bokar från 3 till 4 och Bengt vill boka från 4 till 5:
<code>
WHERE NOT ((BokningSlut <= PeriodStart) OR (BokningStart >= PeriodSlut))
</code>
Ger:
<code>
WHERE NOT ((4 <= 4) OR (3 >= 5))
</code>
Är lika med:
<code>
WHERE NOT ((True) OR (False))
</code>
Är lika med:
<code>
WHERE NOT (True)
</code>
Är lika med:
<code>
WHERE False
</code>
vilket är korrekt. Bokningarna sammanfaller inte under samma period.
<code>
WHERE NOT ((BokningSlut < PeriodStart) OR (BokningStart > PeriodSlut))
</code>
Ger:
<code>
WHERE NOT ((4 < 4) OR (3 > 5))
</code>
Är lika med:
<code>
WHERE NOT ((False) OR (False))
</code>
Är lika med:
<code>
WHERE NOT (False)
</code>
Är lika med:
<code>
WHERE True
</code>
Vilket är inkorrekt.
Men det beror nog mer på att jag slarvat. Är ju tekniken som är det intressanta. ;o)
Men jag tackar dig Guffa för att påpekat detta för mig. Roligt att man man faktiskt har användning av "matematik" inom programmering.