Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Auslosung für Tilnehmer (Turnierdatenbank) A2003

Begonnen von Optiplex, November 15, 2010, 09:24:53

⏪ vorheriges - nächstes ⏩

Optiplex

Hallo zusammen
ich schreibe gerade an einer Turnierdatenbank und habe nun alle Mitspieler in einer Tabelle. Nun möchte ich die Reihenfolge per Zufallsgenerator auslosen, wie macht man sowas,da ein Spieler ja nicht doppelt ausgelost werden darf. Die neue Reihenfolge möcht ich dann in ein Feld der gleichen Tabelle schreiben.

Gruß Dieter

DF6GL

Hallo,

ad hoc würde ich sagen, dass Du aus einer Abfrage, die alle DS liefert, die noch keinen "Reihenfolgewert" haben, per Schleife mit einer Zufall-Funktion einen DS ausliest, und diesem DS den Wert eines laufenden Zählers verpaßt.  Dann startest Du die Abfrage erneut und wiederholst das Spiel, bis die Abfrage keine DS mehr liefert.

Am Anfang aktualisiert Du zunächst alle Einträge im "Reihenfolgefeld" auf NULL oder halt 0, je nachdem, wie Du die Abfrage und Tabelle  gestaltest.

Optiplex

Hallo DF6GL,
Ok einen Zähler xxx erstellen der ins Reihenfolgefeld eingetragen wird, Und ,,Select * From Tabelle Where Reihenfolgefeld=0" ist auch OK. Aber wie erstelle ich die Zufalls Funktion die mir einen Datensatz auswählt?

Ich stehe da echt auf der Leitung.

Danke und Gruß Dieter

lumbumba

#3
evtl. hilft das:

Private Sub RandomSpielerliste()
   Dim SQL As String
   Dim vf As Variant, v As Variant
   Dim rs As DAO.Recordset
   SQL = "Select MSID, RT from Tabelle1;"  '<<----hier deinen eigenen SQL-String erstellen
   Set rs = CurrentDb.OpenRecordset(SQL)
   rs.MoveLast
   lRet = rs.RecordCount
   rs.MoveFirst
   vf = RandomLongArray(lRet)
   For Each v In vf
       rs.Edit
           rs("RT") = v       '<<---Anpassen
       rs.Update
       rs.MoveNext
   Next
   rs.Close
End Sub

Public Function RandomLongArray( _
   ByVal Max As Long, _
   Optional ByVal Min As Long = 1, _
   Optional ByVal Count As Long = 0 _
 ) As Variant

   ' ©2004 by Jost Schwider, http://vb-tec.de/

   
   Dim Range As Long
   Dim Longs() As Long
   Dim i As Long
   Dim j As Long
   Dim Item As Long
   
   
   Randomize Now()
   
   'Array initialisieren:
   ReDim Longs(Min To Max)
   For i = Min To Max
       Longs(i) = i
   Next i
   
   'Array mischen:
   Range = Max - Min + 1
   For i = Min To Max - 1
       j = Int(Rnd * Range) + i
       Item = Longs(j)
       Longs(j) = Longs(i)
       Longs(i) = Item
       Range = Range - 1
   Next i
   
   'Ergebnis zurückgeben:
   If Count > 0 Then
       ReDim Preserve Longs(Min To Min + Count - 1)
   End If
   RandomLongArray = Longs

End Function


Gruss
Daniel
---

oma

Hallo,

mache in der Tabelle Teilnehmer ein Zahlenfeld Nummer u. eine Abfrage qryTeilnehmer mit einem berechneten
Feld Zufall: ZZG(IstNull([ID_Teilhehmer])*0+1) u. sortiere absteigend nach diesem Feld

Mit einer kleinen Funktion in ein beliebiges Modul deiner DB wird eine laufende Nummer nach Zufall in Tabelle Teilnehmer eingetragen:


Public Function NR()
Dim db As Database, rs As Recordset
Dim I As Long

Set db = CurrentDb
Set rs = db.OpenRecordset("qryTeilnehmer ")

rs.MoveFirst
I = 1
Do While rs.EOF = False
       rs.Edit
       rs!Nummer = I
       rs.Update
I = I + 1
rs.MoveNext
Loop
End Function



Gruß Oma
nichts ist fertig!

Optiplex

Hallo Lumbumba oder besser Daniel,
also der Code hat auf Anhieb funktioniert, wie ich es mir vorgestellt habe. Ein paar Erklärungen wären allerdings noch von Vorteil. Für was sind die Optional Werte in der Funktion, ich habe das Gefühl mit der Funktion kann man viel mehr machen. Muss man einen erstellten Array nicht auch wieder freigeben(den Speicher bereinigen). Sorry für die dummen Fragen aber ich bin noch am lernen und sehr neugierig.

Hallo Oma, ich werde am Wochenende mal testen ob ich deinen Vorschlag der bestimmt funktioniert mal komplett in VBA umzusetzen. Es müsste eigentlich nicht so schwierig sein, ein Feld durchgehend mit deiner Formel zu berechnen danach zu sortieren und in einem zweiten Feld neu zu nummerieren. Allerdings sagt mir die ZZG Methode nichts, auch in der Access-Hilfe habe ich nichts darüber gefunden. Ich möchte das alles in der Spielertabelle machen, da mehrere Turniere gleichzeitig laufen und ich dadurch auch mehrere Spielertabellen habe erspare ich mir die Abfragen(was bei Daniels Vorschlag der Fall ist).

Gruß Dieter

lumbumba

#6
Hallo Dieter

Stimmt, die Erklärungen fehlen irgendwie.
RandomLongArray( ByVal Max As Long, Opt ByVal Min As Long = 1, Opt ByVal Count As Long = 0) as ...
Diese Funktion erzeugt eine Folge von ganzzahlen in einem Array welche durch die Angabe von Max und Min berenzt werden. Die Angabe Count gibt die Menge an die zurück gegeben werden soll.

Bsp 1: Lotto 6 aus 49
RandomLongArray( 49, , 6 )
Max = 49
Min = 1, brauch nicht angegeben werden da die OptionalVariable den wert Automatisch bekommt.
Count = 6
erzeugt ein Array( 1 to 6 ) in dem 6 zahlen vorkommen von 1 - 49

Bsp 2: 5 Zahlen aus einem Wertebereich 1000 - 9999
RandomLongArray( 9999, 1000 , 5 )
Erzeugt ein Array ( 1 to 5 ) mit Zahlen aus dem oben genannten Bereich.

Den Speicher des Arrays brauchst du nicht wieder freigeben, das sollte VBA für dich erledigen, da wir ja das Array mit den vba-eigenen Funktionen erzeugt haben.
Keine Panik, dumme Fragen gibt es nicht,  und neugierig und am lernen sind wir hier alle glaub ich, denn "nichts ist fertig" auch das eigene Wissen nicht. zudem ist ja ein Hilfeforum dazu da um Fragen zu beantworten, sonst könnten wir ja den laden hier dichtmachen und abschließen.

Die ZZG Methode sagte mir jetzt auch nix, aber wenn du z.B. beim Query erstellen in die SQL-Ansicht wechselst wirst du sehen das ZZG der VB-Befehl RND ist, der auch in der RandomLongArray Funktion verwendet wird.


Abschließend ist zu sagen das beide Methoden ( von Oma und die von mir genannte ) praktisch die gleiche Arbeitsweise haben, 1. Erzeuge ein gemischtes Array ( denn im weitesten Sinne ist eine Abfrage auch ein Array ) und erzeuge dann in einer tabelle eine rangfolge.   
---

oma

#7
Hallo,

wenn Daniels Beispiel klappt, ist ja alles in Ordnung.

Jo, ZZG ist Rnd

und natürlich ginge das auch ohne die Abfrage vorneweg:

Public Function Nr()
Dim db As Database, rs As Recordset
Dim I As Long
Randomize

Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT Nummer, ID, Rnd([ID_Teilnehmer]) AS Zufall  FROM tblTeilnehmer ORDER BY Rnd([ID_Teilnehmer])")

rs.MoveFirst
I = 1
Do While rs.EOF = False
      rs.Edit
      rs!Nummer = I
      rs.Update
I = I + 1
rs.MoveNext
Loop
End Function


Gruß Oma
nichts ist fertig!

Optiplex

Hallo zusammen

Danke Daniel für deine Erklärungen.

Oma, deine Version habe ich auch zum laufen gebracht ID und ID_Teilnemer hat mich anfangs etwas verwirrt. Funktioniert genauso wie die Version von Daniel. Was mir nur Aufgefallen ist, dass die beteiligten Felder danach indiziert sind. Ich habe eine Tabelle "tblTeilnehmer " mit den feldern ID - Autowert,Nummer - Zahl und habe die Zeile
"Set rs = db.OpenRecordset("SELECT Nummer, ID, Rnd([ID]) AS Zufall  FROM tblTeilnehmer ORDER BY Rnd([ID])")" so angepasst. Wie gesagt war dann das Feld Nummer nach den ersten Aufruf der Funktion plötzlich indiziert.Ist das Korrekt so oder habe ich was falsch gemacht?

Gruß Dieter

oma

Hallo Dieter,

warum das Feld nach der Funktionsaufruf indiziert sein soll, ist mit schleierhaft, denn mit dem Code hat das nix zu tun.


Mache doch einmal mit einer Test-DB in Tabelle tblTeilnehmer ein neues Feld Nummer; kontolliere das das Feld nicht indiziert ist u. führe dann die Funktion aus. Das Feld Nummer kann dann nicht plötzlich indiziert sein, da mit dem Code nur Werte ins Feld eingetragen werden!

Gruß Oma
nichts ist fertig!

Optiplex

Hallo Oma,
ich nehme alles zurück, das liegt nicht an deinem Code sondern irgendwie an der Datenbank. Habe gerade festgestellt dass des an der Feldbezeichnung liegt sobald ich Nummer eingebe wird dieses Feld indiziert. Normal ist das aber nicht oder?

Gruß Dieter

oma

Hallo Dieter,

nee, normal scheint das nicht zu sein.
Aber ist ja auch nicht weiter tragisch, wenn das Feld indiziert ist. Du kannst es ja händisch einfach zurück setzen

Gruß Oma
nichts ist fertig!

Optiplex

Hallo Oma,
das scheint von den Options zu kommen, Automatisch indizieren bei ID, Nummer usw.

Könntest du mir in der SELECT Anweisung den Bereich ,,Rnd([ID]) AS Zufall" erklären, was passiert da in Access. Denn scheinbar brauche ich kein Feld ,,Zufall" in der Tabelle.

oma

Hallo,

Nein, du brauchst natürlich kein Feld Zufall in der Tabelle!

Die Funktion Rnd gibt einen Wert vom Typ Single zurück, der eine Zufallszahl darstellt. (Siehe Access-Hilfe)

Mit "SELECT Nummer, ID, Rnd([ID_Teilnehmer]) AS Zufall  FROM tblTeilnehmer ORDER BY Rnd([ID_Teilnehmer"
wird im rs ein berechnetes Feld Zufall erzeugt, dass eine Zufallszahl beinhaltet.

Dann wird der rs nach dieser erzeugten Zufallszahl sortiert,  so das eine zufällige Reihenfolge der Teilnehmer entsteht.

Mit der nachfolgenden Do While- Schleife wird dann einfach in dieser zufälligen Reihenfolge der Reihe nach eine Zahl von 1 beginnend
in das Feld Nummer geschrieben.

Ich denke, dass ist eine recht einfache Art der zufälligen Numerierung im Sinne einer Auslosung.


Gruß Oma

nichts ist fertig!

Optiplex

Danke Oma für die Erklärung,
ich glaube jetzt sind alle Fragen geklärt und ich hoffe, dass ich dir, mit meinem Nachhaken nicht auf den Geist gegangen bin.

Großes Lob an euch, ihr habt mir hier zwei unterschiedliche und perfekte Lösungen angeboten.

Nochmals Danke und Gruß Dieter