smartsuitefaq.martinholz.de

Verwendung von Listen oder Arrays um Daten aus einer Textdatei auszulesen und in eine Approach Datenbank zu schreiben

In der cdplayer.ini, die sich in Win9x Systemen im Windows-Ordner befindet und je nach (Windows-) Cd-Player auch genutzt wird, werden von dem Windows-Cd-Player Albuminformationen wie Artist, Albumtitel und die einzelnen Lieder gespeichert. Programme zur Umwandlung von Audio-CDs in MP3-Dateien können teilweise die Ergebnisse von CDDB-Abfragen in die cdplayer.ini schreiben.

Um eine persönliche CD-Datenbank mit Approach zu erstellen wollte ich diese cdplayer.ini mit LotusScript direkt aus dieser ApproachDB auslesen, nachdem Martin sowas mit einem Perlscript vorgemacht hatte. Die ApproachDB besteht aus zwei Tabellen, die eine nimmt die "Kopfdaten", also AlbumID, Albumtitel und Interpret auf, die andere nimmt auch die AlbumID, jetzt SongID genannt und den Songtitel auf. Die Tabellen sind über die AlbumID verknüpft.

Der erste Lösungsansatz, bei dem die cdplayer.ini ausgelesen wurde, verwendete Arrays als Datencontainer, später kam in der NG die Frage nach dem Import der Feurio! eigenen Datenbank auf (Anmerkung: Feurio! bietet eine Möglichkeit, die Einträge der cdplayer.ini zu importieren, dabei ist aber allergrößte Vorsicht geboten, mein Feurio hat bei den importierten Daten mehrfach gleiche AlbumIDs zugewiesen, das sorgt dann beim späteren Import in Approach für allergrößtes Chaos).

Damit stellte sich gleichzeitig die Frage, wie denn mit Quelldateien größer 64 kByte zu verfahren sei, weil Arrays genau wie *.INI-Dateien auf 64 kByte beschränkt sind. Die Lösung habe ich - angeregt durch einen Artikel in der Approach FAQ von John Brown - in der Verwendung von Listen anstelle von Arrays gefunden:

Example LotusScript: Linked List class (beats 64K limit on arrays)
http://www.netspace.net.au/~jabrown/approach/webfaq04902360.html

Sie können hier zwei Beispieldatenbanken herunterladen, eine mit Arrays für das Auslesen der cdplayer.ini und eine mit Listen zum Auslesen der persönlichen Feurio! Datenbank:

Das Funktionsschema beider Lösungsansätze ist gleich, lediglich die Quelldateien und die verwendeten Datencontainer (Arrays bzw. Listen) sind unterschiedlich. Die Hauptbestandteile sind zwei Scripts, das Hauptscript "cdplayerini" und das Prüfscript "Pruefung". Nachfolgend der grobe Ablauf mit entsprechenden "Script-Schnipseln", um das vollständige Script ansehen zu können, öffnen Sie bitte die Beispieldateien und rufen die IDE auf.

1. Die Quelldatei wird geöffnet

'LotusScript benötigt für das Öffnen einer Datei eine 'Dateinummer', 
'es wird eine unbenutzte Dateinummer angefordert und in die 
'fileNum-Variable getan.
Dim fileNum As Integer
fileNum% = Freefile()
 
'Die Quelldatei wird zum EINLESEN geöffnet, ggf. wäre der Pfad anzupassen
Open "C:\Programme\Feurio\db_personal.cdb" For Input As fileNum%

'Hier würde eine Routine zum Einlesen der Zeilen in 
'einen Container (Array/Liste) stehen
'siehe 2.
 
'Sehr wichtig: nach dem Auslesen des Inhaltes muß 
'die Datei wieder geschlossen werden.
Close fileNum%

2. Alle Zeilen der Quelldatei werden zeilenweise in den Container (Liste oder Array, siehe auch "Dim statement in LotusScript" in der LotusScript Hilfe) eingelesen, jede Zeile wird als Eintrag behandelt

Beispiel für das einlesen in eine Liste:

'Die Liste wird deklariert, auf das "As [Type]" wird verzichtet, die Liste ist damit "Type = Variant"
Dim listZeile List

'Die Stringvariable, die jeweils eine Zeile der Quelldatei beim auslesen und 
'später beim weitergeben aufnimmt.
Dim txt As String
 
'Der Zeilenzähler wird deklariert und initialisiert
Dim zaehlerZeile As Integer
zaehlerZeile% = 0
 
'Mit dieser Schleife werden die Zeilen komplett und eine nach der anderen in die Liste eingelesen, 
'sie geht die Zeilen der Quelldatei solange Zeile für Zeile durch, bis sie am Ende der Datei 
'angekommen ist (EOF = End Of File)
Do While Not Eof(fileNum%)

    'Der Befehl zum einlesen der aktuellen Zeile in die Stringvariable "txt"
    Line Input #fileNum%, txt$
 
    'Der Befehl um die Zeile in die Liste zu schreiben. Die Listeneinträge teilen sich
    'in "Name des Eintrags" (in Klammern) und "dem Namen zugeordneter Wert"
    '(rechts vom Gleichheitszeichen) auf.
    listZeile(zaehlerZeile%) = txt$

    'Der Zähler für die laufende Nummerierung bzw. Für den "Namen" der Listeneinträge
    zaehlerZeile% = zaehlerZeile% + 1
 
Loop

Beispiel für das einlesen in ein Array:

'Die dynamischen Arrays werden deklariert. 
Dim arrayZeile() As String

'Die Stringvariable, die jeweils eine Zeile der *.ini aufnimmt.
Dim txt As String
 
Dim zaehlerZeile As Integer, countRec As Integer
zaehlerZeile% = 0
 
'Mit dieser Schleife wird gezählt, wieviele Zeilen in der Quelldatei sind, um das Array 
'dimensionieren zu können, es soll ja weder zu groß, noch zu klein sein
Do While Not Eof(fileNum%)
    Line Input #fileNum%, txt$
    zaehlerZeile% = zaehlerZeile% + 1
Loop

'Der "filepointer" wird wieder an den Anfang der Datei gesetzt.
Seek fileNum%, 1
 
'Die Quelldatei hat soviele Zeilen, wie jetzt im zaehlerZeile steht. Bevor das dynamische Array
'benutzt werden kann, muß es mit dem ReDim Befehl auf eine feste Größe dimensioniert werden. 
Redim arrayZeile(zaehlerZeile%)
 
'Mit einer Schleife werden die Zeilen in das Array eingelesen, womit der Inhalt ein Abbild der 
'Quelldatei ist. Hier kommt der Zeilenzähler wieder zum Einsatz.
For countRec% = 1 To zaehlerZeile%
    Line Input #fileNum%, txt$
    arrayZeile(countrec%) = txt$
Next

3. Der Inhalt des gerade gefüllten Containers wird zeilenweise mit festgelegten Zeichenfolgen verglichen und dann mehr oder weniger modifiziert auf die weiteren Container AlbumID, Artist, Title, SongID, Song verteilt. Als Beispiel gebe ich hier den Script-Teil wieder, der sich mit der AlbumID beschäftigt. Mit dabei ist die Übergabe der AlbumID an das Prüf-Script, das in Erfahrung bringt, ob die AlbumID schon in der ApproachDB vorhanden ist. Die Funktion "Prüfung" wird in Schritt 4. detaillierter beschrieben.

'Der Container, hier eine Liste, wird deklariert
Dim listAlbumID List

'Die Variable, die die AlbumID zum späteren verknüpfen mit den Songtiteln
'aufnimmt, wird jedesmal, wenn eine neue CD anfängt, neu gefüllt.
Dim albumID As String
 
'Eine Zählervariable wird deklariert und initialisiert.
Dim zaehlerAlbumID As Integer
zaehlerAlbumID = 1
 
'Ein Merker wird deklariert und initialisiert
Dim pruefFlag As Integer
pruefFlag = True
 
'Mit einer Forall-Schleife werden die eingelesenen Zeilen in Unterlisten aufgeteilt.
Forall x In listZeile
 
    'Als erstes wird nach einer mit '#' beginnenden Zeile gesucht, weil die AlbumID in der 
    'Feurio! DB damit anfängt
    If x Like "[-#]*" Then 
 
        'Die Variable AlbumID ist ein zentrales Element beider Scipte, weil sie die AlbumId
        'für die Übergabe an das Prüfscript aufnimmt und später den Wert an die SongID Liste
        'übergibt.
        AlbumID = x
 
        'Hier wird sie an die Function 'Pruefung' übergeben und der Rückwert abgeholt
        If pruefung(AlbumID) = True Then
            'Die Variable PruefFlag wird gefüllt, dann sehen die weiteren Schritte, 
            'ob sie einen Wert in die jeweilige Liste schreiben dürfen oder nicht.
            pruefFlag = True
        Else
            pruefFlag = False
        End If
 
        'Wenn die AlbumID noch nicht in der *.DBF vorhanden ist, dann wird sie zusammen
        'mit dem aktuellen Zählerstand (entspricht einer lfd. Nummer) in die vorgesehene Liste
        'geschrieben
        If pruefFlag = False Then
            listAlbumID(zaehlerAlbumID) = AlbumID
            zaehlerAlbumID = zaehlerAlbumID + 1
       End If
    End If
End Forall

4. Während des Aufteilens wird jeweils die AlbumID zur Prüfung an das Prüfscript übergeben und ein Rückgabewert zur Entscheidung über das weitere Verfahren verwendet. Das Prüfscript stellt eine Verbindung zur DBF her, schaut nach, ob die (eindeutige) AlbumID in der ApproachDB schon vorhanden ist und gibt je nach Ergebnis True oder False als Wert zurück.

Function pruefung(AlbumID$)

'Variablen für die Verbindung initialisieren.
Dim Con As New Connection
Dim Qry As New Query
Dim ResSet As New ResultSet
 
'Eine "Fehlerfalle", damit der Benutzer zumindest weiß, was schief gegangen ist.
On Error Goto Fehler

'Wenn die Verbindung erfolgreich ist, dann...
If Con.ConnectTo("dBASE IV") Then
 
    '...dieses Connection Object der neuen Abfrage zuordnen.
    Set Qry.Connection = Con
 
    'Der Pfad der Datendatei wird hier zusammen "gebastelt".
    Qry.TableName = CurrentDocument.Path & "haupt_cddb.dbf"
 
    'Das Query Object dem neuen ResultSet zuordnen.
    Set ResSet.Query = Qry
 
    'Die Abfrage wird ausgeführt, wenn erfolgreich, dann...
    If (ResSet.Execute)Then
 
        'Wenn der Ergebnisbereich nicht leer ist, dann gehe zum ersten Datensatz.
        If (ResSet.NumRows) Then 
            ResSet.FirstRow
 
            'Die Schleife um die Datenbank nach Datensätzen zu
            'durchsuchen, bei denen die AlbumID schon vorhanden ist.
            Do
                If AlbumID = ResSet.GetValue("ID")Then
                    'Der Rückgabewert der Überprüfung wird erstellt
                    pruefung = True
                End If
            Loop While (ResSet.NextRow) 
        End If
    End If
 
    ' Verbindung zu Datentabelle schließen.
    Con.Disconnect
End If
Exit Function
 
Fehler: Msgbox Err & " " & Erl & " " & Error$
    Exit Function
End Function

5. Nachdem der Hauptcontainer in die weiteren Container aufgeteilt ist, werden die Inhalte direkt in die *.DBF Dateien der Approach Datenbank geschrieben, dafür werden (wie in 4.) Verbindungen zu den beiden DBFs hergestellt und dann die Zeilen aus den Containern in die DBFs geschrieben.
Hier sind nur noch die Schritte kommentiert, mit denen die Daten in die Dbs geschrieben werden, die anderen Schritte sind ja schon in 4. kommentiert.

Dim rs As New ResultSet
Dim C As New Connection
Dim Q As New Query
 
If C.ConnectTo("dBASE IV") Then
    Set Q.Connection = C
 
    Q.Tablename = CurrentDocument.Path & "CDDB_list_in_dbf_feurio.dbf"
    Set rs.Query = Q
    If (rs.Execute)Then
 
        'Die AddRow-Methode wird angewendet um der DB einen neuen Datensatz
        'hinzuzufügen
        Call rs.addRow()
 
        'Das soll die Schleife so oft machen, wie sie Einträge in den Containern hat. Das 
        'Verfahren ist für Arrays wie Listen gleich.
        For y = 1 To zaehlerAlbumID -1
 
            'Der jeweilige Wert wird in das DB-Feld geschrieben 
            Call rs.SetValue( "ID", listAlbumID(y))
            Call rs.SetValue( "Interpret", listArtist(y))
            Call rs.SetValue( "Albumtitel", listTitle(y))
 
            'Erst mit der Update-Methode werden die mit SetValue gemachten Änderungen
            'in dem ResultSet bzw. der DB gespeichert.
            rs.UpdateRow
 
            'Zum Abschluß des Schleifendurchgangs wird ein neuer Datensatz angelegt.
            Call rs.addRow()
        Next
     End If
End If

6. Abschließend Formatbeispiele zu cdplayer.ini und FeurioDB:

cdplayer.ini

[1887D1E]
artist=Korn
title=Untouchables
numtracks=14
0=Here To Stay
1=Make Believe
2=Blame
3=Hollow Life
4=Bottled Up Inside
5=Thoughtless
6=Hating
7=One More Time
8=Alone I Break
9=Embrace
10=Beat it Upright
11=Wake Up Hate
12=I'm Hiding
13=No One's There
cddbid=0xA10E390E
sourcetoc=150 20472 41253 58576 77261 95273 115742 139027 159986 179250 199276 218440 232886 250694 273225

Feurio!

#C20E5C0E9279E470,BF0E5B0E
A:BRIDE OF CHUCKY
T:BRIDE OF CHUCKY
C:soundtrack
R:14
P:275719
F:20
L:1051827295
B:275720
v:1
0:16,10179456,0,The Screamin' Cheetah Wheelies - Boogie King
1:16,10363500,17312,White Zombie - Thunder Kiss '65
2:16,12867204,34937,Coal Chamber - Blisters
3:16,10848600,56820,Monster Magnet - See You in Hell
4:16,14433636,75270,Judas Priest - Blood Stained
5:16,18914784,99817,Type O Negative - Love You to Death
6:16,11734716,131985,Slayer - Human Disease
7:16,8895264,151942,Stabbing Westward - So Wrong
8:16,7721616,167070,Powerman 5000 - Son of X51
9:16,15818964,180202,Bruce Dickinson - Trumpets of Jericho
10:16,9984240,207105,Static - X - Bled For Days
11:16,12978336,224085,Motorhead - Love For Sale
12:16,8774724,246157,kidneythieves - Crazy
13:16,8608320,261080,Graeme Revell - We Belong Dead
$
Über diesen ArtikelArtikelbewertung
Stand: 08.05.2003
Autor(en): Rainer Schmidt
Durchschnittsnote: Dieser Artikel wurde noch nicht bewertet.
1 2 3 4 5 6