[VBA] Functie in functie niet mogelijk??

Pagina: 1
Acties:

  • Masch
  • Registratie: Augustus 2002
  • Laatst online: 20-08 16:21
Mensen,

Ik zit met het onderstaande dillema waar ik al een aantal dagen mee aan het prutsen ben hier op het werk. Je ziet in onderstaande codes drie functies, die allemaal werken. Als ik echter de functie findklant() gebruik in findcontact(), dus een functie in een functie, dan krijg ik de onderstaande foutmelding;
Fout 3020 tijdens uitvoering:

Update or CancelUpdate without .AddNew or .Edit
Dit is zeer onlogisch, omdat de code helemaal niet langs een .edit en .addnew langs komt. Dit weet ik zeker, omdat ik het allemaal netjes stap voor stap heb doorlopen. De functie findklant geeft ook de juiste waarde mee, maar nadat de functie is afgerond, dan krijg ik dus de foutmelding.

Is het op de een of andere manier in vba soms niet mogelijk om een functie in een functie te gebruiken oid?? :?

Hieronder mijn code

code:
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
59
60
61
62
63
64
65
66
Public Function importoffertes()
' hier zit veel niet relevante code
newrst.AddNew
            newrst!Offertenummer = !Offertenummer
            newrst!Nummer = !Offertenummer
            newrst!Klantnummer = FindKlant(!Klantcode) <---- Dit gaat goed
            newrst!CID = FindContact(!Klantcode)
'etc niet relevante code en later ook een .update
end function       


Public Function FindKlant(code As String) As Long
    '1 --> Klant aanwezig in huidige database ?(zoek en vind code)
    strSQL = "SELECT * " & _
             "FROM [klant NAW] "
    Set newklantrst = newdb.OpenRecordset(strSQL)
    With newklantrst
        .FindFirst "klantcode  = '" & code & "'"
        If .NoMatch = False Then
            '1 --> Klant aanwezig in huidige database
            FindKlant = !Klantnummer
        Else
            '2 --> Klant overhalen uit oudere database
            strSQL = "SELECT * " & _
                     "FROM [Klant NAW] "
            Set oldklantrst = olddb.OpenRecordset(strSQL)
            oldklantrst.FindFirst "klantcode  = '" & code & "'"
            .AddNew
            !Klantnummer = lngKlt_nummer + 1
            !Klantcode = oldklantrst!Klantcode
                       'Hier zitten nog veel meer velden die gevuld worden
            lngKlt_nummer = lngKlt_nummer + 1
            .update
            FindKlant = !Klantnummer
        End If
    End With
End Function


Public Function FindContact(code As String) As Long

    '1 --> Vind contactpersoon zoals ingevuld in oude database
    strSQL = "SELECT klantcode, contactpersoon, telnr, faxnr " & _
             "FROM [Klant NAW] " & _
             "WHERE klantcode = '" & code & "'"
    Set oldklantrst = olddb.OpenRecordset(strSQL)
    
    If IsNull(oldklantrst!Contactpersoon) = True Then
        ContactNaam = "DUMMY"
    Else
        ContactNaam = oldklantrst!Contactpersoon
    End If
    
    If ContactNaam = "DUMMY" Then
        strSQL = "SELECT * " & _
                 "FROM Contactpersonen "
        Set newklantrst = newdb.OpenRecordset(strSQL)
        With newklantrst
            .AddNew
            !Naam = "Dummy Contactpersoon"
            !Klantnummer = FindKlant(code)    <--------- Dit gaat dus fout
            .Update
            FindContact = !CID
        End With

'etc code indien andere voorwaarden


edit:

Als ik in de foutopsporing het volgende commando geef;

debug.Print Findklant(code)

Dan geeft hij wel netjes de juiste klantcode |:(

[ Voor 23% gewijzigd door Masch op 14-11-2003 09:21 . Reden: code ff afgemaakt + toevoeging ]

(\__/) Ik wist totaal niet wat hier neer te zetten....
(='.'=) Dus het werd....
("")("") Een konijn!!


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
Masch schreef op 14 november 2003 @ 09:02:
Dit is zeer onlogisch, omdat de code helemaal niet langs een .edit en .addnew langs komt.
De foutmelding is ook : Je doet een .Update terwijl er geen .Edit or .AddNew was aangeroepen. Deze fout is simpel te achterhalen door een breakpoint te zetten en door je code te steppen.
Is het op de een of andere manier in vba soms niet mogelijk om een functie in een functie te gebruiken oid?? :?
Als we geen subs / functies konden aanroepen vanuit subd / functies zouden we weer terug zijn bij de goto en gosub van 15 jaar geleden. :)
Nee dus, het is niet niet mogelijk om functies vanuit functies aan te roepen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Masch
  • Registratie: Augustus 2002
  • Laatst online: 20-08 16:21
farlane schreef op 14 november 2003 @ 09:28:
[...]

De foutmelding is ook : Je doet een .Update terwijl er geen .Edit or .AddNew was aangeroepen. Deze fout is simpel te achterhalen door een breakpoint te zetten en door je code te steppen.
Dit heb ik ook gedaan, maar hij komt dus niet langs een .update.
Als we geen subs / functies konden aanroepen vanuit subd / functies zouden we weer terug zijn bij de goto en gosub van 15 jaar geleden. :)
Nee dus, het is niet niet mogelijk om functies vanuit functies aan te roepen.
:? :? Dit snap ik dus niet helemaal. Ik ben geen fulltime programmeur, maar een sysadmin die soms ook nog eens wat code maakt, voor zijn lieve gebruikertjes ;)
Volgens mij bedoel je het cynisch, maar ik wist dat dus niet. * shame on me

(\__/) Ik wist totaal niet wat hier neer te zetten....
(='.'=) Dus het werd....
("")("") Een konijn!!


  • Masch
  • Registratie: Augustus 2002
  • Laatst online: 20-08 16:21
Okay, eindelijk opgelost. Het probleem was dat ik de 2 recordsets in de functies (newklantrst) hetzelfde genoemt had. Dit is een zeer domme fout, omdat hij dus na het aanroepen van de functie een .update wilde uitvoeren op de recordset die in de vorige functie gebruikt werd. Nadat ik dus de gebruikte recordset in de functie findcontact heb veranderd werkte het wel!

Let wel hier ben ik dus ong. 16 uur zoet mee geweest....... aargh |:( |:(

Dus in het vervolg er niet altijd uitgaan dat de code klopt, maar heel basic alles nakijken.

(\__/) Ik wist totaal niet wat hier neer te zetten....
(='.'=) Dus het werd....
("")("") Een konijn!!


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
Masch schreef op 14 november 2003 @ 09:37:
Volgens mij bedoel je het cynisch, maar ik wist dat dus niet. * shame on me
Een beetje wel jah ... :)

Overigens, de fout die optrad is een gevolg van het feit dat je je recordsets globaal ( of iig globaal in de unit ) hebt gedeclareerd, en niet meegeeft als parameter oid.

Dus een geod idee zou zijn om die functies als parameter ook een recordset mee te geven waarmee ze mogen werken.
Een andere oplossing is om de recordsets niet globaal te maken, maar lokaal in de functie.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Masch
  • Registratie: Augustus 2002
  • Laatst online: 20-08 16:21
farlane schreef op 14 november 2003 @ 11:36:
[...]
Een beetje wel jah ... :)
Iedereen begint ergens hé.
Overigens, de fout die optrad is een gevolg van het feit dat je je recordsets globaal ( of iig globaal in de unit ) hebt gedeclareerd, en niet meegeeft als parameter oid.
Ik heb ze idd globaal gedeclareerd, zodat je ze in alle functies kunt gebruiken. Dat is toch ook zo hé?
Dus een geod idee zou zijn om die functies als parameter ook een recordset mee te geven waarmee ze mogen werken.
Een andere oplossing is om de recordsets niet globaal te maken, maar lokaal in de functie.
Ik krijg het niet helemaal mee. Je bedoelt een functie met zoiets als;

code:
1
function bla(rstbla as recordset)

?
Wat is hier dan het voordeel van? Dan kun je toch nog steeds dezelfde recordsets per ongeluk gebruiken? correct me if i am wrong (vast wel ;) )

(\__/) Ik wist totaal niet wat hier neer te zetten....
(='.'=) Dus het werd....
("")("") Een konijn!!


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Als je een variabele globaal declareert moet je:
[list=1]
• heel zeker weten dat het niet anders kan;
• heel zeker weten dat je dat wel wil;
• heel zeker weten dat de variabele altijd geinitialiseerd is wanneer je hem gebruikt;
• heel zeker weten dat het niet anders kan.


:)

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:47
Je hebt een aantal mogelijkheden :

1 - Dat data in de recordset hoef je alleen te weten in 1 functie.
2 - De data in de recordset moet beschikbaar zijn in een aantal andere functies.
3 - De data in de recordset moet beschikbaar zijn in een groot aantal andere functies.

In het eerste geval declareer je je recordset lokaal in de functie :
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
Public Function DoSomething() as Boolean

    Dim r as Recordset 
    Set r = new Recordset

    ..... Do something with r here ......

    Call r.Close
    Set r = Nothing

End Function


In het 2e geval neem je idd die recordset als parameter mee in de functie
Visual Basic:
1
2
3
4
5
Public Function DoSomething( r as Recordset ) as Boolean

    ..... Do something with r here ......

End Function


De functie van waaruit je deze aanroept ziet er uit als functie 1

In het derde geval zou er een mogelijkheid zijn om de recordset globaal te maken, maar dan nog is het een goed idee om een getter en setter te maken, waarin je eventueel extra controles kunt doen.

Het voordeel van dit alles is :
A - Je kunt je functie hergebruiken, maar dan met een andere recordset.
B - Bij de aanroep kun je duidelijk zien welk recordset gebruikt wordt.
C - Overzichtelijkheid. Globale variabelen zorgen voor onduidelijke code.
D - Onderhoudbaarheid.
E ... INF - En nog ontelbaar meer voordelen .... :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Masch
  • Registratie: Augustus 2002
  • Laatst online: 20-08 16:21
Okay, zeer bedankt voor dit goede en duidelijke verhaal. Ik zal er in het vervolg zeker rekening mee gaan houden waar ik mijn variabelen (en recordsets) declareer.

(\__/) Ik wist totaal niet wat hier neer te zetten....
(='.'=) Dus het werd....
("")("") Een konijn!!

Pagina: 1