Moin Gemeinde,
gibt es eine Möglichkeit die zuletzt angezeigten Datensätze (sagen wir mal 20) zu speichern und mit Buttons dann durchzublättern?
Vielleicht hat ja jemand von euch eine Beispieldatei dazu?
Wünsche allen einen schönen Tag
Jörg
Hallo,
warum nimmst Du nicht einfach eine Abfrage für die 20 DS?
Dann kannst Du die Abfrage durchblättern.
Oder Du nimmst ein Formular das auf 20 DS gefiltert wird.
Hallo Jörg,
was genau machst Du denn Filters Du die Daten und willst den Filter erneut verwenden oder Scrollst du einfach nur durch oder ???
Gruß
Holger
Hallo Jörg,
kannst du bitte mal ein wenig ausholen, damit man auch versteht, was du da eigentlich machen möchtest?
Knobbi38
Ich hab mich wahrscheinlich missverständlich ausgedrückt.
Ich möchte die letzten 20 Datensätze die ich aufgerufen habe durchblättern können.
Liebe Grüße
Jörg
Wie aufgerufen
Willkürlich und dann wie oder gefiltert und dann wie gib uns etwas mehr bitte
Holger
Hallo Holger,
der Aufruf erfolgt willkürlich und ist nicht gefiltert.
Es sollen einfach die 20 zuletzt aufgerufenen Datensätze nachzuverfolgen sein.
Liebe Grüße
Jörg
Ja gut, dann mußt du dir einfach die letzten 20 Primärschlüssel merken, z.B. in einer Auflistung, und dann diese Informationen in einem Filter anwenden. Am einfachsten geht so etwas mit einer Klasse. Suche mal mit den Begriffen "Bounded Queue FIFO mit Historie VBA" im Internet, dann kommen schon die richtigen Lösungen.
Knobbi38
Hallo Jörg,
das was Knobbi schreibt ist eine gute Lösung.
Hier mal mein (meine Beschreibung) Ansatz dazu:
mit einem Zeitstempel und einer entsprechenden Protokolltabelle kanns Du das meiner Meinung nach umsetzten
Du musst vom Prinzip her folgendes machen:
1. Eien kleine Zusatz-Tabelle erstelle die immer die ID des gerade aufgerufenen Datensatzes und einen Zeitstempel speichert.
2. Ein Formular erstellen, welches dan die lezten z.B.: 20 Einträge aus der Zusatz-Tabelle anzeigt.
Du musst eigentlich folgendes machen
Deine Tabelle anpassen falls nicht vorhanden mit einem Primärschlüssel versehen z.B.: ID
Erstellen der Zusatz-Tabelle z.B.: tblZugriff mit folgenden Feldern
- IDProtokoll (AutoWert)
- IDDaten (Zahl, bezieht sich auf DeineTabelle.ID)
- TimeStamp (Datum/Uhrzeit, Standartwert = Jetzt() )
Eine Abfrage erstellen (qryLetzte20) für die letzten "20 aufgerufenen Datensätze"
SELECT TOP 20
DeineTabelle.*
FROM
DeineTabelle
INNER JOIN
tblZugriff
ON DeinTabelle.ID = tblZugriff.IDDaten
ORDER BY
tblZugriff.TimeStamp DESC;
Das sollte die immer die letzten 20 DAtensätze nach TimeStamp anzeigen.
Was ist nun noch weiter zu machen:
Protokollieren beim öffnen oder Erstellen eines Datensatzes
Im entsprechenden Formular kannst Du im Ereignis Form_Current folgendes zufügen:
Private Sub Form_Current()
Dim idAktuell As Long
If Me.NewRecord Then Exit Sub
idAktuell = Nz(Me!ID, 0)
If idAktuell = 0 Then Exit Sub
CurrentDb.Execute "INSERT INTO tblZugriff (IDDaten) VALUES (" & idAktuell & ");", dbFailOnError
End Sub
Du musst natürlich die Feldnamen anpassen!
Was passiert hier: Jedes Mal, wenn Du Datensätze aufrufst / wechselst, wird ein Eintrag mit IDDaten und einem aktuellem TimeStamp angelegt.
Jetzt musst Du ein Formular erstellen auf Basis der Abfrage qryLetzte20
Das Formular kannst Du nun als Endlosformualr oder Datenblatt darstllen, wie Du möchtest.
Du musst natürlich noch darauf achten, dass die Tabelle tblZugriff nicht zu groß wird also immer Reorganisieren sprich alles löschen was mehr als X Einträge in der DB ergibt und hier natürlich immer die ältesten zuerst.
Ich hoffe das ist einigermaßen verständlich.
Holger
Das ist das was Knobbi meint die Lösung gibt noch mehr her:
Sorry der Text ist kopiert aus Google
Eine "Bounded Queue" (begrenzte Warteschlange) nach dem FIFO-Prinzip (First-In-First-Out) mit Historie lässt sich in VBA am besten durch ein Klassenmodul umsetzen. Dieses verwaltet ein festes Array (die Begrenzung) und speichert die Historie (alle jemals hinzugefügten Elemente) in einem separaten Log, beispielsweise auf einem Arbeitsblatt.VBA Lösung: Bounded Queue KlasseKlassenmodul erstellen: Nennen Sie es BoundedQueue.Code einfügen:vba' --- Klassenmodul: BoundedQueue ---
Option Explicit
Private pItems() As Variant
Private pCapacity As Long
Private pSize As Long
Private pHead As Long
Private pTail As Long
Private pHistorySheet As Worksheet
' Initialisierung der Queue
Public Sub Init(Capacity As Long, HistorySheet As Worksheet)
pCapacity = Capacity
ReDim pItems(0 To pCapacity - 1)
pSize = 0
pHead = 0
pTail = 0
Set pHistorySheet = HistorySheet
End Sub
' Element hinzufügen (Enqueue)
Public Sub Enqueue(Item As Variant)
If pSize = pCapacity Then
' Optional: Altes Element entfernen, wenn voll (Overflow)
Dequeue
End If
pItems(pTail) = Item
pTail = (pTail + 1) Mod pCapacity
pSize = pSize + 1
' Historie auf dem Arbeitsblatt loggen
LogToHistory Item
End Sub
' Element entfernen (Dequeue)
Public Function Dequeue() As Variant
If pSize = 0 Then
Dequeue = Null
Exit Function
End If
Dequeue = pItems(pHead)
pItems(pHead) = Empty ' Speicher freigeben
pHead = (pHead + 1) Mod pCapacity
pSize = pSize - 1
End Function
' Historie in Excel schreiben
Private Sub LogToHistory(Item As Variant)
Dim nextRow As Long
nextRow = pHistorySheet.Cells(pHistorySheet.Rows.Count, 1).End(xlUp).Row + 1
pHistorySheet.Cells(nextRow, 1).Value = Now ' Zeitstempel
pHistorySheet.Cells(nextRow, 2).Value = Item ' Element
End Sub
Public Property Get Count() As Long
Count = pSize
End Property
Verwende Code mit Vorsicht.Nutzung der Klasse (Standardmodul)vba' --- Standardmodul ---
Sub TestQueue()
Dim q As New BoundedQueue
Dim wsLog As Worksheet
Set wsLog = ThisWorkbook.Sheets("Log") ' Arbeitsblatt für Historie
' Initialisiere Queue mit Kapazität 5
q.Init 5, wsLog
' Elemente hinzufügen
q.Enqueue "Auftrag 1"
q.Enqueue "Auftrag 2"
q.Enqueue "Auftrag 3"
Debug.Print "Queue Größe: " & q.Count ' Ausgabe: 3
End Sub
Verwende Code mit Vorsicht.Kernfunktionen dieser ImplementierungBounded: Die Kapazität wird über ReDim festgesetzt.FIFO: Die pHead/pTail Pointer-Logik (Circular Buffer) stellt sicher, dass das erste Element zuerst entfernt wird.Historie: Die LogToHistory-Prozedur schreibt jeden Enqueue-Vorgang mit Zeitstempel in eine Excel-Tabelle.Overflow Handling: Wenn die Queue voll ist, wird das älteste Element entfernt (Dequeue innerhalb Enqueue), um Platz zu machen.Diese Methode ist ideal, um z.B. die letzten \(N\) Aktivitäten zu verfolgen und gleichzeitig eine vollständige Historie auf einem Blatt zu führen.
Danke für eure antworten. Das werde ich mir die Tage anschauen.
Liebe Grüße
Jörg
Hallo Jörg,
habe Dir mal auf die schnelle noch eine klein Demo gemacht.
Das Reorganisieren und dass keine doppelten dabei sind, würde ich an Deiner Stelle aber auch noch einbauen.
Holger
Hallo Jörg, habe Dir auch noch das reorganisieren eingebaut. Beim Laden Deines Formulars werden alle Datensätze aus der Tabelle tblZugriff gelöscht. Alle bis auf die letzten 10. Des Weiteren habe ich noch in Backup der Tabelle eingebaut damit Du ggf immer noch einen schritt zurück kannst.
Holger
Hier der Code für Dein Formular
Private Sub Form_Load()
Const cTblQuelle As String = "tblZugriff"
Const cTblBackup As String = "tblZugriff_Backup"
Dim strSQL As String
On Error GoTo ErrorHandler
If DCount("*", "MSysObjects", "Name='" & cTblBackup & "' AND Type=1") > 0 Then
DoCmd.DeleteObject acTable, cTblBackup
End If
DoCmd.CopyObject , cTblBackup, acTable, cTblQuelle
If DCount("*", cTblQuelle) > 10 Then
strSQL = "DELETE * " & _
"FROM tblZugriff " & _
"WHERE IDProtokoll NOT IN " & _
"(SELECT TOP 10 IDProtokoll " & _
" FROM tblZugriff " & _
" ORDER BY TimeStamp DESC, IDProtokoll ASC);"
CurrentDb.Execute strSQL, dbFailOnError
End If
Exit Sub
ErrorHandler:
MsgBox "Fehler:" & vbCrLf & Err.Description, vbCritical
End Sub
Gruß
Holger
Hallo Holger,
das mit der "Bounded Queue" sollte eigentlich ganz gut funktionieren, allerdings hatte ich da eher an eine Collection gedacht als an ein Implementierung mit einem Array. Wenn es um Eindeutigkeit geht, wäre ein Dictionary vielleicht sogar besser. Das Log per Excel Sheet ist dabei eine, wie ich finde, pfiffige Idee denn so exzessives Einfügen und Löschen führt unweigerlich zum Aufblähen der DB und würde öfters eine Datenkomprimierung notwendig machen. Ich bin mir nicht sicher, ob die Tabelle "tblZugriff" wirklich benötigt wird.
Gruß Knobbi38
Hallo Knobbi,
Du hast natürlich recht mit Deiner Lösung, und diese ist auch deutlich "eleganter", was ich auch schon in #8 erwähnt hatte. Aber ich glaube, das Jörg hier mehr private Dinge verwaltet, wenn ich mich richtig entsinne :=)). Daher wird die Datenmenge überschaubar sein. Aus diesem Grund habe ich versucht eine einfache und für Ihn einfach nach zu vollziehende Lösung zu bauen. Und um das Problem des Aufblähens der DB zu vermeiden habe ich ja noch das reorganisieren mit eingebaut. Wenn man nun im privaten Bereich alle 14 Tage die DB beim beenden komprimiert sollte das meiner Meinung nach vollkommen ausreichen (kann man ja auch per vba regeln).
Aber wie gesagt Deine Lösung ist auf jeden Fall die elegantere und auch bessere wenn man von anderen Datenmengen ausgeht.
Gruß
Holger