In vielen Applikationen wird immer wieder eine Datenstruktur benötigt um beispielsweise Programminformationen, oder aber vom Anwender angelegte Eingabedaten abzulegen. Dafür bietet sich natürlich eine Datenbank wie Access, MS-SQL oder MySQL Server an. Der Nachteil dieser Vorgehensweise ist, dass auf dem Zielsystem erst einmal diese Datenbank angelegt, bzw. installiert werden muss. Weiterhin müssen Sie die nötigen ADO (MDAC) oder DAO Komponenten auf dem Zielsystem installieren. Das bringt oft Risiken mit sich, die Sie im Vorfeld nicht absehen können. Sicherlich kommen Sie um die Benutzung solcher Datenbanken nicht herum, wenn Sie mit komplexen Datenstrukturen arbeiten - doch was ist, wenn Sie lediglich mit einer Tabelle in Ihrer Applikation arbeiten? Dieser Workshop zeigt Ihnen eine Möglichkeit auf, wie Sie mit einer Tabelle arbeiten können, ohne ADO oder DAO in Ihrem Projekt zu nutzen. Die VB6 Klasse "clsRecordset" (virtuelles Recordset) Grundlagen: Die Klasse "clsRecord" ' ************************************************************** ' * ' * clsRecord - Klassenmodul ' * ' * Definieren Sie hier die Felder Ihres Records ' * ' ************************************************************** Option Explicit Public Anrede As String Public Vorname As String Public Nachname As String Public eMail As String Public Betrag As Currency Passen Sie diese Variablen an Ihre persönliche Struktur an. Die Hauptklasse "clsRecordset" Die Eigenschaften der Klasse:
Die Methoden der Klasse:
Die Ereignisse der Klasse:
Funktionen des virtuellen Recordsets Nachfolgend möchten wir Ihnen nun die einzelnen Funktionen unseres virtuellen Recordsets vorstellen. Der allgemeine Deklarationsteil der Klasse Option Explicit Public Enum RSMoveType RSFirst = 0 RSPrev = 1 RSNext = 2 RSLast = 3 End Enum ' Ereignisse der Klasse Public Event RecordMoved(RecordNum As Long, oRecord As clsRecord) Public Event DumpField(vData As Variant) Public Event Dump(oRecord As clsRecord) ' Private Klassen-Vars Private colRS As Collection Private cLockUpdate As Boolean Private RecPTR As Long Die öffentliche Aufzählung (Enum) "RSMoveType" definiert die Bewegungsrichtung des Datensatzzeigers innerhalb der Collection. Der Datensatzzeiger selber ist die Private Long-Variable "RecPTR". Dieser Zeiger markiert die Position innerhalb der Collection auf den aktuellen Record. Die Initialisierung und Terminierung der Klasse ' Klasse initialisieren ' ===================== Private Sub Class_Initialize() Set colRS = New Collection cLockUpdate = False RecPTR = 0 End Sub ' Klasse terminieren ' ================== Private Sub Class_Terminate() Set colRS = Nothing End Sub Die Eigenschaft "AbsolutePosition" ' Eigenschaft "AbsolutePosition" (Read) ' ===================================== Public Property Get AbsolutePosition() As Long AbsolutePosition = RecPTR End Property Die Eigenschaft "Clone" ' Eigenschaft "Clone" ' =================== Public Property Get Clone() As Collection Set Clone = colRS End Property Die Eigenschaft "GetField" ' Eigenschaft "GetField" (Read) ' ============================= Public Property Get GetField(RecordNum As Long, FieldName As String) As Variant Dim dRecord As clsRecord ' Rückgabewert ist der Feldinhalt aus der Recordnum ' und dem Feldnamen (Matrix). Dabei wird der ' Datensatzzeiger nicht verändert. If (RecordNum > 0) And (RecordNum <= colRS.Count) Then Set dRecord = colRS.Item(RecordNum) GetField = CallByName(dRecord, FieldName, VbGet) Set dRecord = Nothing End If End Property Die Eigenschaft "GetRecord" ' Eigenschaft "GetRecord" (Read) ' ============================== Public Property Get GetRecord(RecordNum As Long) As clsRecord ' Rückgabewert ist der Record(RecordNum). Der ' Datensatzzeiger wird nicht verändert. If (RecordNum > 0) And (RecordNum <= colRS.Count) Then Set GetRecord = colRS.Item(RecordNum) End If End Property Die Eigenschaft "RecordCount" ' Eigenschaft "RecordCount" (Read) ' ============================= Public Property Get RecordCount() As Long RecordCount = colRS.Count End Property Methoden der Klasse, Teil 1 Die Methode "ClearRecordset" ' Methode "ClearRecordset" ' ======================== Public Sub ClearRecordset() ' löscht die gesamte Collection Set colRS = New Collection End Sub Die Methode "DelRecord" ' Methode "DelRecord" ' =================== Public Function DelRecord(RecordNum As Long) As Boolean ' löscht den Datensatz(RecordNum) aus der Collection If (RecordNum < 0) Or (RecordNum > colRS.Count) Then DelRecord = False Exit Function End If colRS.Remove RecordNum ' ggf. Datensatzpointer anpassen If RecPTR > colRS.Count Then RecPTR = colRS.Count ' Ereignis "RecordMoved" auslösen If Not cLockUpdate Then RaiseEvent RecordMoved(RecPTR, colRS.Item(RecPTR)) ' Rückgabewert setzen DelRecord = True End Function Hinweis: Verwenden Sie "DelRecord" in Kombination mit der Eigenschaft "AbsolutePosition" um den aktuellen Record aus dem Recordset zu löschen. Beispiel: With myRecordSet Call .DelRecord(.AbsolutePosition) End With Die Methode "DumpFields" ' Methode "DumpFields" ' ==================== Public Sub DumpFields(FieldList() As String) Dim dRecord As New clsRecord Dim vTmp As Variant Dim x As Long ' Es werden die Felder aus der Arg-Liste gedumpt. ' Die Schleife läuft dabei über alle Records aus ' der Collection. Diese Funktion eignet sich zum ' Speichern der Collection in eine Datei. For Each dRecord In colRS For x = LBound(FieldList) To UBound(FieldList) vTmp = CallByName(dRecord, FieldList(x), VbGet) ' Ereignis auslösen RaiseEvent DumpField(vTmp) Next x Next dRecord Set dRecord = Nothing End Sub Die Methode "DumpRecordset" ' Methode "Dumprecordset" Public Sub DumpRecordset() Dim dRecord As New clsRecord ' Es werden alle Records gedumpt. ' Die Schleife läuft dabei über die gesamte ' Collection. Diese Funktion eignet sich zur ' Ausgabe der Records in ein Listenelement ' wie z.B. das ListView. For Each dRecord In colRS RaiseEvent Dump(dRecord) Next dRecord Set dRecord = Nothing End Sub Die Methode "Find" Die Suchmethode beginnt ab der aktuellen Position innerhalb unseres Recordsets. Wird eine Übereinstimmung mit dem Suchbegriff gefunden, wird der Datensatzzeiger auf diesen Record positioniert und das Ereignis "RecordMoved" ausgelöst. Als Rückgabewert der Funktion wird der gefundene Record übergeben. Wird keine Übereinstimmung gefunden, bleibt der Datensatzzeiger an der ursprünglichen Position. Als Rückgabewert der Funktion wird "Nothing" übergeben. Über den optionalen 3. Parameter können Sie den Suchmodus bestimmen. Setzen Sie "FindNext" auf True, so beginnt die Suche ab der aktuellen Position + 1 im Recordset. Mit dem 4. optionalen Parameter legen Sie fest, ob nach einer genauen Übereinstimmung oder nach einem Teilbegriff gesucht werden soll. ' Methode "Find" ' ============== Public Function Find(FieldName As String, sMatch As Variant, _ Optional FindNext As Boolean = False, _ Optional ExactMatch As Boolean = False) As clsRecord Dim dRecord As New clsRecord Dim bFound As Boolean Dim vTmp As Variant Dim lRet As Long Dim tPtr As Long Dim x As Long ' Pointer in Hilfsvariable retten tPtr = RecPTR If (FindNext = True) And (RecPTR < colRS.Count) Then RecPTR = RecPTR + 1 tPtr = RecPTR End If ' Schleife über alle Records ab der ' aktuellen Position For x = tPtr To colRS.Count Set dRecord = colRS.Item(x) vTmp = CallByName(dRecord, FieldName, VbGet) bFound = False ' exakte Suche If ExactMatch Then If sMatch = vTmp Then bFound = True Exit For End If ' Suche nach Teilbegriff Else vTmp = Trim(CStr(UCase(vTmp))) sMatch = Trim(CStr(UCase(sMatch))) lRet = InStr(1, vTmp, sMatch) If lRet > 0 Then bFound = True Exit For End If End If RecPTR = RecPTR + 1 Next x ' Suchbegriff gefunden If bFound Then If Not cLockUpdate Then RaiseEvent RecordMoved(RecPTR, colRS.Item(RecPTR)) Set Find = colRS.Item(RecPTR) Else RecPTR = tPtr Set Find = Nothing End If If Not dRecord Is Nothing Then Set dRecord = Nothing End Function Die Methode "GotoRecord" ' Methode "GotoRecord" ' ==================== Public Function GotoRecord(RecordNum As Long) As clsRecord If (RecordNum < 0) Or (RecordNum > colRS.Count) Then GotoRecord = Nothing Exit Function End If RecPTR = RecordNum Set GotoRecord = colRS.Item(RecPTR) If Not cLockUpdate Then RaiseEvent RecordMoved(RecPTR, colRS.Item(RecPTR)) End Function Die Methode "LockUpdate" ' Methode "LockUpdate" ' =================== Public Sub LockUpdate(Optional vLock As Boolean = True) cLockUpdate = vLock End Sub Methoden der Klasse, Teil 2 Die Methode "NewRecord" ' Methode "NewRecord" ' =================== Public Sub NewRecord(oRecord As clsRecord) If oRecord Is Nothing Then Exit Sub colRS.Add oRecord RecPTR = colRS.Count If Not cLockUpdate Then RaiseEvent RecordMoved(RecPTR, colRS.Item(RecPTR)) End Sub Die Methode "MoveRecord"
Auch hier wird das Ereignis "RecordMoved" ausgelöst. Als Rückgabewert der Methode wird das Record, auf dem sich der Datensatzzeiger befindet, zurückgegeben. ' Methode "MoveRecord" ' ==================== Public Function MoveRecord(ByVal MoveType As RSMoveType) As clsRecord If RecPTR <= 0 Then Exit Function ' Diese Methode positioniert den Datensatzzeiger. ' Die Richtung wird über die Aufzählung (Enum) ' "RSMoveType" bestimmt. Select Case MoveType Case RSFirst: RecPTR = 1 Case RSPrev If RecPTR > 1 Then RecPTR = RecPTR - 1 Case RSNext If RecPTR < colRS.Count Then RecPTR = RecPTR + 1 Case RSLast: RecPTR = colRS.Count End Select Set MoveRecord = colRS.Item(RecPTR) If Not cLockUpdate Then RaiseEvent RecordMoved(RecPTR, colRS.Item(RecPTR)) End Function Die Methode "SaveRecord" ' Methode "SaveRecord" ' ==================== Public Function SaveRecord(RecordNum As Long, oRecord As clsRecord) As Boolean If (RecordNum < 0) Or (RecordNum > colRS.Count) Then SaveRecord = False Exit Function End If ' Es werden die Änderungen eines Records ' in die Collection zurückgeschrieben. colRS.Remove RecordNum If RecordNum <= colRS.Count Then colRS.Add oRecord, , RecordNum Else colRS.Add oRecord End If SaveRecord = True End Function Die Methode "Sort" Als Sortierkriterium geben Sie den Feldnamen an, nach dem sortiert werden soll. Als optionaler 2. Parameter legen Sie die Sortierrichtung auf- oder absteigend fest. Der Default ist aufsteigend. ' Methode "Sort" ' ============== Public Function Sort(FieldName As String, _ Optional sOrderASC As Boolean = True) As Boolean Dim dRecord As New clsRecord Dim cRecord As New clsRecord Dim tmpCol As Collection Dim vOrg As Variant Dim vComp As Variant Dim bFound As Boolean Dim lPos As Long On Error GoTo Sort_Error If colRS.Count <= 1 Then Exit Function Set tmpCol = New Collection ' Äußere Schleife über alle Records in colRS For Each dRecord In colRS ' Value aus dem Feldnamen holen vOrg = CallByName(dRecord, FieldName, VbGet) ' Variablen initialisieren bFound = False lPos = 0 ' Innere Schleife über alle Records aus ' der Swap-Collection For Each cRecord In tmpCol lPos = lPos + 1 ' Value aus dem Feldnamen holen vComp = CallByName(cRecord, FieldName, VbGet) ' Feldinhalte vergleichen ASC If sOrderASC Then If vOrg < vComp Then bFound = True ' Record einfügen wenn kleiner tmpCol.Add dRecord, , lPos Exit For End If ' Feldinhalte vergleichen DESC Else If vOrg > vComp Then bFound = True ' Record einfügen wenn größer tmpCol.Add dRecord, , lPos Exit For End If End If Next cRecord ' ggf. Record anhängen If Not bFound Then tmpCol.Add dRecord Next dRecord ' Swap-Collection zuweisen Set colRS = tmpCol RecPTR = 1 If Not cLockUpdate Then RaiseEvent RecordMoved(RecPTR, colRS.Item(RecPTR)) Set tmpCol = Nothing Set dRecord = Nothing ' Rückgabewert setzen Sort = True Exit Function Sort_Error: Sort = False If Not tmpCol Is Nothing Then Set tmpCol = Nothing If Not dRecord Is Nothing Then Set dRecord = Nothing End Function So, das war´s. In unseren Beispielprojekten zeigen wir Ihnen, wie Sie die Klasse einmal mit einem ListView und zum anderen mit dem sevDataGrid v2.0 nutzen können. Schlussbemerkung: Die Klasse ist so aufgebaut, dass Sie sie nicht nur als Frontend, sondern auch ohne jegliche Oberfläche, also als Backend nutzen können.Wir wünschen Ihnen gutes Gelingen mit dem virtuellen Recordset. Dieser Workshop wurde bereits 37.738 mal aufgerufen.
Anzeige
Diesen und auch alle anderen Workshops finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
sevAniGif (VB/VBA) Anzeigen von animierten GIF-Dateien Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. Tipp des Monats Oktober 2024 Heinz Prelle Firewall-Status unter WinXP/Vista prüfen Das Beispiel prüft, ob die Firewall unter Windows XP/Vista eingeschaltet ist oder nicht. Zudem wird eine Abfrage durchgeführt ob es sich bei dem zugrundeliegenden Betriebssystem um Windows XP/Vista handelt oder nicht. TOP Entwickler-Paket TOP-Preis!! Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR... |
|||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |