Ich suche eine Lösung, wie ich in einem Endlosformular
(mit endlicher Anzahl von DS, z.B. 10) die Datensätze mittels "up"- und "down"-Buttons sortieren kann. Wenn ich auf den up-Button drücke, soll der Eintrag eine Zeile weiter hoch rutschen und beim Down-Button umgekehrt.
Ich dachte daran, ein Feld mit ganzen Zahlen zu vergeben und beim klicken vo Up, soll eine zahl weiter hoch zählen und bei dem DS, der gerade diese Zahl hat, soll eins weiter runter gezählt werden. Danach refresh.
Wär so eine Lösung gut?
Hat jemand ein funktionierendes Beispiel dafür? :-)
Carl
Hallo,
das sind verschiedene Sachen.
Sortierung ändern auf absteigend, aufsteigend, unsortiert macht man indem man die Datenherkunft des Endlosformulars ändert.
Was genau meinst du mit hoch rutschen? Dass die Reihenfolge geändert wird? Das könntest du machen indem du in deiner Datenherkunft ein Zahlenfeld für die Reihenfolge hast. Dann kannst du mittels Aktualisierungsabfrage den Reihenfolgenwert mit dem des vorherigen tauschen und die Datensatzherkunft des Formulares Aktualisieren:
Private Sub cmdUp_Click()
Dim PreviousID As Long
PreviousID = DLookup("IDWert", "deineTabelle", "Reihenfolge=" & Me.Reihenfolge - 1)
CurrentDb.Execute "Update deineTabelle set Reihenfolge = " & Me.Reihenfolge - 1 & " Where IDWert=" & Me.IDWert
CurrentDb.Execute "Update deineTabelle set Reihenfolge = Reihenfolge +1 Where IDWert=" & PreviousID
Me.Recordset.Requery
End Sub
Ich hab dir mal ein Beispiel gemacht.
Gruß Andreas
Hallo,
Um den DS als aktuellen zu behalten, wenn man's denn möchte, würde ich ID
auch in einer Variablen festhalten.
Private Sub cmdUp_Click()
Dim PreviousID As Long
Dim ActiveID As Long
ActiveID = Me.IDWert
PreviousID = DLookup("IDWert", "deineTabelle", "Reihenfolge=" & Me.Reihenfolge - 1)
CurrentDb.Execute "Update deineTabelle set Reihenfolge = " & Me.Reihenfolge - 1 & " Where IDWert=" & Me.IDWert
CurrentDb.Execute "Update deineTabelle set Reihenfolge = Reihenfolge +1 Where IDWert=" & PreviousID
Me.Recordset.Requery
Me.Recordset.FindFirst "IDWert = " & ActiveID
End Sub
gruss ekkehard
Hallo,
ja das mit dem FindFirst ist richtig, sollte man machen.
Bei meinem Code gibt es allerdings noch Probleme wenn man EOF oder BOF erreicht - und wenn die Reihenfolge nicht fortlaufend (mit/ohne Lücken egal) ist.
Daher hab ich nochmals daran etwas gearbeitet und auch hoffentlich eine für dich lesbare Lösung erstellt.
Anstatt sich darauf zu verlassen dass man einfach das Reihenfolgendfeld +/- ändert, ermittel ich jetzt den Reihenfolgenwert des vorherigen/nächsten Datensatzes und werte ihn aus. Gleichzeitig werden noch Lücken mit der Zeit automatisch geschlossen.
Hier mein Code und Beispiel nochmal:
Dim prevnextID As Long
Dim secondID As Long
Dim currentID As Long
Dim prevnextReihenfolge As Long
Private Sub cmdDown_Click()
currentID = Me.IDWert
prevnextRecord Me.IDWert
If prevnextID = 0 Then Exit Sub 'Dateianfang/-ende erreicht
'Lücken in Reihenfolge füllen
If prevnextReihenfolge > Me.Reihenfolge + 1 Then
prevnextReihenfolge = Me.Reihenfolge + 1
secondID = Me.Reihenfolge
Else
secondID = Me.Reihenfolge - 1
End If
CurrentDb.Execute "Update deineTabelle set Reihenfolge = " & prevnextReihenfolge & " Where IDWert=" & Me.IDWert
CurrentDb.Execute "Update deineTabelle set Reihenfolge = " & secondID & " Where IDWert=" & prevnextID
Me.Recordset.Requery
Me.Recordset.FindFirst "IDWert = " & currentID
End Sub
Private Sub cmdUp_Click()
currentID = Me.IDWert
prevnextRecord Me.IDWert, "up"
If prevnextID = 0 Then Exit Sub 'Dateianfang/-ende erreicht
'Lücken in Reihenfolge füllen
If prevnextReihenfolge < Me.Reihenfolge - 1 Then
prevnextReihenfolge = Me.Reihenfolge - 1
secondID = Me.Reihenfolge
Else
secondID = Me.Reihenfolge + 1
End If
CurrentDb.Execute "Update deineTabelle set Reihenfolge = " & prevnextReihenfolge & " Where IDWert=" & Me.IDWert
CurrentDb.Execute "Update deineTabelle set Reihenfolge = " & secondID & " Where IDWert=" & prevnextID
Me.Recordset.Requery
Me.Recordset.FindFirst "IDWert = " & currentID
End Sub
Private Sub prevnextRecord(ByVal vIDWert As Long, Optional direction As String = "down")
With CurrentDb.OpenRecordset("Select * From deineTabelle Order By Reihenfolge", dbOpenSnapshot)
Do While Not .EOF
If .Fields("IDWert") = vIDWert Then
If direction = "up" And Not .BOF Then
.MovePrevious
ElseIf direction = "down" And Not .EOF Then
.MoveNext
End If
If Not .EOF And Not .BOF Then
prevnextID = .Fields("IDWert")
prevnextReihenfolge = .Fields("Reihenfolge")
End If
Exit Do
End If
.MoveNext
Loop
End With
End Sub
Gruß Andreas
Vielen Dank für die Lösungen. bei der zweiten Lösung vergibt er allerdings Werte mehrfach.
Außerdem entfernen sich Werte mehr als eine sich die Differenz mehr als einen Zähler.
Hallo,
kann eigentlich nicht sein.
Außerdem spielt das für die Reihenfolge ja keine Rolle ob Werte fehlen oder neg. sind oder doppelt vorkommen.
Die Spalte Reihenfolge blendet man ja später aus.
Aber dass Werte doppelt gesetzt werden kann eigentlich nicht sein.
Gruß Andreas
Zitatein funktionierendes Beispiel
... korreliert mit einer konkreten Datenbasis (gedacht, real).
Wenn man die verwendete Tabelle zusätzlich filtert - eigene Individualfilterung, Filterung aus HFo/UFo-Verknüpfung - muss man bei Verschiebung der Reihenfolge um 1 sicher noch einmal neu nachdenken.
Zitat von: Hondo am Dezember 30, 2019, 10:45:01
Außerdem spielt das für die Reihenfolge ja keine Rolle ob Werte fehlen oder neg. sind oder doppelt vorkommen.
Die Spalte Reihenfolge blendet man ja später aus.
Gruß Andreas
Doch, weil man dann eine Schaltfläche z.B. mehrfach klicken muss, um nach oben oder unten zu bewegen.
Carl
Hallo Eberhard,
ja das ist klar. Dann müsste man die Reihenfolge leeren und neu fortlaufend mit der aktuellen Filterung schreiben.
Carl, das verstehe ich gar nicht. Klicke ich auf einen Button runter wechselt der Datensatz nach unten und der darunter liegende rutscht hoch. Da muss man nicht 2x klicken!
Hallo Andreas,
ZitatDa muss man nicht 2x klicken!
Doch, wenn man mit Offset 1/-1 in der Lücke bleibt.
gruss ekkehard
Dadurch kann man keine automatische Kontrolle einrichten, ob eine Reihenfolge richtig gefunden wurde. Zum Beispiel bei einem Test.
Kann man die Zahlen in "Reihenfolge" nicht auf natürliche Zahlen zwischen 1-100 begrenzen?
Carl
Ich habe noch eine andere Idee. Mit welchem Code lassen sich die Datensätze der Reihe nach durchzählen (von 1-10) und diese Werte in das Feld Reihenfolge eintragen?
Carl
Gibt es noch eine andere Lösung, bei der immer nur die Zahlen 1-10 vorhanden sind, also nie z.b. "-1" oder Abstände mit mehr als einer Ganzzahl? Und auch keine Zahl doppelt.
Wenn der Anwender richtig sortiert hat, muss eine exakte Reihenfolge 1-10 vorliegen, damit man kontrollieren kann, ob das Ergebnis richtig ist.
Carl
Hallo,
ich frage mich, was Du Dir von der ganzen Geschichte überhaupt versprichst...
Und warum Dir das Beispiel von Andreas nicht gefällt....
Es gehört zu einem psychologischen Test auf logische Denkfähigkeit. Patienten sollen eine Bildergeschichte mit 10 Bildern in eine logisch stringente Reihenfolge bringen, um fest zu stellen, dass sie in Ursache-Wirkungs-Zusammenhängen denken können. (erst kauft man ein Eis, dann isst man es)
Das Beispiel von Andreas
* lässt durch die Schaltflächen zu, dass Zahlen mehrfach vergeben werden. (z.B. mehrfach die 1)
* dass andere Zahlen als 1-10 vergeben werden, z.B. -1
* und dass Abstände von mehr als einem Zähler entstehen, weshalb manchmal mehrfach auf die Schaltfläche eines Datensatzes gedrückt werden muss.
dadurch kann man nicht automatisiert ermitteln lassen, ob der Pat die logisch richtige Reihenfolge gefunden hat, die ja für jede Geschichte bekannt ist.
Ich denke, es wäre viel einfache, wenn die Datensätze beim Klicken der Schaltfläche ihre jeweiligen Werte "tauschen". Damit kommt man auch oben und unten nicht in Schwierigkeiten.
Carl
Ich habe es gelöst. Nach Beakers Beschreibung https://www.access-o-mania.de/forum/index.php?topic=16309.msg94489#msg94489
lasse ich ein weiteres Feld Position berechnen und mit den vorbekannten wahren Positionen in der Abfrage vergleichen. Damit kann ich ermitteln, ob ein Patient die richtige Reihenfolge ermittelt hat.
Danke für die Hilfe, an alle. :-)
Gesundes Neues!
Carl
Hallo,
anbei die erweiterte Version von Andreas.
Es wird auch das Löschen eines DS berücksichtigt
Vielen Dank, ich werde es mir gleich anschauen. :-)
Hallo Carl,
Da ging es aber um eine Neunummerierung nach dem Löschen eines DS, aber
wenn's geholfen hat ...
ZitatDamit kommt man auch oben und unten nicht in Schwierigkeiten.
Die würde ich von vorne herein ausschliessen
Private Sub Form_Current()
Me.cmdUp.Enabled = (Me.SortNr > 1)
Me.cmdDown.Enabled = Me.SortNr < Me.Recordset.RecordCount
End Subgruss ekkehard
Ich habe den Ursprungs-Code von drüben schon in mehreren Tabellen erfolgreich drin, alles funktioniert.
Aber mal eine andere Frage: Kann man auch die Werte in ID-Schlüsselfeldern editieren, aus einer 12 eine 23 machen? Bzw. ist davon abzuraten und wieso? Die DS werden im endlosUFO aufsteigend angezeigt und sollen ihre Position tauschen können.
Carl
Hallo,
Zitat...die Werte in ID-Schlüsselfeldern editieren, aus einer 12 eine 23 machen...
Solange es sich beim Schlüsselfeld nicht um einen Autowert handelt, ist das prinzipiell möglich.
Zitatist davon abzuraten und wieso?
Das sollte aber jetzt nicht mehr erklärt werden müssen...
wenn ein Schlüsselfeld-Wert geändert wird, wird auch die Bedeutung des DS verändert. Das ist so, als würdest Du Deinen Personalausweis einem Anderen zu dessen Weiterverwendung zur Verfügung stellen.
ZitatDie DS werden im endlosUFO aufsteigend angezeigt
Das ist nur eine Frage der Reihenfolgeeinstellung (Sortierung). Wenn keine Sortierung (Order By ...) explizit angegeben ist, wird halt das Schlüsselfeld zur Sortierung herangezogen.
Und bei einem Autowert geht es nicht? Geht es prinzipiell nicht oder ist es nur nicht praktikabel? Könnte man beispielsweise das Schlüsselfeld völlig entfernen, umsortieren und neu indizieren? Oder ein anderes Feld mit dessen bereits vorhandenen Werten zum Schlüsselfeld machen?
Carl
Hallo,
ZitatUnd bei einem Autowert geht es nicht?
Hab ich gerade schon beantwortet. Ein Autowert ist per Definition
automatisch und eindeutig erzeugt und lässt demzufolge keine manuelle Änderung zu. (Ein Autowert ist zwar per SQL trotzdem manipulierbar, hat aber bei unbedachter Anwendung eine Zerstörung der Db-Integrität zur Folge, was soviel Ärger erzeugt, so dass sich solche Vorgehensweise nicht "lohnt")).
Du redest immer von "Schlüsselfeld". Schlüsselfelder sind dazu da, DS , bzw. die ganze Tabellenstruktur zusammen genau zu definieren und nicht zu manipulieren.
Wie Sortierung ohne "Schlüsselfelder" (was nicht heißt, dass die Felder eindeutig indiziert sein können) geht, siehst Du an den Beispielen.
Ich verstehe nicht, warum Du Dich an dieser Stelle so verhakst.