Neuigkeiten:

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

Mobiles Hauptmenü

BOF und EOF

Begonnen von Stele4, September 18, 2025, 11:37:22

⏪ vorheriges - nächstes ⏩

Stele4

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

Knobbi38

#1
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

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

Stele4

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

Knobbi38

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



Stele4

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

Stele4

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!

Beaker s.a.

ZitatIm Klon muss zuerst noch zum Datensatz, wie im Original gesprungen werden.
Da bietet sich die .Bookmark-Eigenschaft an
oRst.Bookmark = Me.Recordset.Bookmark
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

Knobbi38

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

Stele4

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

Knobbi38

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