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
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.
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
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
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
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
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.
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
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
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
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
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
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.
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
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