Toon posts:

[Acces] Klein vraagje over SQL

Pagina: 1
Acties:
  • 301 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Kort vraagje:

Ik heb een database met daarin 21 tabellen. Elke tabel staat voor een aparte locatie (vestiging van een school) en in elke tabel staat een lijst van personen op die locatie met gegevens van die personen. Ik heb een query gemaakt waar dmv een union alle personen per locatie onder elkaar opgesomd worden, totaal 234 records.

Nu wil ik een formulier maken, waar je een locatie kunt aanklikken en vervolgens de lijst met personen eronder verschijnt. Ik weet in grote lijnen wat ik moet doen, maar ik mis een klein detail geloof ik.

Ik heb de 'samenvoegquery' als uitgangssituatie genomen voor het formulier, vervolgens in de koptekst een keuzelijst ingevoerd die de locaties weergeeft (vervolgens GROUP BY Locatie gedaan voor die lijst, zodat elke locatie maar 1 keer voorkomt) en zodra je op een locatie klikt, wordt de eerste record van die locatie aangewezen in de tabel eronder (in die tabel staan dus alle 234 records).

Ik weet 99% zeker dat ik een bepaalde SQL-opdracht moet koppelen aan die keuzelijst om zo alleen de records van de geselecteerde locatie te laten zien en de rest te verbergen. De code ziet er momenteel als volgt uit:

Private Sub Form_Load()
' De record zoeken die overeenkomt met het besturingselement
Dim rs As Object

Set rs = Me.Recordset.Clone
rs.FindFirst "[Locatie] = '" & Me![Keuzelijst18] & "'"
Me.Bookmark = rs.Bookmark

End Sub


Private Sub Keuzelijst18_AfterUpdate()
' De record zoeken die overeenkomt met het besturingselement
Dim rs As Object

Set rs = Me.Recordset.Clone
rs.FindFirst "[Locatie] = '" & Me![Keuzelijst18] & "'"
Me.Bookmark = rs.Bookmark
End Sub

Dit resulteert er dus in dat, zodra je een locatie aanklikt, de eerste record van die locatie aangewezen wordt.

>> Welke code moet ik aan deze SQL-functie toevoegen om te zorgen dat hij alleen alle records van de gekozen locatie laat zien en de rest verbergt?

BVD :)

[ Voor 8% gewijzigd door Verwijderd op 21-10-2003 10:01 ]


Verwijderd

code:
1
2
3
4
5
Private Sub Keuzelijst18_AfterUpdate()
' De record zoeken die overeenkomt met het besturingselement
   me.filter =  Me![Keuzelijst18] & "'"
   me.refresh
End Sub


Dit zou vogges mij gewoon moeten werken.

Ten tweede moet je eens naar je datamodel kijken ... 21 tabellen met almal dezelfde SOORT info? Waarom niet in 2 tabellen? Maar dat zal voor je form nie zoveel uitmaken als je idd die union query als recordsource gebruikt

[ Voor 57% gewijzigd door Verwijderd op 21-10-2003 10:05 ]


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 09:41

gorgi_19

Kruimeltjes zijn weer op :9

* gorgi_19 ruikt ook een verkeerd datamodel....

Waarom 21 tabellen? Past toch allemaal perfect in 2 tabellen? (tabel personen en tabel locatie)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
gorgi_19 schreef op 21 October 2003 @ 10:04:
* gorgi_19 ruikt ook een verkeerd datamodel....

Waarom 21 tabellen? Past toch allemaal perfect in 2 tabellen? (tabel personen en tabel locatie)
Omdat het duidelijk per locatie afgeschermd moet zijn en mensen snel per locatie personen moeten kunnen toevoegen of verwijderen. De samenvoegquery zorgt er wel voor dat alles samengevoegd wordt in 1 tabel.
Verwijderd schreef op 21 October 2003 @ 10:03:
code:
1
2
3
4
5
Private Sub Keuzelijst18_AfterUpdate()
' De record zoeken die overeenkomt met het besturingselement
   me.filter =  Me![Keuzelijst18] & "'"
   me.refresh
End Sub
Hmm, die code geeft een foutmelding.
Het is de bedoeling dat, zodra je op een locatie klikt in de keuzelijst, alle records verborgen worden en alleen de records van die specifieke locatie nog zichtbaar zijn..

[ Voor 34% gewijzigd door Verwijderd op 21-10-2003 10:22 ]


Verwijderd

ja die code geeft ook een foutmelding.. was ook nie de bedoeling dat je 'm letterlijk overnam, meer om een idee te geven :)

zo dan:

me.filter = "locatieID = " & me.keuzelijst18

ik weet niet hoe jouw prim. key van de locatie tabelheet, maar die moet je dus vervangen voor "locatieID".. en als dat geen numerieke variabele is, moet je er ook nog ' om heen zetten...

Verwijderd

Topicstarter
Ik snap de opzet van je code, maar Acces snapt het volgens mij niet zo.
Als ik de bestaande code vervang door jouw filter-code (met aanpassingen zodat hij klopt binnen dit formulier) doet hij helemaal niks meer als je op een locatie klikt in de keuzelijst en als ik deze code bij de bestaande code in zet gebeurt er ook niks bijzonders...

Verwijderd

De event is ook verkeerd...

Deze moet Keuzelijst18_Change() zijn
Dus gebeurtenis "Bij Gewijzigd"
Niet afterupdate, want dan wordt het pas uitgevoerd wanneer je ECHT de waarde van de locatie aanpast in de database.. en dat wil je niet... je wilt deze alleen gebruiken en niet wijzigen

[ Voor 17% gewijzigd door Verwijderd op 21-10-2003 10:43 ]


Verwijderd

Topicstarter
|:( Dat haalt ook al niks uit...

Zowel de hele code onder Keuzelijst18_Change() zetten, als slechts het deel; het maakt niks uit, het werkt nog steeds niet. Acces doet net alsof hij die code niet ziet ofzo...

Maar de code om de eerste record van een locatie aan te wijzen in de tabel (zie mijn eerste post) staat wel onder Keuzelijst18_AfterUpdate() trouwens en die werkt wel.

Welke code zou je in principe kunnen gebruiken om de hele tabel te verbergen zodra je op een locatie klikt? Eerst kijken of dat werkt, anders ligt het probleem misschien in de database zelf ofzo..

[ Voor 50% gewijzigd door Verwijderd op 21-10-2003 10:55 ]


Verwijderd

dat kan alleen door de filter eigenschap in te stellen of een compleet nieuwe recordsource toe te kennen.. je gebruikt toch ook wel die me.refresh he?

ow, en ik ben vergeten te vertellen dat je ook nog me.filterOn = true moet doen :P
voordat je refreshed

En zet anders eens ergens een msgbox "hoi" neer, dan weet je tenminste dat die code wordt uitgevoerd.

[ Voor 22% gewijzigd door Verwijderd op 21-10-2003 10:57 ]


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op 21 oktober 2003 @ 10:10:
[...]

Omdat het duidelijk per locatie afgeschermd moet zijn en mensen snel per locatie personen moeten kunnen toevoegen of verwijderen.
Dat is bij lange na nog geen reden om je normalizatie volledig overboord te gooien. Nu loop je daar tegenaan. Bovenstaande 'problemen' zijn absoluut geen issue waneer je gewoon 2 tabellen had gebruikt, en je huidige probleem is a piece of cake met een 2 tabellen struktuur.

Heel vaak lijkt het in het begin handig om toch een bepaalde exotische structuur te gebruiken, maar achteraf blijkt men toch altijd weer tegen de lamp aan te lopen. Normalizatie is niet voor niks een van de belangrijkste onderdelen bij database ontwikkel cursusen/vakken!

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Janoz schreef op 21 oktober 2003 @ 10:57:
[...]

Dat is bij lange na nog geen reden om je normalizatie volledig overboord te gooien. Nu loop je daar tegenaan. Bovenstaande 'problemen' zijn absoluut geen issue waneer je gewoon 2 tabellen had gebruikt, en je huidige probleem is a piece of cake met een 2 tabellen struktuur.

Heel vaak lijkt het in het begin handig om toch een bepaalde exotische structuur te gebruiken, maar achteraf blijkt men toch altijd weer tegen de lamp aan te lopen. Normalizatie is niet voor niks een van de belangrijkste onderdelen bij database ontwikkel cursusen/vakken!
zijn probleem ligt echt niet aan zijn datamodel (ok, is verre van ideaal), maar zijn recordsource is gewoon 1 tabel (een query met unions).. het probleem zit 'm in z'n code.. welke heel simpel is, maar kennelijk mist hij de ervaring/kennis

Verwijderd

Topicstarter
Die msgbox "hoi" werkt alleen als hij onder AfterUpdate() komt te staan. Zodra je dan op een locatie klikt in de lijst komt er een popup met "hoi" tevoorschijn.
De code zal dus alsnog wel onder AfterUpdate() moeten komen, maar wellicht zal hij iets anders moeten ofzo..

Verwijderd

nee, je moet die dropdownbox nie koppelen aan een column... anders verander je telkens de data als je een locatie kiest

Verwijderd

Topicstarter
Ok, maar hoe moet het dan wel? :?

Verwijderd

ok, je moet wel een rowsource instellen, dat zijn dus alle locaties... Je moet 'm verder niet koppelen aan een column, anders verander je ook daadwerkelijk de data.

Als je dan een waarde uit die dropdownbox kiest, wordt het "Bij Wijzigen" event afgevuurd. Als je daaronder de volgende code hangt:

me.filter = "locatieID = " & me.keuzelijst18
me.filterOn = true
me.refresh

Dan zou het moeten werken

Verwijderd

Topicstarter
De Rowsource is
code:
1
SELECT [Samenvoegquery].[Locatie] FROM Samenvoegquery GROUP BY [Locatie];

Waardoor dus elke locatie 1 keer genoemd wordt in de dropdownbox.

Als verdere opdracht heb ik nu
code:
1
2
3
4
5
6
7
    Private Sub Keuzelijst18_Change()

Me.Filter = "'[Locatie]' =' " & Me.Keuzelijst18 '
    Me.FilterOn = True
    Me.Refresh

End Sub

Hierbij krijg ik een foutmelding en word ik doorverwezen naar de foutopsporing. De fout zit hem in de regel
Me.Filter = "'[Locatie]' =' " & Me.Keuzelijst18 ', maar die heb ik al op zoveel verschillende manieren aangepast dat ik niet meer zou weten hoe dit wél goed zou kunnen...

De code staat inmiddels onder AfterUpdate(), want onder Change() doet hij helemaal niks..
Change() staat ook niet bij het menu bovenaan trouwens, alleen dingen als BeforeUpdate(), Click() enz. staan daar tussen.. Wanneer ik Keuzemenu18_Change() gebruik herkent hij volgens mij ook niet meer dat dit met de dropdownbox te maken heeft..

[ Voor 17% gewijzigd door Verwijderd op 21-10-2003 13:49 ]


Verwijderd

oooow, als die onchange() daar nie bijstaat dan werkt het niet nee... welke access versie heb je dan? ik zit hier met Access XP, misschien dat ie in oudere versies nog niet bestond. Maar afterupdate is echt fout vogges mij.. maar kijk maar even.

Wat je in ieder geval fout doet is de enkele apastrofjes (') op [locatie]. Die moeten echt weg. De dubbele moeten wel blijven staan. Ook moet je wel kleine apastrofjes om me.keuzelijst doen

dus dan wordt het zo:

code:
1
me.Filter = "Locatie = '" & me.keuzelijst18 & "'"

[ Voor 13% gewijzigd door Verwijderd op 21-10-2003 13:54 ]


Verwijderd

Topicstarter
Ik heb Acces 2000, dus misschien dat het daar aan ligt, ik geloof niet dat er een vergelijkbare functie voor onchange() in zit, maar afterupdate moet naar mijn idee hetzelfde uithalen, omdat dat gewoon verwijst naar het moment waarop de filteractie uitgevoerd moeten worden (nadat je de keuzelijst ge-update hebt door een andere locatie aan te klikken)..

De code van de filter die je voorstelt heb ik ook al geprobeerd, maar nog steeds dezelfde foutmelding. Ik begin het idee te krijgen dat de fout in de database zelf zit...

Verwijderd

wat voor foutmelding krijg je dan?

Verwijderd

Topicstarter
Fout 3068 tijdens uitvoering:
De opgegeven naam is geen geldige aliasnaam

Waarna je kunt kiezen uit beëindigen en foutopsporing. De foutopsporing brengt je terug naar visual basic en wijst de regel Me.Filter = "Locatie = '" & Me.Keuzelijst18 & "'" aan...

Verwijderd

ok, hoe ziet die "samenvoeg query" er dan uit? Het lijkt er op dat "Locatie" daar hilmal nie in voorkomt, althans, niet precies onder die naam.

Post de SQL eens

Verwijderd

Topicstarter
Locatie komt wel degelijk voor in de samenvoegquery, zoals ik in mn eerste post al vertelde krijg ik het wel voor elkaar dat, wanneer je een locatie uit de dropdownbox selecteert, Acces de eerste record voor die locatie aanwijst in het formulier. (Het zit dus zo dat alle 234 records onder elkaar staan, gesorteerd op locatie en zodra je in de dropdownbox op een locatie klikt wordt de eerste record van die locatie aangewezen).
Voor die actie wordt de volgende regel gebruikt (zie eerste post):
rs.FindFirst "[Locatie] = '" & Me![Keuzelijst18] & "'"
hetgeen bijna hetzelfde is als de filter-optie die je voorstelde, maar deze selecteert dus de eerste record van de gekozen locatie (vandaar de rs.findfirst :P).

Maar nog even voor de volledigheid, de SQL van de samenvoegquery ziet er ongeveer zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
SELECT *, "Locatie 1" as Locatie
FROM [Locatie 1]

UNION

SELECT *, "Locatie 2" as Locatie
FROM [Locatie 2]

UNION

SELECT *, "Locatie 3" as Locatie
FROM [Locatie 3]

enzovoorts enzovoorts, voor alle locaties (maar dan dus met namen van de locaties ipv locatie 1, 2, 3). Dit resulteert in een tabel waar per persoon eerst in het veld Locatie de locatie genoemd wordt en vervolgens de gegevens per persoon zoals ze ook in de afzonderlijke tabellen te vinden zijn.

Euhm, suggesties? :)

[ Voor 4% gewijzigd door Verwijderd op 21-10-2003 17:28 ]


Verwijderd

Topicstarter
Iemand? O-)

Verwijderd

Topicstarter
Ok, ik ga proberen of het wel lukt als ik mijn datamodel omgooi.
Ik maak (zoals mij voorgesteld werd aan het begin van dit topic) twee tabellen; eentje met personen en eentje met locaties.

Kan iemand mij vertellen wat dan de beste manier is om vervolgens te zorgen dat ik in een formulier een dropdownbox kan maken met daarin alle Locaties opgesomd en dat, zodra je een locatie aanklikt, een lijst met personen van die locatie eronder verschijnt?

Verwijderd

Ik hoop niet dat je dit een lullige reactie vindt, maar dit is wel een hele basic vraag. Elk beginnersboek voor Access behandelt hoe je relaties legt tussen twee tabellen en daarna met behulp van een formulier met subformulier de gegevens kan tonen.
(Geef ik toch nog deels het antwoord :) )

Verwijderd

Topicstarter
Als je de rest van dit topic had bekeken zou je zien dat dit niet zo simpel ligt als je denkt...

Mensen die wel een serieus antwoord willen geven?

Verwijderd

Topicstarter
Nevermind, ik ben er inmiddels zelf uitgekomen..
Ik veranderde mn datamodel, naar twee tabellen, eentje met Personen en eentje met Locaties, linkte de Locatie-rijen aan elkaar, maakte een query en vervolgens gooide ik alles in een formulier en voegde daar een dropdownbox aan toe met de visual basic code:
code:
1
2
3
4
5
6
7
Private Sub Keuzelijst12_AfterUpdate()

    Me.Filter = "[Locatie] = '" & Me![Keuzelijst12] & "'"
    Me.FilterOn = True
    Me.Refresh

End Sub

en hij loopt als een trein!

Bij deze wil ik Tijz nog even bedanken voor alle tips, want daardoor lukte het me om die code samen te stellen! _/-\o_
Pagina: 1