Variabel veld in de query

  • Onderwerp starter Onderwerp starter BasHD
  • Startdatum Startdatum
Status
Niet open voor verdere reacties.

BasHD

Gebruiker
Lid geworden
2 dec 2008
Berichten
99
Hallo,

Ik ben aan het query's maken in Access. In de ontwerpweergave kan ik vanuit de tabel of query een veldnaam naar Veld: brengen. Kan ik veld: (de kolom in een query) ook automatisch vullen? Kan ik bijvoorbeeld in een formulier een keuzelijst maken en dat hetgeen wat ik daar kies in het hokje veld komt te staan? Dan hoef ik namelijk veel minder query's te maken.

Zou iemand zo vriendelijk willen zijn mij wat tips te geven?

Hartelijke groet,

Bas Bassa
 
Ik zou dan een knop op het formulier maken die je query in SQL opbouwt, en vervolgens runt. Ervan uitgaande dat je gelijk het resultaat wilt zien.
De code om de query op te bouwen zet je op het <Na bijwerken> event (gebeurtenis) van je keuzelijst.

Ziet er, heel schematisch gezegd, ongeveer zo uit:

Code:
strSQL="SELECT Veld1, Veld2, Veld3, " & Me.cboKeuzeveld.Value & " FROM MijnTabel"

DoCmd.RunSQL strSQL

Als je de query niet gelijk wilt draaien als je een veld kiest, kun je ook een knop maken die de waarde van de keuzelijst uitleest, zoals in het voorbeeld. Je plakt dan de code achter de knop, en niet achter de keuzelijst.

Om het mooier te maken, kun je de keuzelijst automatisch laten vullen met de aanwezige velden in de tabel. Daarvoor kun je de volgende code gebruiken, die je achter de formuliereigenschap <Bij Laden> kunt zetten.

Code:
Dim rstTemp As New ADODB.Recordset
Dim fldTemp As ADODB.Field
Dim sVelden As String

    rstTemp.ActiveConnection = CurrentProject.Connection
    rstTemp.Open "SELECT * FROM MijnTabel", , adOpenKeyset, adLockOptimistic
    For Each fldTemp In rstTemp.Fields
        If sVelden <> "" Then sVelden = sVelden & ";"
        sVelden = sVelden & fldTemp.Name
    Next fldTemp
    Me.KeuzeLijst.RowSourceType = "Value List"
    Me.KeuzeLijst.RowSource = sVelden

rstTemp.Close
Set rstTemp = Nothing

Daarmee vul je de keuzelijst met alle beschikbare velden.

Michel
 
Nog een aanvulling:
Als je geen keuzelijst met invoervak gebruikt, maar een normale keuzelijst, kun je de query helemaal flexibel opbouwen. Dat doe je met de <Na Bijwerken> gebeurtenis op de keuzelijst.
De code daarvoor is de volgende:

Code:
Private Sub Keuzelijst_AfterUpdate()
Dim frm As Form, ctl As Control
Dim varItem As Variant
Dim strSQL As String
Dim i As Integer

    i = 0
    Set frm = Me.Form
    Set ctl = frm!KeuzeLijst
    strSQL = "Select "
    For Each varItem In ctl.ItemsSelected
        If i > 1 Then strSQL = strSQL & ", "
        strSQL = strSQL & ctl.ItemData(varItem)
        i = i + 1
    Next varItem

    'Trim the end of strSQL
    Trim (strSQL)
    If Right(strSQL, 1) = "," Then strSQL = Left(strSQL, Len(strSQL) - 1)

End Sub

Als je voor de End sub "msgbox strSQL" zet, kun je de opbouw van de code mooi volgen.
Bij elke nieuwe keuze die je maakt, wordt de sql uitgebreid.

Michel
 
Hallo Michel,

Dank je voor je snelle reactie zeg. Ik zal het een en ander gaan proberen. Ik ben zelf beter bekend in excel dan access. Maar ik wil het me wel eigen maken, Dus mogelijk duurt het even voor ik het door heb. Je moet ergens beginnen met leren.

Waarom is een keuzelijst zonder invoervak altijd makkelijker? Is die beter te benaderen omdat je dan enkel in de lijst hoeft te zoeken ipv naar een apart vakje die vanuit de lijst gevuld wordt?



Verder de term Me. die je gebruikt : waar staat dat voor? Je gebruikt hem bij Me.Form

Ik begrijp nog niet alles in access maar wil het wel leren begrijpen.


Hartelijke groet,

Bas
 
Je hebt mij (dacht ik) niet horen zeggen dat een normale keuzelijst makkelijker is; ik gebruik zelf meestal keuzelijsten met invoervak. Omdat je over het algemeen toch maar één waarde terug wilt lezen, althans, in mijn gevalletjes.

Het voordeel voor jou bij een normale keuzelijst is, dat je een flexibele query kunt maken, waarbij je elk veld kunt gebruiken wat in de lijst staat. Dus het maakt dan niet uit of je één veld, of 10 velden selecteert. Daar zou je dus wat mee kunnen.
Wil je altijd maar één flexibel veld gebruiken, dan is een keuzelijst met invoervak beter, want dan leg je alle velden dus vast in de VBA code achter de keuzelijst, en voeg je alleen de gekozen waarde uit de keuzelijst aan de query toe.

Kortom: wat jij wilt! Ik heb beide varianten uitgeprobeerd, en ze werken prima! Goede kans dat ik de keuzelijst zelf wat vaker ga gebruiken, want ik vind 'm wel :cool:

Michel
 
Hoi Michel,

Van je eertse tip heb ik dit gemaakt en dat werkt perfect. Ik ga nu beginnen aan de mooi maak tips! Als ik tegen problemen aanloop dan post ik gewoon een vraag aan je.


Private Sub KeuzeLijst_AfterUpdate()

Dim default, Criteria, StrSQL

Dim Leden, Keuze, Criteria


Keuze = Me.KeuzeLijst.Value

‘Ter controle of het werkte



'DoCmd.RunSQL "CREATE TABLE TabelKeuzeLijst ([LidNummer]Text,[Keuze]Text)"

‘Deze gebruik ik alleen de eerste keer



Message = "de gemaakte keuze is: " & Keuze & Chr(10) & Chr(10) & _

"aan welke criteria moet de keuze voldoen?"



default = ""



Criteria = InputBox(Message, Title, default)

If Criteria = "" Then

Exit Sub

End If



‘met voorgaande kun je een criterium aan je keuze hangen. Stel je voor je keuze is betalend lid dan kun je bij criterium ja of nee invullen. Dan heb je gelijk een selectie op betalende en niet betalende leden. Allerlei ander criteria zijn ook mogelijk.

'verwijderen laatste keuze van vorige analyse

DoCmd.RunSQL "DELETE * From TabelKeuzeLijst"

'invoegen criteria nieuwe analyse in TabelKeuzeLijst

DoCmd.RunSQL "INSERT INTO TabelKeuzeLijst (LidNummer, Keuze) SELECT LidNummer, " & Me.KeuzeLijst.Value & " FROM Leden WHERE [" & Keuze & "] ='" & Criteria & "'"


'controle wat je hebt gekozen

StrSQL = "SELECT LidNummer, " & Me.KeuzeLijst.Value & " FROM Leden"

MsgBox StrSQL

End Sub


De gemaakte tabel wordt aan een query gekoppeld.

Groeten,

Bas
 
Ziet er netjes uit, voor een eerste poging ;)

Ik zou nog uitleggen waar Me voor stond.... Eigenlijk simpel: je kunt in VBA objecten, eigenschappen etc. opvragen van het actieve element; vaak is dat je formulier. <Me> is daar de representant van, oftewel: met Me vraag je objecten op van het huidige actieve formulier of rapport.
Als je bij het opvragen van bijvoorbeeld een keuzelijst begint met <Me.>, kun je de formulierobjecten heel gemakkelijk uit een keuzelijst opzoeken, door de beginletters in te typen. Dat scheelt tijd, en voorkomt typfouten. Zonder ME. moet je de namen volledig typen, en je kunt dus een typfout maken, waardoor e.e.a. uiteraard niet werkt.

Als je een query hebt gemaak die als bron voor het formulier moet dienen, kun je dat heel snel doen met Me.Rowsource=strSQL. Ook verversen gaat snel: Me.Requery.

Kortom: ik gebruik Me best vaak in mijn code.

Ik zou overigens in jouw voorbeeld

Keuze & Chr(10) & Chr(10)

vervangen door

Keuze & VbLf & VbLf.

Wat je hebt is niet fout, maar VbLf is duidelijker te lezen. (en makkelijker typen...)

Michel
 
volgende vraag

He Michel,

Als ik jouw volgende stukje code in gaat voeren :

Dim Temp As New ADODB.Recordset dan krijg ik de volgende melding:

Een door de gebruiker gedefinieerd gegevenstype is niet gedefinieerd.



Toch staat via Extra --> Verwijzingen--> Microsoft DAO 3.6 Object Library aangevinkt. Wat zie ik over het hoofd. Of moet er nog iets met Connection bij?


Dat lijk je te doen verder op als met ActiveConnection=Current project te doen.

Bas
 
De code maakt gebruik van ADO, dus je moet controleren of je de ADO 2.8 bibliotheek hebt geladen.
Je kunt daarbij ADO en DAO wel allebei tegelijk laden, maar ik heb gemerkt dat procedures niet werken als je eerst DAO laadt, en daarna ADO.
Controleer dus ook of ADO 2.8 (of een oudere versie, maakt niet zoveel uit) boven DAO 3.6 staat. Zo niet, dan kun je hem met de verplaatstoetsen naar boven halen.

En dan nog een keer proberen...
Eventueel kun je DAO 3.6 ook tijdelijk uitschakelen, zodat je alleen ADO gebruikt.
De meeste Office specialisten schijnen zowiezo de voorkeur te geven aan ADO boven DAO; ik begin zelf ook steeds meer die kant op te gaan.

Michel
 
volgende stap

He michel,

Zit nu even lekker te testen. Nu krijg ik de melding dat de instelling voor deze eigenschap te lang is.

Me.KeuzeLijst.RowSource = sVelden

Hier loopt het op vast.

Heeft dat te maken met het feit dat als je handmatig de velden invoert er een maximum van 20 mogelijk bij een keuzelijst zonder invoervak.
Of heeft dat te maken met de verschillende eigenschappen die de velden hebben in de tabel waarin gezocht wordt? Text en nummeriek, datum/ tijd en ja/nee?

Eentueel iets van sVelden is max invoeren??
 
Kun je de inhoud van sVelden hier posten? die kun je met een Inputbox opvragen: sVelden=Inputbox("","",sVelden)

Michel
 
Wellicht is er een speciale reden om op deze manier een lijst van velden te maken.
Maar de meest voor de hand liggende methode is:
Row Source Type : Field List
Row Source: naam van tabel of query
 
antwoord

He Michel,

Id;Invoerdatum;InvoerNaam;Gestopt;DatumEinde;AndereGroep;Voorbeeldnummer1;VerenigingsCode;VerenigingsCodeOud;VerenigingsCodeOud1;VerenigingsCodeOud2;VerenigingsCodeOud3;Voornamen;Voorletters;Voornaam;VoornaamVrouwMan;Tussenvoegsel;Achternaam;Adres;PC;Plaats;telefoonnummer;2eTelefoon;MobielNummer;FaxNummer;EmailNummer;1Woonplaats;Provincie;Geboorteplaats;Geboortedatum;Geslacht;Opleiding;

Op het moment dat ik op de vraag van de Inputbox op OK druk dan krijg op de de 21e keuzemogelijkheid Pla

Dus het woord plaats wordt ergens afgebroken. Het zijn de veldnamen uit onze tabel Leden waarin we de informatie van onze verenigingsleden in hebben zitten.

Het lijkt of er een maximaal aan karakters inzit.

gr Bas
 
Proefondervindelijk ben ik er achter gekomen dat een keuzelijst met invoervak een aantal beperkingen kent:
1. het aantal velden mag niet groter zijn dan 71
2. de veldlengte per item mag niet groter zijn dan 50
3. de totale lengte van de string voor de RowSource moet kleiner zijn dan 2050 tekens.

Vraag me niet hoe ik dat weet :D

De Inputbox heeft een maximum lengte die daar ver onder ligt (255 tekens), dus dat zegt op zich niet zo veel. Je kunt wel controleren met Len(sVelden) of je binnen de 2050 karakters blijft. Met tmp=Split(sVelden;";") kun je checken hoeveel items je hebt. je moet dan wel tmp als matrix definieren met Dim tmp().
Daarna kun je met msgbox UBound(tmp) controleren hoeveel items je hebt. Is dat in orde, dan kun je nog de lengte van de verschillende velden checken met een loopje op de matrix tmp die je eerder hebt gemaakt. Die loop kun je denk ik zelf wel bedenken?

Heb je ook al geprobeerd om met <Field List> als basis te werken?

Michel
 
keuzelijst zonder invoervak

Nu ben ik in mijn formulier verdergegaan met een keuzelijst zonder invoer vak.
Gelden daar dezelfde grenzen voor?


Ik meende namelijk gezien te moeten hebben dat Access aangaf hier maar een maximum van 20 velden in te accepteren. Dan zijn we met 71 al een mooi stukkie verder.

Gelden daar dezelfde grenzen voor?

Nee, ik heb nog niet met Field List gewerkt. Ik ga dat morgen of overmorgen eens proberen. Kijken wat het me oplevert.

gr

BB
 
Ik heb het nog niet geprobeerd met een normale keuzelijst; je zou het uiteraard gewoon eens kunnen proberen, je ziet gauw genoeg of het werkt of niet.
Ik vermoed, dat de optie Field list dezelfde beperkingen zal hebben als ik eerder aangaf, omdat de beperking wel in de keuzelijst zal zitten.

Gewoon proberen dus, en zien wat het oplevert!
Mocht je qua veldlengte en/of totale stringlengte niet uitkomen, dan heb ik nog wel een routine voor je die daar wat aan doet.

Michel
 
De titels van de basis tabel zijn soms onlogisch of worden niet gebruikt om op te selecteren of het nutteloos om daarop te selecteren. Ik heb een tussen query gemaakt die daarin de titles selecteert die wel relevant zijn. Dan overschrijt de selectie de 2050 karakters ook niet meer en kun je naar wens in de tussenquery de vulling van je keuzelijst aanpassen door in de query anders te vullen.

Gr

Bas
 
Foutmelding

Hallo

Ik heb de volgende code achter het update veld gezet van de knop in het properties scherm

strSQL="SELECT KRI, " & Me.cboKeuzeveld.Value & "FROM KRI_2"
DOCmd.RunSQL strSQL

Ik krijg de foutmelding "Microsoft Access can not find the object 'strSQL="SELECT KRI, " & Me.'"

Kan iemand mij helpen? Wat doe ik fout?
 
Je mist een spatie:
Code:
strSQL="SELECT KRI, " & Me.cboKeuzeveld.Value & " FROM KRI_2"
Zonder spatie plak je de keuzelijstwaarde en het woord FROM aan elkaar.
Overigens is dit a) een heel oude draad, b) dit een opgeloste vraag en c) niet jouw vraag. Maak de volgende keer dus een eigen vraag aan!
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan