version=1.1.0
vdate=24.06.2014
fname=sequence.cls
ns=%NAMESPACE%
fpath=/vba/classes
{{description> Sequenzen fehlen in MS Access. Darum hier die ultimative Klasse dazu}}
~~DISCUSSION~~
{{keywords>Sequence Sequenz}}
======[VBA][Access] Klasse Sequence======
==Version %%version%% (%%vdate%%)==
>//Das Modul hat versteckte Attribute. Damit diese aktiv übernommen werden reicht es nicht aus, den Code in ein neues Modul zu kopieren. Man muss das Modul aus der Datei nach VBA importieren.//
>{{popup>:vba:vba_importfile.png|Bild zum Import}}
{{%%fname%%|Download %%fname%% (V-%%version%%)}}
Ich vermisse in MS Access die Möglichkeiten von Sequenzen. Darum habe ich mir eine Sequenz-Klasse gebaut..
Die Sequenzen werden in einer Hilfstabelle gespeichert. Standardmässig heisst diese ADDON_SEQUENZ. Der Name kann aber in der Klasse angepasst werden (Konstante C_SEQ_TABLE abändern)
Um die Tabelle muss man sich nicht kümmern. Diese wird automatisch erstellt falls sie nicht vorhanden ist
=====Anwendungsbeispiele=====
Zuerst zeige ich mal wie man sie anwendet
'Sequenz ganz bewusst erstellen
debug.print Sequence("SEQ_TEST").create '1
'Nächste Nummer der Sequenz SEQ_TEST ausgeben
debug.print Sequence("SEQ_TEST").nextVal() '2
debug.print Sequence("SEQ_TEST").nextVal() '3
debug.print Sequence("SEQ_TEST").nextVal() '4
'Letzte Nummer auswählen
debug.print Sequence("SEQ_TEST").lastVal '4
'Zurücksetzen
debug.print Sequence("SEQ_TEST").reset() '1
'löschen
call Sequence("SEQ_TEST").delete()
'Wieder aufrufen ohne bewusst zu erstellen. Standartmässig wird die Sequenz automatisch erstellt
debug.print Sequence("SEQ_TEST").nextVal() '1
'Einen Sequenzaufruf auf eine Nicht existierende Sequenz mit Fehlergenerierung
debug.print Sequence("SEQ_TEST").nextVal(seqNotExistError) 'Error
Und ein weiteres Beispiel
Public Sub testSeq()
Dim seqA_1 As Sequence
Dim seqA_2 As Sequence
Dim seqName As String: seqName = "A"
'Mal vornweg die Sequenz löschen falls sie existiert
Call Sequence(seqName).delete
'seqA_1 über die staitsche Funktion erstellen
Set seqA_1 = Sequence(seqName)
'seqA_2 auf die klassische Art
Set seqA_2 = New Sequence
seqA_2.initMe (seqName)
'Zugriffe über verschieden Methoden auf die Sequqenz 'A'
'Wie man sieht, greifen alle auf dieselben Daten zu
'Zuerst mal nextNr() auf eine Seqeunz die nicht existiert
Debug.Print seqA_1.nextVal(seqNotExist0) '0
Debug.Print seqA_2.nextVal(seqNotExist0) '0
Debug.Print seqA_1.nextVal(seqNotExistCreate) '1
'Die Sequqnz ein wenig weiterblättern
Debug.Print seqA_2.nextVal '2
Debug.Print Sequence(seqName).lastVal '2
Debug.Print Sequence(seqName).nextVal '3
Debug.Print seqA_2.lastVal '3
'un neu erstellen
Debug.Print seqA_1.create(seqCreateOnExistReset) '1
Debug.Print Sequence(seqName).nextVal '2
End Sub
{{anchor:staticClasses}}
=====Modul staticClasses=====
Um auf die Klasse zuzugreifen ohne sie vorher zu initialisieren verwende ich einen Statischen
Aufruf ([[vba:access:staticClass]]). Darum habe ich das folgende Modul staticClasses. Der Trick dabei ist, dass die Funktion gleich heisst wie die Klasse. Somit kann mit der Klasse wie im obigen Beispiel hantiert werden
====Definitionen====
===Local Properties===
==staticSequenz==
Ein VB-Dictionary mit den bereits gebrauchten Sequenzen. Alsi Key dient der Seqenzname, als Value jeweils das Sequenzobjekt
Private staticSequence As Dictionary
===Methodes===
==Sequence()==
Initialisiert die Sequenzen. In der Modul-Variable staticSequenz wird pro Sequenz die aufgerufen wird eine Instanz der Klasse Sequenz erstellt. und im Speicher gehalten.
@param String Name der Sequenz
Public Function Sequence(ByVal iSeqName As String) As Sequence
====Code====
Private staticSequence As Dictionary
'/**
' * Initialisiert die Sequenzen
' * @param String Name der Sequenz
' */
Public Function Sequence(ByVal iSeqName As String) As Sequence
Dim inst As Sequence
If staticSequence Is Nothing Then Set staticSequence = New Dictionary
If Not staticSequence.Exists(iSeqName) Then
Set inst = New Sequence
Call inst.initMe(iSeqName)
Call staticSequence.Add(iSeqName, inst)
End If
Set Sequence = staticSequence.item(iSeqName)
End Function
=====Klasse Sequence=====
Die Klasse handelt das ganze mit den Sequenzen. über die StaticClasses wird pro Sequenz ein
====Definitionen====
===Enumeratoren===
==seqCreateOnExistOptions==
Anweisungen was bei einem create() gemacht werden soll, wenn die Sequenz bereits existiert
*seqCreateOnExist0 'Mach nix und gib eine 0 zurück
*seqCreateOnExistLastVal 'Mach nix und gib die aktuelle Nummer zurück
*seqCreateOnExistNextVal 'Mach nix und gib setze den Sequenz um eins hoch
*seqCreateOnExistReset 'Resete die Sequenz. gibt 1 zurück
*seqCreateOnExistError 'Raise einen Error
==seqNotExistsOptions==
Anweisung wie sich die entsprechende Funktion verhalten soll, wenn die Sequenz noch nicht existiert. Wird in den folgenden Methoden verwendet: lastVal, nextVal(), reset()
*seqNotExistCreate 'erstelle die Sequqnz und gib 1 zurück
*seqNotExist0 'Mach nix und gib eine 0 zurück
*seqNotExistError 'Raise einen Error
===Properties===
==lastVal()==
gibt die aktuelle Nummer zurück
@param seqNotExistsOptions Anweisung, was bei Nichtexistenz der Sequenz geschehen soll
@return Aktueller Wert. Aktuelle Nummer oder 0, je nach iOption
Public Property Get lastVal(Optional ByVal iOption As seqNotExistsOptions = seqNotExist0) As Long
==sequenceExists()==
prüft, ob die Sequenz existiert
@return Boolean
Public Property Get sequenceExists() As Boolean
===Methodes===
==create()==
Erstellt die Sequenz
@param seqCreateOnExistOptions Angabe was gemacht werden soll, falls die Sequenz bereits exisitert
@return eine 1 oder je nach iOption die Aktuelle Sequenznummer oder 0
Public Function create(Optional ByVal iOption As seqCreateOnExistOptions = seqCreateOnExist0) As Long
==nextVal()==
setzt die Sequenz eins weiter
@param seqNotExistsOptions Anweisung, was bei Nichtexistenz der Sequenz geschehen soll
@return Aktueller Wert. Sequenz-Nr oder 0, je nach iOption
Public Function nextVal(Optional ByVal iOption As seqNotExistsOptions = seqNotExistCreate) As Long
==reset()==
setzt die Sequenz auf 1 zurück
@param seqNotExistsOptions Anweisung, was bei Nichtexistenz der Sequenz geschehen soll
@return Aktueller Wert. 1 oder 0, je nach iOption
Public Function reset(Optional ByVal iOption As seqNotExistsOptions = seqNotExistCreate) As Long
==delete()==
Löscht die Sequenz
Public Sub delete()
====Code====
Und die Sequenz-Klasse