Access-o-Mania

Access-Forum (Deutsch/German) => Tabelle/Abfrage => Thema gestartet von: Michael Wulf am Juli 24, 2016, 19:23:38

Titel: Rangliste berechnen
Beitrag von: Michael Wulf am Juli 24, 2016, 19:23:38
Guten morgen zusammen,

ich habe nachstehendes Problem:

Ich erstelle eine Datenbank für eine Turnierverwaltung. Es gibt eine Tabelle "Turnier" in der die Teilnehmer und deren Ergebisse verwaltet werden. Hierunter sind u.a. die Felder  "Summe Runden" und "Rangber".

Über eine Abfrage werden bestimmte Klassen und Gruppen gefiltert. Die Abfrage heißt ABF_Urkunden. Ich möchte nun das Feld "Rangber" automatisch mit dem entsprechenden Rang füllen um Urkunden drucken zu können. Dazu habe ich nachstehende Funktion gefunden:


Public Function RangSetzen()

Dim db As Database
Dim rs As Recordset
Dim z As Long

    Set db = CurrentDb()
    Set rs = db.openrecordset("SELECT * FROM ABF_Urkunden ORDER BY [Summe Runden];", dbopendynaset)
   
    Do Until rs.EOF
        z = z + 1
        rs.Edit
            rs!Rangber = z
        rs.Update
        rs.MoveNext
    Loop
   
    rs.Close
    db.Close
   
End Function


Über eine Schaltfläche im Hauptformular wird die Berechnung durchgeführt um im Unterformular die neu berechnete Abfrage zu zeigen.

Dim a As Variant

    a = RangSetzen()
    MsgBox "VBA-Aktualisierung wurde durchgeführt!", 48
    Me.Requery



Beim Ausführen erhalte ich die nachstehende Fehlermeldung:

Laufzeitfehler 3061

Es wurden 4 Parameter erwartet, aber es wurden zuwenig Parameter übergeben.

Kann mir bitte jemand helfen ? Ich nutze Access 2010

Vielen Dank
Titel: Re: Rangliste berechnen
Beitrag von: ebs17 am Juli 24, 2016, 19:36:48
Die Fehlermeldung ist typisch für nicht verfügbare Felder und Tabellen/Abfragen sowie für nicht auflösbare Parameter (Formularbezüge?).
Wie lautet die vollständige SQL-Anweisung zu ABF_Urkunden?
Titel: Re: Rangliste berechnen
Beitrag von: Michael Wulf am Juli 25, 2016, 06:50:19
Danke dass Du dir das anschaust. Hier der Code für die Abfrage:

SELECT Turnier.Turniername, Turnier.Teilnehmer, Turnier.[Summe Runden], Turnier.[Summe X], Turnier.Klasse_Grob_FS, Turnier.Bogenklasse_FS, Turnier.Altersklasse_FS, Turnier.Rangber
FROM Turnier
WHERE (((Turnier.Turniername)=[Formulare]![Hauptmenü]![Auswahl_Turnier]) AND ((Turnier.Klasse_Grob_FS)=[Formulare]![FRM_Urkunden]![Kombinationsfeld1]) AND ((Turnier.Bogenklasse_FS)=[Formulare]![FRM_Urkunden]![Kombinationsfeld3]) AND ((Turnier.Altersklasse_FS)=[Formulare]![FRM_Urkunden]![Kombinationsfeld5]))
ORDER BY Turnier.[Summe Runden] DESC;


Kann es sein, das die Funktion nicht in eine Abfrage schreiben kann ?
Titel: Re: Rangliste berechnen
Beitrag von: ebs17 am Juli 25, 2016, 10:00:20
Du verwendest in Deiner Abfrage direkte Formularbezüge in der Filterung. Die sind schnell mal kritisch. Wenn Du die Abfrage in Access öffnest (Doppelklick im Navigationsbereich, OpenQuery u.a.), dann spielt Access mit und macht die Werte der Formularfelder verfügbar.
In Deiner Funktion wird die Abfrage jedoch direkt an die Jet-Engine übergeben (über das Recordset). Diese kennt keine Formulare und deren Objekte und kann so den Inhalt nicht auswerten. Da kommt dann eben die Nachfrage.
Siehe auch Ein Parameter wurde erwartet (http://www.donkarl.com?FAQ6.4)
Da gibt es auch Lösungsvorschläge (Eval, echte Parameterabfrage).

Eine weitere Möglichkeit wäre, unmittelbar die SQL-Anweisung der Abfrage einzusetzen und die Parameter dynamisch einzusetzen, wobei die Parameter sinnvollerweise als Argumente an die Funktion zu übergeben wären, etwa ...
Public Function RangSetzen(ByVal Arg1 As String, ...)
   Dim sSQL As String
   ' ...
   sSQL = "SELECT * FROM Turnier" & _
         " WHERE Turniername = '" & Arg1 & "' AND Klasse_Grob_FS = ..."
   Set rs = db.Openrecordset(sSQL, dbOpenDynaset)
   ' ...
End Function

Hier werden die Variablen/Argumente vor dem Zusammensetzen der SQL-Anweisung ausgewertet, so dass dann die SQL-Anweisung fertig an die Jet-Engine übergeben wird.

Alternativ könnte man auch an eine komplette Abfragelösung denken: Laufende Nummer/Summe in Abfragen (http://www.donkarl.com?FAQ3.11)
Titel: Re: Rangliste berechnen
Beitrag von: Michael Wulf am Juli 25, 2016, 12:00:17
Vielen Dank.

An die angesprochene Lösung habe ich auch schon gedacht.

Wie baue ich diese denn in die ABF_Urkunden ein ? Einfach hinten anfügen ?

SELECT Turnier.Turniername, Turnier.Teilnehmer, Turnier.[Summe Runden], Turnier.[Summe X], Turnier.Klasse_Grob_FS, Turnier.Bogenklasse_FS, Turnier.Altersklasse_FS, Turnier.Rangber
FROM Turnier
WHERE (((Turnier.Turniername)=[Formulare]![Hauptmenü]![Auswahl_Turnier]) AND ((Turnier.Klasse_Grob_FS)=[Formulare]![FRM_Urkunden]![Kombinationsfeld1]) AND ((Turnier.Bogenklasse_FS)=[Formulare]![FRM_Urkunden]![Kombinationsfeld3]) AND ((Turnier.Altersklasse_FS)=[Formulare]![FRM_Urkunden]![Kombinationsfeld5]))
ORDER BY Turnier.[Summe Runden] DESC;


und dann

LaufNummer: (Select Count (*) FROM [ABF_Urkunden] as Temp WHERE [Temp].[Summe Runden] < [ABF_Urkunden].[Summe Runden])+1

Wenn ich das mache kommt es zu einem Zirkelbezug

Danke Michael
Titel: Re: Rangliste berechnen
Beitrag von: MaggieMay am Juli 25, 2016, 12:39:05
Hi,

du musst dich im Sub-Select auf die Tabelle "Turnier" beziehen.

PS:
Diese Art der Rangermittlung ist deiner Prozedur schon deshalb vorzuziehen, weil dabei gleiche Ergebnisse und somit auch gleriche Plätze berücksichtigt werden.
Titel: Re: Rangliste berechnen
Beitrag von: Michael Wulf am Juli 25, 2016, 13:11:24
Habe den nachfolgenden Code eingeführt:

LaufNummer: (Select Count (*) FROM [Turnier] as Temp WHERE [Temp].[Summe Runden] > [Turnier].[Summe Runden])+1

Das führt zu dem im Anhang dargestellten Ergebnis. Ich möchte aber eine bei 1 beginnende steigende durchgehende Nummerierung.

Sorry, aber wir arbeiten uns ran  ;)

Danke Michael
Titel: Re: Rangliste berechnen
Beitrag von: MaggieMay am Juli 25, 2016, 13:24:04
Du musst natürlich auch die übrigen Kriterien mit hinzunehmen:
WHERE [Temp].[Summe Runden] > [Turnier].[Summe Runden] AND
Turnier.Turniername=Temp.Turniername AND Turnier.Klasse_Grob_FS=Temp.Klasse_Grob_FS AND Turnier.Bogenklasse_FS=Temp.Bogenklasse_FS AND Turnier.Altersklasse_FS=Temp.Altersklasse_FS
Titel: Re: Rangliste berechnen
Beitrag von: Michael Wulf am Juli 25, 2016, 16:06:05
Leider kann ich euch nicht umarmen. DANKE. Es funktioniert.

:) :-*