Toon posts:

[Access] Invoegen record zonder duplicaten

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben momenteel bezig met het maken van een systeem om werknemers in te plannen voor bepaalde dagen. Ik gebruik een kalenderbesturingselement om de datum te kiezen en een drop-down list om de werknemer te kiezen. Daarnaast wordt er nog gebruik, gemaakt van een tijd.

De achterliggende tabel Planning ziet er zo uit:
code:
1
PlanningID(PK), TijdID, Datum, AgentID

PlanningID is dus de PK, TijdID verwijst naar een andere tabel waarin vaste werktijden zijn aangegeven (TijdID 1 is bv. van 17:00 - 21:00, we werken met shifts). Datum is de datum dat er gewerkt wordt en AgentID tot slot is het ID van de werknemer.

Om een nieuwe planning toe te voegen heb ik de volgende query gemaakt:
code:
1
2
INSERT INTO Planning (Datum, AgentID, TijdID)
SELECT [Kalenderbesturingselement], [Dropdown werknemer], [Tijd]

Met behulp van wat VB code is het niet mogelijk om een planning toe te voegen zonder AgentID, DatumID of TijdID.

So far so good. Alles werkt precies zoals ik het wil, op een klein maar vitaal element na.

Helaas is het namelijk mogelijk om een werknemer vaker voor dezelfde datum en tijd in te plannen. Zo kan het voorkomen dat werknemer 2 drie keer op dezelfde dag en dezelfde tijd ingepland staat. Wat ik dus wil is dat dat niet mogelijk is. Handen uit de mouwen dus, query gemaakt:
code:
1
2
3
4
5
SELECT count(p.PlanningID)
FROM Planning p
WHERE p.AgentID = [Dropdown werknemers]
AND p.Datum = [Kalenderbesturingselement]
AND p.TijdID = [Tijd]

Ook dit werkt, als je nu op het formulier een datum, tijd en werknemer hebt geselecteerd en die werkt dan al, dan geeft de query een 1 terug. Wat ik nu dus wil is dat de query uitgevoerd wordt in VB, en dat de code die bij de knop hoort om de query aan te roepen niet uitgevoerd wordt.

Iets als:
code:
1
2
3
4
If [QueryTel] > 0 Then
MsgBox("Werknemer al ingepland")
Else {Querytoevoegen]
End If

Maar wie o wie weet hoe dit precies moet?!?!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 25-07 18:17

Skinny

DIRECT!

Kan je niet beter een samengestelde primary key maken op Datum, Tijd en Werknemer ??

Mocht je dit niet willen kan je met
code:
1
CurrentDb.QueryDefs("QueryName").OpenRecordSet

wel doen wat je wilt. Zoek anders even in de Help of MSDN op dit commando, daar zal vast wel een voorbeeld bij staan.

SIZE does matter.
"You're go at throttle up!"


Verwijderd

Topicstarter
Op dinsdag 11 juni 2002 14:09 schreef Skinny het volgende:
Kan je niet beter een samengestelde primary key maken op Datum, Tijd en Werknemer ??

Mocht je dit niet willen kan je met
code:
1
CurrentDb.QueryDefs("QueryName").OpenRecordSet

wel doen wat je wilt. Zoek anders even in de Help of MSDN op dit commando, daar zal vast wel een voorbeeld bij staan.
Uit het oogpunt van een consistente db is een samengestelde PK inderdaad beter. Het brengt in mijn geval echter ook wat extra werk mee, en de huidige situatie biedt in mij geval weinig problemen.

Het stukje code dat je geeft lijkt me redelijk duidelijk, ga ik dan ook proberen! Op MSDN het volgende gevonden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Sub UKOrders()
    Dim dbs As Database, rst As Recordset
    Dim strSQL As String

    ' Return reference to current database.
    Set dbs = CurrentDb
    strSQL = "SELECT * FROM Orders WHERE [ShipCountry] = 'UK'"
    Set rst = dbs.OpenRecordset(strSQL)
    rst.MoveLast
    Debug.Print rst.RecordCount
    rst.Close
    Set dbs = Nothing
End Sub

Als ik daar dan het volgende van ga maken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Sub DubbelPlanning()
    Dim rst As Recordset, stDocName As String
    Set rst = CurrentDb.QueryDefs("CheckPlanningDubbel").OpenRecordset
    rst.MoveLast
    
    If rst.RecordCount > 0 Then
    MsgBox("Werknemer werkt al")

    Else stDocName = "PlanningInvoegen"
    DoCmd.OpenQuery stDocName, acNormal, acEdit
    End If

    rst.Close
End Sub

Zou het moeten werken... toch?

  • Uiligheid
  • Registratie: December 2000
  • Laatst online: 20-08 15:21

Uiligheid

alle gekheid op een stokje

lijkt mij wel, ja.

Maarem... wat ik me even afvroeg toen ik je verhaaltje las... kun je niet beter shifts maken, die een planningsID hebben? Dan kun je meerdere Agents koppelen aan een shift... dat lijkt mij het meest logisch :?

Ceterum censeo Carthaginem esse delendam


Verwijderd

Topicstarter
Op dinsdag 11 juni 2002 15:41 schreef Uiligheid het volgende:
lijkt mij wel, ja.

Maarem... wat ik me even afvroeg toen ik je verhaaltje las... kun je niet beter shifts maken, die een planningsID hebben? Dan kun je meerdere Agents koppelen aan een shift... dat lijkt mij het meest logisch :?
Probleem van die methode is (denk ik) dat je dan elke shift apart "aan moet maken" voordat je er een agent aan kan koppelen. Toch? En als je bedenkt dat er per dag 6 shifts zijn, en dat we 365 dagen per jaar open zijn...

Aangezien de shifts op een dag vast staan (7:00 - 13:00, 9:00 - 13:00 , 13:00 - 17:00, 17:00 - 21:00, 21:00 - 0:00, 0:00 - 01:15) leek het mij het meest logisch om deze apart in een tabel te zetten, met een uniek ID.

[/edit]

Volgens mij is mijn methode ook beter voor de consistentie.. toch?

Verwijderd

code:
1
2
3
4
5
6
    Dim rst As Recordset, stDocName As String
    Set rst = CurrentDb.QueryDefs("CheckPlanningDubbel").OpenRecordset
    rst.MoveLast
    
    If rst.RecordCount > 0 Then
    MsgBox("Werknemer werkt al")
Lijkt me een beetje overbodig. Als je recordset EOF is (leeg dus) kun je al geen movelast uitvoeren. Je code zou dus al vastlopen voordat je de recordcount kunt bekijken...

Verwijderd

Topicstarter
Op dinsdag 11 juni 2002 15:10 schreef DaJaN het volgende:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Sub DubbelPlanning()
    Dim rst As Recordset, stDocName As String
    Set rst = CurrentDb.QueryDefs("CheckPlanningDubbel").OpenRecordset
    rst.MoveLast
    
    If rst.RecordCount > 0 Then
    MsgBox("Werknemer werkt al")

    Else stDocName = "PlanningInvoegen"
    DoCmd.OpenQuery stDocName, acNormal, acEdit
    End If

    rst.Close
End Sub

Dit werkt dus helaas niet. Ik krijg een foutmelding dat het aantal parameters niet klopt, dat dat 2 moet zijn. het foutje zit in
code:
1
Set rst = CurrentDb.QueryDefs("CheckPlanningDubbel").OpenRecordset

Iemand een idee hoe dit opgelost kan worden?

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 25-07 18:17

Skinny

DIRECT!

Blijkbaar maakt de Query die je opent, gebruik van parameters. Geef de definitie van je query eens anders.

SIZE does matter.
"You're go at throttle up!"


Verwijderd

Topicstarter
Op vrijdag 14 juni 2002 14:29 schreef Skinny het volgende:
Blijkbaar maakt de Query die je opent, gebruik van parameters. Geef de definitie van je query eens anders.
code:
1
2
3
4
5
SELECT p.PlanningID
FROM Planning p
WHERE p.AgentID = [Dropdown werknemers]
AND p.Datum = [Kalenderbesturingselement]
AND p.TijdID = [Tijd]

Dit is de code van de query. De elementen tussen de [] komen uit het formulier, dat gewoon geopend is. Als ik de query gewoon run vanuit het Access scherm werkt ie wel gewoon...

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Volgens mij heb je ook nog een probleem met de eerste twee shifts, die overlappen namelijk.
Ik zou de definitie van de shifts wel in een aparte tabel zetten, maar de tijden gewoon los opnemen.
Dan wordt je overlap controle veel eenvoudiger.

Verwijderd

Topicstarter
OK, probleem is dus dat de query de elementen niet kan vinden uit het formulier. De Datum en AgentID worden opgevraagd uit het formulier, en als ik de query handmatig draai als het formulier geopend is werkt het zonder problemen. Draai ik de query vanuit VB dan kan ie opeens de twee parameters niet meer vinden. Heel vreemd, aangezien het formulier nog steeds gewoon geopend is, sterker nog, de query wordt aangeroepen met een button op het formulier!

Ik heb geprobeerd om de query als string in de VB code te verwerken, maar ook dat biedt geen soelaas. Daarnaast ben ik aan de slag geweest met PARAMETER, maar daar is me de werking nog niet geheel duidelijk van. Iemand een oplossing?
Op vrijdag 14 juni 2002 14:50 schreef Goodielover het volgende:
Volgens mij heb je ook nog een probleem met de eerste twee shifts, die overlappen namelijk.
Ik zou de definitie van de shifts wel in een aparte tabel zetten, maar de tijden gewoon los opnemen.
Dan wordt je overlap controle veel eenvoudiger.
De eerste twee shifts overlappen inderdaad, maar het punt is dat die shifts op verschillende dagen vallen (ene doordeweeks, de andere in het weekend). Een probleem moet dit vormen IMO.

Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Sub DubbelPlanning()
    Dim rst As Recordset, stDocName As String
    Set rst = CurrentDb.QueryDefs("CheckPlanningDubbel").OpenRecordset
    rst.MoveLast
    
    If rst.RecordCount > 0 Then
    MsgBox("Werknemer werkt al")

    Else stDocName = "PlanningInvoegen"
    DoCmd.OpenQuery stDocName, acNormal, acEdit
    End If

    rst.Close
End Sub

Dit stukje code roept een query aan, en die query gebruikt in de WHERE clausule twee waardes uit een formulier. Probleem is dat ik een foutmelding krijg zodra ik de query op ga roepen via dit stukje code. Start ik de query handmatig, dan is er niets aan de hand, maar zoals ik al zei, via de code krijg ik de foutmelding: "Parameters ontbreken. Het verwachte aantal is : 2". Deze foutmelding krijg ik ook als het formulier geopend is. (of juist eigenlijk...). Weet iemand een manier waarmee ik dit op kan lossen?

  • robjanssen
  • Registratie: September 2001
  • Laatst online: 02-08 16:10

robjanssen

Software Developer

Je kunt toch ook gewoon die SELECT query in VB draaien en dan handmatig de 2 variabelen invullen, want die zijn al geselecteerd op je form.
En dan daarna kijken wat de recordcount is.

Verwijderd

volgens mij moet je eerst de querydef definieren

set qdef=db.createquerydef("select bla from bla where veld = [p1]")

dan de parameters setten

qdef!p1 = "value"

en dan je rst vullen met de querydef

set rst = db.querydef(qdef)

Verwijderd

Topicstarter
HIer ben ik nu in ieder geval uit. je moet met Parameters werken, die eerst definieren en dan een waarde toewijzen daaraan! Yes, it works :P !!

(heb me zitten zweten op dit stukje...)
Pagina: 1