[Access VBA] keuzelijst vullen met recordset van objecten

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Ik ben benieuw of het mogelijk is om een keuzelijst te vullen (dynamisch natuurlijk) met de controls die voorkomen op een formulier, dmv een recordset.

Het is natuurlijk mogelijk om alle controls van een form na te lopen en daarmee een string op te bouwen en die vervolgens toe te wijzen aan de recordsource van het control (in "List of values"-mode), maar is het ook mogelijk om in het geheugen vanuit een functie die alle controls naloopt een recordset te maken die je vervolgens toewijst aan het control (maar dan in "table/query" mode)?

Waar ik vooral tegenaanloop en niet gevonden krijg is of het mogelijk is om vanuit dergelijke vba (versimpeld weergegeven)
code:
1
2
3
for each form.control
        code.name
next control

een recordset te produceren, dus een "tabel of query" in het geheugen. De enige manier die ik weet om een recordset te vullen is via currentdb.openrecordset(SQL) (in ieder geval alleen uit tabellen)

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ik denk niet dat dit kan, behalve met vba zoals je zelf al aangeeft. Maar waarom zou je dit willen? :? Je kan desnoods gewoon met vba een echte tabel vullen met de namen van alle controls op een formulier, waarom wil je juist een in-memory variant hebben?

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
pedorus schreef op woensdag 12 mei 2010 @ 11:04:
Ik denk niet dat dit kan, behalve met vba zoals je zelf al aangeeft. Maar waarom zou je dit willen? :? Je kan desnoods gewoon met vba een echte tabel vullen met de namen van alle controls op een formulier, waarom wil je juist een in-memory variant hebben?
Ja, maar daar gaat het net om, hoe vul je een recordset puur met VBA, zonder tussenkomst van tabellen of queries met records en SQL-aanroepen.

De reden dat ik dit wil is omdat dit het meest flexibel is (komt er een nieuwe control bij dan hoef ik daar niets voor te doen om die in de lijst te laten verschijnen, puur een algemene functie). Via VBA een string opbouw (waarde1;waarde2;etc) en in de rowsource invullen werkt ook, daar niet van, maar ik vraag me dus af of het mogelijk is om puur in het geheugen een recordset op te bouwen.
Een tabel moet je onderhouden (handmatig of automatisch (.addnew)), dat maakt het alleen maar ingewikkelder (maar het kan natuurlijk)

[ Voor 7% gewijzigd door Stefke op 12-05-2010 11:14 ]


Acties:
  • 0 Henk 'm!

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

In grote lijnen:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
Dim r as new recordset
Dim f as field
Set f=new field
f.name= "foo"
' vul hier de corrcte properties (name, type, lenght etc)
r.fields.append f

'te herhalen voor andere velden

ctrl.recordset=r


Waar je wel alert op meot zijn is het verschil tussen ADO en DAO recordsset, resp. oud en antiek. :p

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Lustucru schreef op woensdag 12 mei 2010 @ 11:18:
In grote lijnen:

Waar je wel alert op meot zijn is het verschil tussen ADO en DAO recordsset, resp. oud en antiek. :p
Oke, met jouw hulp en ook nog wat eigen zaken kwam ik tot het volgende

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Dim rst As New Recordset
Dim fld As Field
Set fld = New Field
fld.Name = "test"
fld.Type = dbText
fld.Size = 3

'Set rst = CurrentDb.Recordset
'Set rst = Workspace.OpenRecordset("test")

Dim t As Integer
rst.Fields.Append fld
t = 1

For t = 1 To 5
rst.AddNew
rst!fld = t
rst.Update
Next t
Debug.Print rst.RecordCount

Dit zou dan een recordset met 5 records moeten opleveren als testje, maar ik krijg een foutmelding op de eerste regel, nl. "ongeldig gebruik van sleutelwoord NEW"

als ik in plaats daarvan hetzelfde doe als voor het veld (set rst = new recordset) werkt t ook niet

[ Voor 7% gewijzigd door Stefke op 12-05-2010 11:41 ]


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Volgens Create In-Memory ADO Recordsets zou het wel moeten kunnen (zelf geen ervaring). Maar dan nog kun je niet "select * from VbaFunction()" doen bij mijn weten. Dus ik snap niet helemaal wat je er in dit geval mee op zou schieten.

Verder snap ik ook niet waarom je een lijstje met control-namen wil. Het lijkt wel alsof je een form-designer binnen access aan het maken bent, wat al een form-designer heeft. ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

stefijn schreef op woensdag 12 mei 2010 @ 11:38:
[...]
Dit zou dan een recordset met 5 records moeten opleveren als testje, maar ik krijg een foutmelding op de eerste regel, nl. "ongeldig gebruik van sleutelwoord NEW"

als ik in plaats daarvan hetzelfde doe als voor het veld (set rst = new recordset) werkt t ook niet
Default maak je een DAO recordset en die kan idd alleen op basis van query, table of sql stirng worden gemaakt. Je moet dus expliciet adodb.recordset opgeven als class.

Overigens is er een prachtfunctie te vinden om comboboxen te vullen met code, incl een null optie.

[ Voor 8% gewijzigd door Lustucru op 12-05-2010 11:50 ]

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Waar is die te vinden dan :) ?
pedorus schreef op woensdag 12 mei 2010 @ 11:44:
Volgens Create In-Memory ADO Recordsets zou het wel moeten kunnen (zelf geen ervaring). Maar dan nog kun je niet "select * from VbaFunction()" doen bij mijn weten. Dus ik snap niet helemaal wat je er in dit geval mee op zou schieten.

Verder snap ik ook niet waarom je een lijstje met control-namen wil. Het lijkt wel alsof je een form-designer binnen access aan het maken bent, wat al een form-designer heeft. ;)
Nee, ik wil een autorisatiesysteempje maken waarin de forms en de controls van de forms in een keuzelijst komen, zodat je daar een autorisatie aan kunt toewijzen. Ik snap dat er een usersysteem in Access zit en ik kan daar goed mee uit de voeten, maar in deze situatie wil ik dit. Met name omdat ik geen gebruik ga maken van de werkgroepfile om in te loggen maar van de computer inlognaam.
Als het op deze manier niet lukt doe ik het gewoon met een string die opgebouwd wordt en een "list of values"

[ Voor 6% gewijzigd door Stefke op 12-05-2010 11:52 ]


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Het is gelukt met:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Dim Rst As adodb.Recordset
Dim Fld As adodb.Field

Set Rst = New adodb.Recordset


Dim t As Integer
With Rst
    .Fields.Append "test", adVarChar, 3
    '.CursorType = adOpenKeyset
    '.CursorLocation = adUseClient
    .LockType = adLockPessimistic
    .Open
End With

t = 1

For t = 1 To 5
Rst.AddNew
Rst!test = t
Rst.Update
Next t
Debug.Print Rst.RecordCount
Set Forms!formulier1!Keuzelijst1.Recordset = Rst


bedankt voor de tips en links!

Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Volgende probleem; nu heb ik een recordset in mijn geheugen, maar hoe kan ik die sorteren?

Ik wijs hem uiteindelijk toe aan een keuzelijst door

set keuzelijst.recordset = rst

maar de sortering klopt niet. Volgens de help zou

rst.sort "veld asc"

moeten werken, maar ik krijg een melding "ongeldig gebruik an een eigenschap"

Iemand tips?

Acties:
  • 0 Henk 'm!

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

'=' teken FTW? 't is een eigenschap, geen methode.

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Wat bedoel je? K gebruik geen = bij rst.sort "veld asc"?

het toewijzen aan de eigenschap recordset van een keuzelijst werkt. Ik wil alleen de recordset eerst sorteren

[ Voor 14% gewijzigd door Stefke op 30-05-2010 16:02 ]


Acties:
  • 0 Henk 'm!

  • Marko_J
  • Registratie: Maart 2010
  • Laatst online: 15-03-2024
Hij bedoelt dat je er een is-teken aan toe moet voegen. Net als bij alle andere eigenschappen van de recordset. Dus;

rst.sort = "veld asc"

Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Marko_J schreef op zondag 30 mei 2010 @ 16:33:
Hij bedoelt dat je er een is-teken aan toe moet voegen. Net als bij alle andere eigenschappen van de recordset. Dus;

rst.sort = "veld asc"
Heb ik dacht ik al geprobeerd (en t staat niet in de help) maar ik zal nog es kijken

edit: doet t niet, nu de melding: "object vereist"

Acties:
  • 0 Henk 'm!

  • Marko_J
  • Registratie: Maart 2010
  • Laatst online: 15-03-2024
Waar in de code heb je die regel geplaatst? Kan je het hele stuk eens plakken?

Acties:
  • 0 Henk 'm!

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

stefijn schreef op zondag 30 mei 2010 @ 16:35:
Heb ik dacht ik al geprobeerd (en t staat niet in de help) maar ik zal nog es kijken
Dan heb je een andere helpfile :? :
' sort the recordset last name ascending
rstAuthors.Sort = "au_lname ASC, au_fname ASC"
Maar afgezien daarvan, zoals de melding aangeeft is het een eigenschap en die lees je uit, resp stel je in door ze een waarde te geven. Vergelijk het met het toewijzen van een waarde aan een variabele
Visual Basic:
1
2
3
4
]
rs.sort "veld" komt overeen met a 6 'geeft een error
of 
rs.sort = "veld" komt overeen met a=6
edit: doet t niet, nu de melding: "object vereist"
dan is je recordsetvariabele wrsch. (nog) niet ingesteld.

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
(Let op dat ik adodb recordsets gebruik dit geval)

Algemene functie die RST maakt
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Public Sub Create_RST_Ctls()

If Not DisableErrorhandling Then On Error GoTo Err_Handler

Dim Fld As ADODB.Field

Set RST_Ctls = New ADODB.Recordset

With RST_Ctls
    .Fields.Append "AutorisationID", adBigInt, 1, adFldIsNullable
    .Fields.Append "Ctl_Name", adVarChar, 25
    .Fields.Append "Ctl_ControlTipText", adVarChar, 50
    .Fields.Append "Ctl_Autorisation", adVarChar, 1
    
'    .CursorType = adOpenKeyset
    .CursorLocation = adUseClient
    .LockType = adLockPessimistic
    .Open
    
End With

Exit_Handler:
Exit Sub

Err_Handler:
    Call LogError(Err.Number, Err.Description, conMod & ".Create_RST")
    Resume Exit_Handler
End Sub


Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Private Sub Show_FrmControls()

'This module shows the autorisation-state for all controls that can be autorized on the selected form

If Not DisableErrorhandling Then On Error GoTo Err_Handler

Dim ctl As Control
Dim obj As AccessObject
Set dbs = Application.CurrentProject
Dim RST_Autorisation As Recordset
Dim STR_filter As String

Create_RST_Ctls


Set RST_Autorisation = CurrentDb.OpenRecordset("SELECT * FROM tbl_autorisation")

For Each obj In dbs.AllForms
    If obj.Name = Me!combo_forms.Column(1) Then
        If Not obj.Name = Me.Name Then
        
        'Debug.Print obj.Name
            DoCmd.OpenForm obj.Name, acDesign, , , acFormReadOnly, acHidden
        End If
        For Each ctl In Forms(obj.Name)
            'Select Case ctl.ControlType
            'Case acListBox, acComboBox, acTextBox, acOptionGroup, acCheckBox, acCommandButton, acToggleButton, acSubform
            Debug.Print ctl.Name
            
            If ctl.Tag Like "*Autorisation*" Then               'controls met een tag "Autorisation" worden opgenomen in de controlslijst
                RST_Ctls.AddNew
                
                ' de verschillende velden van de rst vullen met data (grote lap VBA)

                RST_Ctls.Update
                'Debug.Print ctl.Name
            End If
            'End Select
        Next ctl
        If Not obj.Name = Me.Name Then
            DoCmd.Close acForm, obj.Name
        End If
    End If
Next obj

Set Me!combo_controls.Recordset = RST_Ctls
Me!combo_controls = Null

Exit_Handler:
RST_Ctls.Close
RST_Autorisation.Close

Exit Sub

Err_Handler:
        Call LogError(Err.Number, Err.Description, conMod & ".Show_FrmControls")
        Resume Exit_Handler
End Sub

[ Voor 29% gewijzigd door Stefke op 30-05-2010 16:55 ]


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Ik wil dus de recordset RST_Ctls toegewezen in rgl 46, sorteren
46: Set Me!combo_controls.Recordset = RST_Ctls

Dus ik zou zeggen dat ik minimaal daarvóór die RST_Ctls moet kunnen sorteren, bijv. in rgl 45

Acties:
  • 0 Henk 'm!

  • Marko_J
  • Registratie: Maart 2010
  • Laatst online: 15-03-2024
Eerder regel 34

Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Oke, dat werkt met rst_ctls.sort = "CTl_Name ASC" :)

Maar ik begrijp t niet, waarom werkt t op die plek wel en net voor t toewijzen aan de keuzelijst niet?

Acties:
  • 0 Henk 'm!

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

Wat doet regel 47 voor iets raars?
Enne, ik zie nergens een rst.sort 8)7. Post dan eens de volledige code, incl. de regel die foutloopt, haal dat 'on error' eens weg (op zet diableerrorhandling op true) en kijk op welke regel hij exact vast loopt of zet een breakpoint en loop stap voor stap door je code heen.

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Acties:
  • 0 Henk 'm!

  • Marko_J
  • Registratie: Maart 2010
  • Laatst online: 15-03-2024
stefijn schreef op zondag 30 mei 2010 @ 17:04:
Maar ik begrijp t niet, waarom werkt t op die plek wel en net voor t toewijzen aan de keuzelijst niet?
Kan het niet met zekerheid zeggen, maar waarschijnlijk door regel 41, die docmd.close.

Wordt regel 25 t/m 39 vaak herhaald? Om het efficienter te maken kan je de .sort en .update daar wellicht uit halen.

[ Voor 6% gewijzigd door Marko_J op 30-05-2010 17:16 ]


Acties:
  • 0 Henk 'm!

  • Stefke
  • Registratie: December 2000
  • Laatst online: 12-09 14:58
Lustucru schreef op zondag 30 mei 2010 @ 17:08:
Wat doet regel 47 voor iets raars?
Enne, ik zie nergens een rst.sort 8)7. Post dan eens de volledige code, incl. de regel die foutloopt, haal dat 'on error' eens weg (op zet diableerrorhandling op true) en kijk op welke regel hij exact vast loopt of zet een breakpoint en loop stap voor stap door je code heen.
Regel 47 zorgt er voor dat als er een keuze is gemaakt in de keuzelijst deze gewist wordt, maar die is nu overbodig. Ik heb m net weggehaald, was ws. nog over van een oude situatie. Die if bij regel 41 ook, die is nu ook weg.

Die rst.sort heb ik er uit gehaald omdat ie daarop misgaat (dat heb ik al gedaan met breakpoint etc), ik had m op regel 45 staan (en daar ging ie dan ook mis).
Nu staat ie op regel 34 en nu werkt t wel.

edit: vreemd, nu doet 'RST_Ctls.Sort = "Ctl_name ASC" het ook op regel 45, dat had ik al geprobeerd en dat ging niet. Zeker een stiekeme typo gemaakt (deed t al voor ik regel 41 verwijderde)

Anyway, t werkt én mijn code is een beetje opgeschoond n.a.v. jullie opmerkingen :) tnx

[ Voor 21% gewijzigd door Stefke op 30-05-2010 17:25 ]

Pagina: 1