Hallo!
Ein Formular hat als Record Source eine Tabelle. Mehrere Datensaetze. Daten unveraendert.
Im folgenden Code wird bei jedem 1. Aufruf der obere Zweig mit Fehler "No current Record" durchlaufen.
Bei jedem 2. Aufruf wird der untere Zweig ohne Fehler durchlaufen.
oRst ist jeweils nicht Nothing.
Das Verhalten wurde mit Datensatz 1 und Datensatz 2 geprueft.
Warum wechselt das Verhalten?
Wie kann man das umgehen?
Gruss
Stele
Set oRst = oMe.RecordsetClone
With oRst
If Not .BOF Then
.MovePrevious
lIdNxt = oRst(cIdFld)
ElseIf Not .EOF Then
.MoveNext
lIdNxt = oRst(cIdFld)
End If
End With
Hallo Stele,
das ist genau das Verhalten, was du programmiert hast. Sicherlich ist das jetzt nicht die Antwort, welche du erwartet hast, deshalb zur besseren Verdeutlichung hier die Auflösung und schau dir mal die Wahrheitstabelle an, wann BOF welchen Wert annimmt:
https://learn.microsoft.com/de-de/office/client-developer/access/desktop-database-reference/recordset-bof-property-dao (https://learn.microsoft.com/de-de/office/client-developer/access/desktop-database-reference/recordset-bof-property-dao)
Im Übrigen ist hier ElseIf etwas falsch gewählt, es reicht ein einfaches if-then-else-endif, aber viel wichtiger ist eigentlich, was du mit so einer Programmierung erreichen möchtest, denn so ist das Ganze etwas sinnfrei.
Knobbi38
Hallo Knobbi!
Ein und derselbe Aufruf ergeben ein unterschiedliches Verhalten. Das kann ich noch nicht erklaeren. Ich meine, nach jedem Aufruf alles sauber geloescht zu haben.
Zum BOF und EOF hatte ich eine Verstaendnisproblem. Nach Klaerung konnte ich die Funktion herstellen.
Bzgl. Sinnfrei: Es soll ein Datensatz geloescht werden. Nach Requery soll der Datensatz davor (oder ggf. dahinter) ausgewaehlt sein.
Gruss und Dank
Stele
With oRst
If .BOF And .EOF Then
Debug.Print "keine Daten"
GoTo Ende
End If
.MovePrevious '1 Pos. hoch
If Not .BOF Then 'wenn Pos. nicht vor Anfang..
lIdNxt = oRst(cIdFld) 'ID dieser Pos. merken
Else '.. sonst war es der 1. Datensatz..
.MoveFirst 'zu Pos. 1
.MoveNext '1 Pos. runter
If Not .EOF Then 'wenn Pos. nicht hinter Ende..
lIdNxt = oRst(cIdFld) 'ID dieser Pos. merken
Else '.. sonst gibt es nur 1 Datensatz..
lIdNxt = -1 'Dummy-Wert
End If
End If
End With
Hallo Stele,
anstatt mit der Recordset-Position zu hantieren, bietet sich dafür die Methode .FindRecord und .NoMatch mit einem Kriterium größer/kleiner an, wobei ich zunächst auf den nächst "größeren" DS positionieren würde und im Fehlerfall dann den "kleineren" auswählen würde.
Tip:
.MoveFirst mit anschließendem .MoveNext könnte man auch einfach duruch .Move 2 ersetzen.
Knobbi38
Hallo Knobbi!
Wenn das Formular anders sortiert ist, als erwartet, suche ich evtl. nicht in der richtigen Spalte.
Aber der Tip ist cool.
Mit Eingangspruefung auf RecordCount>1 kann auch noch etwas gekuerzt werden.
Wenn du noch Spass dran hast:
Das Verhalten, das im Kommentar 1 beschrieben ist, macht fuer mich keinen Sinn.
Der Programm muesste, wenn der 1. Datensatz markiert ist, immer im oberen Zweig mit Fehler enden.
Wenn der 2. Datensatz markiert ist, muesste es immer ohne Fehler den oberen Zweig durchlaufen.
Beobachtet wurde aber, dass der obere und der untere Zweig abwechselnd durchlaufen wurden (je man. Aufruf entweder/oder).
Gruss
Stele
Das Recordset wird geklont, damit beim Moven nicht das Current-Ereignis ausgeloest wird.
Im Klon muss zuerst noch zum Datensatz, wie im Original gesprungen werden.
Vergib mir das Denglish!
ZitatIm Klon muss zuerst noch zum Datensatz, wie im Original gesprungen werden.
Da bietet sich die .Bookmark-Eigenschaft an
oRst.Bookmark = Me.Recordset.Bookmark
Hallo Stele,
wenn du RecordsetClone und Form-Recordset zunächst synchronisierst, kann niemals EOF oder BOF gesetzt sein, mal vorausgesetzt es gibt mindestens ein DS zum anzeigen.
BOF oder EOF werden nur durch Move-Methoden gesetzt, wenn dadurch vor oder nach dem ersten bzw. letzten DS im Recordset positioniert wird.
In deinem Fall wird also immer der erste IF Zweig ausgeführt, weil BOF durch das markieren des 1.DS niemals gesetzt sein kann; analog wird der 2. Zweig niemals ausgeführt, weil diese Bedingung mit EOF niemals wahr werden kann.
Wie gesagt, kannst du mit FindFirst und NoMatch viel einfacher positionieren und das vereinfacht vieles.
Gruß Knobbi38
Hallo!
Danke für die Antworten.
Die Website wurde zwischenzeitlich als nicht vertrauenswürdig eingestuft. Daher meine späte Reaktion.
Die BookMark-Variante habe ich übernommen.
@Knobbi:
Angenommen: 1 Tabelle mit 10 Spalten 100 Datensätzen. Sortierung unbekannt. Der Benutzer hat bspw. Datensatz 43 zum Löschen markiert. Nach dem Löschen soll der 'darüber liegende' Datensatz markiert sein.
Wie hilft hier FindFirst?
Gruß Stele
Im einfachsten Fall die aktuelle Sortierung ermitteln und dann den DS suchen, wo das Sortierkriterium > ist als das bei DS 43. Gibt es kein Sortierkriterium oder möchte man das nicht ermitteln, aktuellen Primarykey ermitteln, Recordset clonen, FindFirst auf den PrimaryKey und dann mit MoveNext zum nächsten DS positionieren. FindFirst könnte auch möglicherweise durch die Methode aus #6 ersetzt werden, je nachdem, was in der Situation besser passt.
Gruß Knobbi38