aanwezigheid sleutels

Status
Niet open voor verdere reacties.

HankMegens

Gebruiker
Lid geworden
1 sep 2015
Berichten
100
Ik heb een tabel met sleutels en een tabel met werknemers.
Middels een formulier geef ik een sleutel aan een werknemer mee.
Echter wil ik dat voor de volgende uitgave van een sleutel, de reeds uitgegeven sleutel niet meer in de combobox zichtbaar is, totdat deze weer is ingeleverd.
Met filters en queries is het me niet gelukt. De uitgegeven sleutel(s) verdwijnen dan ook uit de eerder aangemaakte records.
 
We hebben meer informatie nodig. Bijvoorbeeld: hoe en waar leg je precies vast dat een sleutel is uitgegeven en hoe dat hij is ingeleverd?
Zoals zo vaak zou een (geanonimiseerde) voorbeelddatabase enorm helpen.
 
Ik kijk er later vandaag naar.
 
In essentie is je vraag niet zo moeilijk te realiseren. Je hebt een tabel Sleutels, een tabel Werknemers en een tabel Sleutel_Werknemer. In die laatste leg je vast dat een werknemer een specifieke sleutel krijgt (Afgiftedatum, SleutelID en WerknemerID) en dan is een sleutel dus in beginsel uitgeleend. Een sleutel kan uiteraard weer worden ingeleverd waarbij je de inleverdatum invult, waarna hij weer beschikbaar is voor een volgende werknemer.

In het formulier waarin je dat registreert, wil je dus de sleutels zien die beschikbaar zijn. Dat zijn sleutels met specifieke kenmerken:
1. De sleutel is nog nooit uitgegeven
2. De sleutel is uitgegeven, maar weer ingeleverd. Daarbij moet je kijken naar de laatste uitgifte van een sleutel.

De query die je voor je uitgifte gebruikt, zou ik dan ook baseren op twee subqueries (een Union query): de ene helft bevat een query die de sleutels bevat die nog nooit zijn uitgeleend (een Outer join query) en een query die kijkt naar de laatste uitgiftes, met een gevulde uitgiftedatum. Die combinatie levert je de lijst op met alle beschikbare sleutels. Als je dan een nieuwe uitgifte vastlegt, is de keuzelijst netjes bijgewerkt, want de laatst uitgegeven sleutel voldoet niet meer aan de criteria.
 
Ik heb nog niet naar je de kunnen kijken (laptop is zoek), maar er kwam nog wel een tweede 'probleemgevalletje' op in mijn hoofd. Afhankelijk van de situatie lijkt het mij dat een medewerker precies één, of wellicht meerdere sleutels kan hebben. Stel dat het om lockers gaat, en elke medewerker één locker krijgt.

Dan wil je dus óók voorkomen dat medewerkers die al een actieve sleutel hebben nóg een sleutel kunnen aanvragen. In essentie dezelfde techniek als bij de sleutelafgifte, dus ook de medewerkerslijst zou je dan moeten filteren.
Nogmaals: ik kan nu niet zien of die situatie van toepassing is, maar dat horen we dan graag :).
 
Een indicatie aanwezig zoals jij nu in je sleuteltabel hebt is niet nodig, en zelfs ongewenst, omdat het een afleidbaar gegeven is.

In beginsel moet je keuzelijst alle sleutels laten zien die niet uitgegeven zijn. Een query daarvoor is:
Code:
SELECT * FROM Tsleutel
WHERE sleutelID NOT IN (SELECT sleutelID FROM Tsleuteluitgifte WHERE innamedatum Is Null)
Een probleem in een doorlopend formulier is wel dat als je deze query als recordbron gebruikt, de sleutelnamen van de uitgegeven sleutels niet zichtbaar zijn, want die zitten niet in het queryresultaat. Ik heb dat opgelost door de complete sleutellijst als recordbron te gebruiken en alleen op het moment dat je een sleutel kiest deze te wijzigen in de genoemde query.
 

Bijlagen

Ik vind de query van Peter niet geweldig (omdat hij vermoed ik mijn berichtjes niet leest :)), al was het maar omdat je voor zijn variant helemaal geen subquery nodig hebt. Dat kan namelijk iets simpeler zo:
Code:
SELECT tSleutel.SleutelID, SleutelNaam
FROM tSleutel LEFT JOIN tSleuteluitgifte ON tSleutel.sleutelID = tSleuteluitgifte.sleutelID
WHERE tSleuteluitgifte.sleuteluitgifteID Is Null
Zoals ik al zei: gewoon met een Outer Join. Het tweede deel ontbreekt zelfs helemaal, en dat lijkt mij, zeker als je de db wat langer gebruikt, veel essentiëler dat die goed werkt. En dat is dit stuk:
Code:
SELECT tSleutel.SleutelID, SleutelNaam
FROM tSleutel INNER JOIN tSleuteluitgifte ON tSleutel.sleutelID = tSleuteluitgifte.sleutelID
GROUP BY tSleutel.SleutelID, SleutelNaam
HAVING Last(tSleuteluitgifte.innamedatum) Is Not Null
ORDER BY SleutelNaam

Bij elkaar gevoegd in een Union query krijg je dan:

Code:
SELECT tSleutel.SleutelID, SleutelNaam
FROM tSleutel LEFT JOIN tSleuteluitgifte ON tSleutel.sleutelID = tSleuteluitgifte.sleutelID
WHERE tSleuteluitgifte.sleuteluitgifteID Is Null
UNION
SELECT tSleutel.SleutelID, SleutelNaam
FROM tSleutel INNER JOIN tSleuteluitgifte ON tSleutel.sleutelID = tSleuteluitgifte.sleutelID
GROUP BY tSleutel.SleutelID, SleutelNaam
HAVING Last(tSleuteluitgifte.innamedatum) Is Not Null
ORDER BY SleutelNaam;
.
En daarmee heb je dus altijd de juiste gegevens in je keuzelijst staan.
 
De query die ik voorstel selecteert alle sleutels die niet in de verzameling uitgegeven sleutels voorkomen. En dat is precies wat nodig is. De waarde van de innamedatum speelt daarbij helemaal geen rol. Je hoeft alleen te kijken naar de uitgiftes die geen innamedatum hebben; dat zijn de uitgegeven sleutels en die doen dus niet mee. Klaar.
 
De query die ik voorstel selecteert alle sleutels die niet in de verzameling uitgegeven sleutels voorkomen. En dat is precies wat nodig is.
Nee, dat zie je dus echt totaal verkeerd. Zoals ik dacht ik wettig en overtuigend heb aangetoond. Zodra een sleutel minstens één keer is uitgeleend, staat er een record van in de tabel Sleuteluitgifte, en moet je die records dus meenemen in de query. Er is geen andere mogelijkheid. Ik zal dit ook verder niet meer uitleggen, want praten tegen dovemansoren is geen hobby van mij.
 
Ik heb het nu werkend gekregen, dank daarvoor.
Echter het veld aanwezig heb ik wel nodig (mensen verliezen de sleutel, of vergeten hem na hun dienst in te leveren). Deze wil ik dus (ook) niet zien bij de sleutels die ik kan uitgeven.
Ik dacht dus om Me.sleutelID.RowSource = "SELECT * FROM Tsleutel" te vervangen door Me.sleutelID.RowSource = "SELECT sleutelnaam FROM Tsleutel WHERE aanwezig = True"
Echter blijft het keuzemenu alle sleutels die niet zijn uitgegeven weergeven.
Ik heb het statemenet in een query getest en daar werkt het wel.
waar ga ik mis?

Hank
 
Ik snap het niet helemaal.

Als iemand vergeet een sleutel in te leveren, staat die nog gewoon geregistreerd als uitgegeven (en wordt die niet getoond als uitgeefbaar). Daar hoef je dus niets aanvullends of afwijkends voor te doen. Je kan zelfs met de bestaande gegevens signaleren welke sleutels langer dan x dagen geleden uitgeleend zijn en nog niet terug zijn.

Een verloren sleutel is een iets ander verhaal. Het ligt eraan hoe je daar mee om wil gaan. Wordt zo'n sleutel dan vervangen?
Zo ja (lijkt me logisch), dan kan die op uitgeven blijven staan en zodra de vervangende sleutel er is beschouw je dat als een inname.
Wordt de sleutel niet vervangen, dan kan je hem uit het systeem verwijderen.
 
Ik ben het (uiteraard, zou ik bijna zeggen) niet helemaal eens met Peter, maar ook niet met jou. Ook ik vind het veld Aanwezig nutteloos en overbodig. Maar om andere redenen dus.

Volgens mij is het simpel: je geeft weliswaar een sleutel uit, maar dat ding an sich heeft geen betekenis. Een sleutel geeft toegang tot iets, en dát is hetgeen je uitgeeft. Als iemand een sleutel verliest, blijft dat object gewoon bestaan. Alleen kan de (tijdelijke) gebruiker er niet meer bij. Een verloren sleutel moet je dus gewoon vervangen, en daar heb je geen extra veld voor nodig. Hooguit leg je dit soort gebeurtenissen vast in een aparte tabel.

Sleutels uit het systeem verwijderen is natuurlijk onzin, want dan klopt je systeem niet meer, want ofwel je relaties kloppen niet meer, ofwel je ben alle uitgave registraties kwijt. Moet je echt niet willen. Wél zou je een veld Inactief kunnen gebruiken, om sleutels die niet meer worden ingeleverd door oud-werknemers uit te faseren. Want die blijven anders als 'uitgegeven' in de tabel staan, wat dus niet correct is. En daar is ook makkelijk op te filteren. Maar dus níet een veld gebruiken om te bepalen of een sleutel uitgeleend is of niet.

Overigens lijkt het mij nuttiger om een correcte Uit dienst procedure te hebben waarbij ex werknemers hun sleutels gewoon inleveren :).
En als het in een query wél werkt, maar in je keuzelijst níet, dan wordt het wellicht weer tijd voor een nieuwe database, met de huidige oplossingen en liefst wat meer records om mee te testen. De vorige was natuurlijk volkomen ontoereikend, met 3 sleutels en één uitleen record :).
 
Heren,

Beide bedankt voor jullie input. Ik begrijp beide standpunten.
Ik ga een en ander eens bekijken en heroverwegen.
Mocht ik nog ergens tegen aanlopen dan maak ik wel een nieuw topic.

nogmaals bedankt voor het meedenken.

Hank
 
Heren,

Ik heb het topic toch maar weer even open gegooid.
de oplossing met de rowsource werkt. Nogmaals dank daarvoor.
Om een en ander beter te begrijpen heb ik een nieuwe database gemaakt om alles na te bootsen en te begrijpen.
Nu lijk ik alles werkend te hebben, echter bij het opnieuw openen van het formulier blijft de rowsource van een uitgegeven sleutel leeg.
Wat zie ik over het hoofd?

sluetel is wat ik heb ontvangen, lockerkey is wat ik gemaakt heb.
 

Bijlagen

Ik zal er vanmiddag even naar kijken. Om welke van de twee meegeleverde db's gaat het?
 
Bij het openen van het formulier moet de rijbron van de keuzelijst de totale lijst van sleutels zijn. Nu is de rijbron de lijst van beschikbare sleutels. De twee uitgifterecords hebben allebei betrekking op sleutel 1. Die is niet uitgeefbaar, zit niet in de rijbron en de gegevens ("naam" van de sleutel) kunnen dus niet getoond worden.
Pas als je op de keuzelijst klikt, moet je de rijbron inperken tot tot de uitgeefbare sleutels. Nadat je de nieuwe uitgifte heb vastgelegd, moet de rijbron weer terug naar alle sleutels, zodat ook de namen van de uitgeven sleutels zichtbaar zijn/blijven. De gebeurtenissen die ik in mijn voorbeeld maakte zorgen voor dat wisselen van de rijbron.
 
Ik snap niet zoveel van de uitleg van Peter, maar volgens mij is die nog fout ook. Ik kijk er morgen iets beter naar.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan