Die Community zu .NET und Classic VB.
Menü

Speichern und Einlesen

 von 

Übersicht 

Im Tutorial werden verschiedene Methoden für die Speicherung und das Einlesen von Daten aus Text-, List- und Comboboxen sowie 1- und 2-dimensionalen Textarrays aufgezeigt. Verwendet werden u.A. die Funktionen Split und Join, die ab VB6 zur Verfügung stehen. Für VB5 werden Ersatzfunktionen angeboten.

Mit freundlichen Grüßen
Peter Sauer

Allgemeines  

Standardvariablen in den Beispielen:

Variable Typ Verwendung
TxtFile String Aufnahme des Dateipfades und -namens
FNr Integer Dateinummer, Zuweisung über FreeFile
Msg String Fehlernummer und -text
zw String Zwischenspeicher beim Einlesen
TrZ String Trennzeichen für Elemente in einem String

Dateien öffnen und schliessen

Um Zugang zu einer Datei zu erhalten, muss eine Datei geöffnet und nach Benutzung wieder geschlossen werden. Zum Öffnen muss eine Dateinummer zugewiesen werden. Häufig wird #1 benutzt, das ist aber schlechter Stil, wesentlich besser ist die Zuweisung über die Funktion FreeFile. FreeFile weist eine freie Dateinummer zwischen 1 und 255 zu, FreeFile 1 eine Dateinummer zwischen 256 und 511.

FNr = FreeFile
Open TxtFile For Input As #FNr
Open TxtFile For Output As #FNr
Open TxtFile For Append As #FNr
Open TxtFile For Binary As #FNr
Close #FNr

Listing 1

Anweisung Methode Ergebnis
Input Lesen eine vorhandene Datei wird zum Einlesen geöffnet
Output Schreiben eine bereits existierende Datei wird gelöscht falls vorhanden, eine neue Datei wird zum Schreiben angelegt, der Zeiger steht auf 0
Append Schreiben ist die Datei vorhanden, wird sie zum Schreiben geöffnet, der Zeiger auf das Dateiende gestellt, sonst wird eine neue Datei zum Schreiben angelegt, der Zeiger steht auf 0
Binary Lesen und Schreiben ist die Datei vorhanden, wird sie zum Lesen und Schreiben geöffnet, der Zeiger auf das erste Byte gestellt, sonst wird eine neue Datei angelegt, der Zeiger steht auf 0. Ist die Länge des zu schreibenden Textes kleiner als die Dateilänge, wird die Dateilänge beim Überschreiben nicht verändert. In einem derartigen Fall muss die Datei vorher gelöscht werden.

Dateinamen zuweisen

Eine Datei muss unter ihrem Namen geöffnet werden. Dazu gehört der Pfad mit Laufwerk und der Dateiname. Die Speicherung von Daten aus Text-, List- und Comboboxen erfolgt in aller Regel im Verzeichnis der Applikation, so auch in den vorgestellten Beispielen.

Die Funktion App.Path liefert das Verzeichnis der Applikation, also das Verzeichnis, in dem die Anwendung installiert ist. Leider gibt es da eine Schwäche. Ist die Anwendung im Hauptverzeichnis installiert, liefert die Funktion einen Wert ohne Backslash wie "C:", während bei Installation in einem Unterverzeichnis ein Backslash angehängt wird, wie zum Beispiel "C:\Test\".

In den Beispielen wird daher eine Funktion zur Ermittlung des Applikationsverzeichnisses eingesetzt.

Private Function AppPathGet() As String 

  Dim zw As String 

      zw = App.Path
      If Right(zw, 1) <> "\" Then 
        zw = zw & "\"
      End If 
      AppPathGet = zw

End Function 

Dim TxtFile As String
   TxtFile = AppPathGet & "TextBox.txt"

Listing 2

Ist die Datei vorhanden?

Vor dem Öffnen einer Datei zum Einlesen sollte geprüft werden, ob die Datei überhaupt vorhanden ist. Das geschieht über die Funktion Dir, die normalerweise einen Dateinamen aus einem Verzeichnis liefert. Wenn das gelieferte Ergebnis ein NullString ist, wurde die Datei nicht gefunden.

If Dir(TxtFile) = "" Then 
   Msg = "Datei '" & TxtFile & " nicht gefunden"
   MsgBox Msg, , "Text einlesen"
   Exit Sub 
End If

Listing 3

Ein etwas besseres Beispiel zum Überprüfen, ob eine Datei vorhanden ist. Hier werden alle Dateien ohne Berücksichtigung des Attributes gefunden:

Public Function FileExists(Path As String) As Boolean
    Const NotFile = vbDirectory Or vbVolume
    On Error Resume Next
    FileExists = (GetAttr(Path) And NotFile) = 0
    On Error Goto 0
End Function

Sub Form_Load()
' Aufruf der Funktion
    If FileExists("D:\test.txt") Then MsgBox "Vorhanden"
End Sub

Listing 4

Error-Routinen verwenden

Beim Arbeiten mit Dateien sollten grundsätzlich Error-Routinen eingesetzt werden. Sie ermöglichen es z.B. ein Programm ordnungsgemäss zu beenden, wenn ein Fehler auftritt. Error-Routinen werden unter VB immer auf Prozedurebene abgehandelt.

Bei On Error GoTo Sprungmarke wird das Programm bei Auftreten eines Fehlers an der Sprungmarke fortgesetzt. Dort können dann über die Funktionen Err.Number und Err.Description Fehlernummer und Fehlerbeschreibung abgerufen werden.

On Error Goto Fehler

'hier folgt der ProgrammCode: Open, Verarbeitung, Close, gefolgt von einem Exit Sub

Fehler:
   Msg = "Fehler: " & Err.Number & vbCrLf & Err.Description
   MsgBox Msg, , "Einlesen Textdatei"

Listing 5

Was ist eigentlich eine Zeile?

Man sollte meinen, eine Zeile ist der Text auf der gleichen Höhe zwischen dem linken und dem rechten Rand. Früher war das so, seit Erfindung moderner Textverarbeitung mit Fliesstext und automatischem Zeilenumbruch nicht mehr. Da repräsentiert eine Zeile praktisch einen Absatz. Für die Textverarbeitung mit Textboxen spielt das keine Rolle, bei Speicherung von Daten aus List- und Comboboxen sehr wohl.

Zeilen werden durch ein CrLf getrennt, ein CarriageReturn/LineFeed (Wagenrücklauf mit Zeilenschaltung). Bei der Texterfassung wird CrLf (&H0D0A = Chr(13) & Chr(10)) über die Return Taste gesetzt. Bei der Programmierung unter VB gibt es dafür die Konstante vbCrLf oder vbNewLine.

Problematik der letzten Zeile

Beim Schreiben von Texten Zeile für Zeile in eine Datei wird der Inhalt jeder Zeile mit einem CrLf in die Datei geschrieben. Wenn das auch mit der letzten Zeile geschieht, wird eine zusätzliche Leerzeile an die Datei angefügt. Beim Einlesen erhält man dann eine zusätzliche Leerzeile bzw. bei List- und Comboboxen einen Leereintrag. Bei jeder erneuten Speicherung wird eine weitere Zeile angefügt. Man kann das aber verhindern.

Merkmale der verwendeten Schreibmethoden

Achtung: Print Anweisung einmal ohne und einmal mit folgendem Strichpunkt

Anweisung Open For Methode
Print #FNr, zw Output oder Append schreibt den Inhalt der Variablen zw an das Ende der unter FNr geöffneten Datei inkl. einem CrLf
Print #FNr, zw; Output oder Append wie oben aber ohne folgenden CrLf
Put #FNr, n, zw Binary schreibt den Inhalt der Variablen zw ab der Position n in die unter FNr geöffnete Datei
#FNr, , zw Binary wie oben ab dem ersten Byte in der Datei, nur Nutzdaten, also ohne CrLf

Merkmale der verwendeten Lesemethoden

Anweisung Open For Methode
Line Input #FNr, zw Input liest ab der aktuellen Position der For Input geöffneten Datei (FNr) bis zum nächsten CrLf in die Variable zw ohne den CrLf
zw = Input(n, #FNr) Input liest n Zeichen ab der aktuellen Position in die Variable zw
zw = Input(LOF(FNr),#FNr) Input direkt nach dem Open liest Zeichen in Länge der Datei in die Variable zw. (LOF = Len of File)
zw = Space(n)
Get #FNr, x, zw
Binary liest ab der Position x in der For Binary geöffneten Datei (FNr) n Zeichen in die Variable zw
zw = Space(LOF(FNr))
Get #FNr, , zw
Binary liest ab dem 1. Byte die komplette Datei

Dimensionierung von lokalen Variablen - Option Explicit

Die erste Anweisung im Programmteil einer Form oder in einem Modul sollte die Anweisung Option Explicit sein. Sie erzwingt die explizite Deklaration von Variablen vor deren Verwendung im Programm. Zu einem guten Stil gehört es auch, den Variablentyp festzulegen.

Option Explicit 

Dim TxtFile As String 
Dim FNr As Integer 
Dim Msg As String

Listing 6

Speichern von Textbox-Texten  

Speichern über die Print Methode For Output

Dies ist die gebräuchlichste Art.

FNr = FreeFile
Open TxtFile For Output As #FNr
'schreiben Textboxinhalt, der folgende _ 
'Strichpunkt verhindert eine Leerzeile am Schluss 
Print #FNr, Text1.Text;
Close #FNr

Listing 7

Speichern über die Print Methode For Append

Methode um bestehende Dateien zu ergänzen, Text anzuhängen

FNr = FreeFile
Open TxtFile For Append As #FNr
'Zeilentrenner einfügen wenn Text bereits vorhanden 
If LOF(FNr) > 0 Then 
   Print #FNr, ""
End If 
'schreiben Textboxinhalt, der folgende _ 
'Strichpunkt verhindert eine Leerzeile am Schluss 
Print #FNr, Text1.Text;
Close #FNr

Listing 8

Speichern über die Put Methode For Binary

Diese Methode ist eigentlich nicht gebräuchlich.

'wenn Datei existiert, löschen 
If Dir(TxtFile) > "" Then 
   Kill TxtFile
End If 
 
FNr = FreeFile
Open TxtFile For Binary As #FNr
'schreiben Textboxinhalt 
Put #FNr, , Text1.Text
Close #FNr

Listing 9

Speichern Zeile für Zeile

Diese Methode wird in den Beispielen nicht verwendet, da man davon ausgehen kann, dass der Text einer Textbox immer komplett gespeichert wird. Zur Abrundung eine kurze Demo.

'zusätzliche Deklaration dieser Variablen 
Dim myArray() As String 
Dim i As Long 

myArray() = Split(Text1.Text, vbCrLf)
FNr = FreeFile
Open TxtFile For Output As #FNr
For i = 0 To UBound(myArray) - 1
   Print myArray(i)
Next 
'letzte Zeile ohne CrLf 
Print myArray(i);
Close #FNr

Listing 10

Einlesen von Textbox-Texten  

Dateilänge überprüfen

Eine Textbox fasst maximal 32.767 Zeichen, das ist die grösste mit einer Integer Variablen darzustellende Zahl. Die Dateilänge sollte daher abgeprüft werden.

If FileLen(TxtFile) > 32767 Then 
   Msg = "Datei '" & TxtFile & " zur gross für Textbox"
   MsgBox Msg, , "Text einlesen"
   Exit Sub 
End If

Listing 11

Die .Sel Eigenschaften der Textbox verwenden

Verwendet werden in den Beispielen die Sel Eigenschaften der Textbox wie .SelLength, .SelStart und .SelText, was den Durchsatz steigert. .SelStart verweist auf die Position des Cursors im Text und repräsentiert eine Zahl zwischen 0 und Textlänge. .SelLength gibt an, wieviele Zeichen markiert sind. .SelText repräsentiert den markierten Text.

LOF(FNr) und EOF(FNr) einsetzen

Die Funktion LOF (Length Of File) liefert nach Öffnen einer Datei die Länge der unter FNr geöffneten Datei.

Die Boolsche Variable EOF (End Of File) signalisiert beim sequentiellen Einlesen einer Datei, ob das Dateiende erreicht ist. Der Versuch über die Dateilänge hinaus einzulesen führt zu einem Fehler.

Zeilenweise einlesen

Das Auslesen Zeile um Zeile aus der Textdatei ermöglichst die kontrollierte Übernahme in eine Textbox. Bei dieser Methode können Teile der Textdatei ausgespart oder nur Teile der Datei übernommen werden.
Bei Übernahme in die Textbox muss an jede Zeile an CrLf angefügt werden, das CrLf für die letzte Zeile ist wieder zu entfernen.

FNr = FreeFile
Open TxtFile For Input As #FNr

'auslesen bis zum Dateiende 
Do While Not EOF(FNr)
   'zeilenweise auslesen und übernehmen 
   Line Input #FNr, zw
   'optional: überprüfen ob Zeile übernommen werden soll 
   'If ZeileUebernehmen Then 
   Text1.SelText = zw & vbCrLf
   'End If 
Loop 
Close #FNr

'den letzten CarriageReturn/LineFeed entfernen 
If Len(Text1.Text) > 0 Then 
   Text1.SelStart = Len(Text1.Text) - 2
   Text1.SelLength = 2
   Text1.SelText = ""
End If

Listing 12

Einlesen komplett über die Input Funktion

Bei dieser Methode wird die Textdatei komplett mit nur einer Anweisung eingelesen.

FNr = FreeFile
Open TxtFile For Input As #FNr
'Datei komplett einlesen 
Text1.SelText = Input(LOF(FNr), #FNr)
Close #FNr

Listing 13

Einlesen komplett über die Get Funktion

Diese Methode ist die mit Abstand schnellste.

FNr = FreeFile
Open TxtFile For Binary As #FNr
'Länge der Variablen an Dateilänge anpassen 
zw = Space(LOF(FNr))
'einlesen in (Zwischen)Variable 
Get #FNr, , zw
Text1.SelText = zw
Close #FNr

Listing 14

Der Umweg über ein Array

Das Auslesen Zeile für Zeile ermöglicht eine kontrollierte oder selektive Übernahme aus einer Textdatei in eine Textbox, das Auslesen komplett über Input und Get nicht. Bei Einsatz eines Arrays ist das trotzdem möglich.

'zusätzliche Deklaration dieser Variablen 
Dim myArray() As String 
Dim i As Long 

FNr = FreeFile
Open TxtFile For Binary As #FNr
'Länge der Variablen an Dateilänge anpassen 
zw = Space(LOF(FNr))
Get #FNr, , zw
Close #FNr
MyArray() = Split(zw, vbCrLf)
For i = 0 To UBound(myArray) - 1
   Text1.SelText = myArray(i) & vbCrLf
Next 
Text1.SelText = myArray(i)

Listing 15

Eine Zeile aus einem TextArray löschen

Da diese Frage häufig gestellt wird, hier eine Funktion dazu

Private Function ArrayStrElementDelete(sArray() As String, Zeile As Long) As Boolean 

   Dim i As Long 

      'verschiebe alle Zeilen ab Zeile um 1 nach vorn 
      For i = Zeile To UBound(sArray) - 1
         sArray(i) = sArray(i + 1)
      Next 
      'Array um 1 verkleinern, damit letztes Element löschen 
      ReDim Preserve sArray(LBound(sArray) To UBound(sArray) - 1)
End Function

Listing 16

Funktionen zum Speichern und Einlesen von Textboxen  

Bei mehreren Textboxen sind Funktionen, die mehrfach genutzt werden können, einzelnen Programmteilen vorzuziehen.

Funktion zum Schreiben eines Textboxtextes in eine Textdatei

Private Function TextboxSaveToFile _
(Tbox As TextBox, TxtFile As String, _
Optional doAppend As Boolean = False, _
Optional WithCrLf As Boolean = False, _
Optional Msg As String) As Boolean
'speichern einer Textdatei

   Dim FNr As Integer

   Msg = ""

   On Error Goto Fehler

   'freie Dateinummer zuweisen lassen
   FNr = FreeFile
   If Not doAppend Then
      'überschreiben Datei falls vorhanden
      Open TxtFile For Output As #FNr
   Else
      'anfügen an Datei falls vorhanden
      Open TxtFile For Append As #FNr
      'falls mit Text gefüllt
      If LOF(FNr) > 0 Then
         'Zeilentrenner einfügen       
     If WithCrLf Then
            Print #FNr, ""
         End If
      End If
   End If
   Print #FNr, Text1.Text;
   Close #FNr
   TextboxSaveToFile = True
   Exit Function

Fehler:
   Msg = "Fehler: " & Err.Number & vbCrLf & Err.Description
   TextboxSaveToFile = False
End Function

Listing 17

Funktion zum Einlesen einer Textdatei in eine Textbox [TextboxLoadFromFile]

Private Function TextboxLoadFromFile _
(Tbox As TextBox, TxtFile As String, _
Optional doBoxClear As Boolean = True, _
Optional Msg As String) As Boolean
'einlesen einer Textdatei in eine Textbox

   Dim FNr As Integer
   Dim zw As String

      Msg = ""
      TextboxLoadFromFile = False

      'prüfen ob Datei vorhanden
      If Dir(TxtFile) = "" Then
         Msg = "Datei '" & TxtFile & " nicht gefunden"
         Exit Function
      End If

      'Check auf Dateigrösse
      If FileLen(TxtFile) > 32767 Then
         Msg = "Datei '" & TxtFile & " zur gross für Textbox"
         Exit Function
      End If

      'Text in Textbox löschen
      If doBoxClear Then
         Tbox.Text = ""
      End If

      'Flackern vermindern
      Tbox.Visible = False
 
      On Error Goto Fehler

      FNr = FreeFile
      Open TxtFile For Binary As #FNr
      zw = Space(LOF(FNr))
      Get #FNr, , zw
      Tbox.SelText = zw
      Close #FNr
    
      Tbox.Visible = True
      TextboxLoadFromFile = True
      Exit Function

Fehler:
      Tbox.Visible = True
      Msg = "Fehler: " & Err.Number & vbCrLf & Err.Description
End Function

Listing 18

Beispiel: Speichern einer Textbox mit Überschreiben eines bestehenden Textes

Dim TxtFile As String 
Dim Msg As String 

'zuweisen Applicationpath und Filename 
TxtFile = AppPathGet & "TextBox.txt"

'speichern über Funktion 
If Not TextboxSaveToFile(Text1, TxtFile, , , Msg) Then 
   'Fehlermeldung 
   MsgBox Msg, , "Text speichern"
End If

Listing 19

Beispiel: Einlesen Textdatei in Textbox über Funktionen

Dim TxtFile As String 
Dim Msg As String 

'zuweisen Applicationpath und Filename 
TxtFile = AppPathGet & "TextBox.txt"
'einlesen über Funktion 
If Not TextboxLoadFromFile(Text1, TxtFile, , Msg) Then 
        'Fehlermeldung 
   MsgBox Msg, , "Text einlesen"
End If

Listing 20

Speichern von Listbox-Texten  

Die Eigenschaften der Listbox und der Combobox sind in Bezug auf die Datenhaltung weitgehend identisch. Die vorgestellten Methoden sind deshalb auf beide anwendbar.

MultiSelect Eigenschaften

Die Listbox bietet die Multiselect Eigenschaft. Es ist damit neben der kompletten Speicherung der Listboxdaten möglich, nur Teile zu speichern oder Teile davon auszusparen. Möglichkeiten zur Nutzung im Bereich Speichern sind in der Funktion ObjBoxSaveToFile beschrieben.

Die Eigenschaften List1.List (Index) List1.ListIndex

.List repräsentiert eine Aufzählung(Collection) von Texten innerhalb einer Listbox. Der .ListIndex verweist auf den aktuellen bzw. zuletzt ausgewählten Eintrag, eine Zahl zwischen 0 und der Anzahl der Eintragungen (ListCount -1). Bei ListIndex = -1 ist kein Eintrag ausgewählt.

Die Methode List1.AddItem Element, Index

Mit .AddItem werden Einträge in einer Listbox vorgenommen, Element repräsentiert hier den zu speichernden Text. Wird kein Index angegeben, wird der Eintrag am Ende angefügt.

Die Eigenschaften List1.ItemData (Index) List1.NewIndex

Neben der List-Eigenschaft zur Aufnahme von 1-zeiligen Texten bieten die Boxen die Datenhaltung eines nicht sichtbaren numerischen Wertes vom Typ Long pro Eintrag in der Liste ItemData. Dieser Wert kann als Index verwendet werden (z.B. bei Darstellung von Teilen eines Arrays), als Artikel-Nr, Preis etc..

Direkt nach Einfügen durch .AddItem liefert .NewIndex den Index (lfd. Nummer), unter dem der neue Eintrag vorgenommen wurde.

List1.AddItem Text2.Text
List1.ItemData(List1.NewIndex) = Val(Text3.Text)

Listing 21

Darstellung und Trennen von .List (Item) und .ItemData

In den vorgestellten Beispielen werden die Werte von .List und .ItemData zusammen in einer Zeile dargestellt. Damit diese Werte, einmal ein Text, einmal ein numerischer Wert vom Typ Long, beim Einlesen wieder getrennt werden können, muss ein Trennzeichen eingefügt werden.

Das Trennzeichen wird der Variablen TrZ zugewiesen, in den Beispielen das Zeichen |.

Speicherung Daten einer Box Eintrag für Eintrag

Hier wird Eintrag für Eintrag zusammen mit ItemData ausgelesen und in die Textdatei geschrieben. Der letzte Eintrag muss ohne CrLf geschrieben werden.

TrZ = "|"

FNr = FreeFile
Open TxtFile For Output As #FNr
'ListCount liefert Anzahl der Elemente 
'List wird aber ab 0 gezählt, deshalb ListCount - 1 
For i = 0 To List1.ListCount - 1
   If i < List1.ListCount - 1 Then 
      'mit CrLf schreiben 
      Print #FNr, List1.ItemData(i) & TrZ & List1.List(i)
   Else 
      'letzten Eintrag ohne CrLf schreiben 
      Print #FNr, List1.ItemData(i) & TrZ & List1.List(i);
   End If 
Next     
Close #FNr

Listing 22

Speichern einer Listbox über Array und Join

Bei dieser Methode wird ein (Zwischen)Array gebildet, das mit Join zu einem String konvertiert und auf einmal geschrieben wird. Als Trennzeichen für die einzelnen Zeichen wird über Join ein CrLf eingefügt. Dürfte den Durchsatz steigern.

TrZ = "|"

'Array dimensionieren und füllen 
ReDim wArray(List1.ListCount)
'ListCount liefert Anzahl der Elemente 
'List wird aber ab 0 gezählt, deshalb ListCount - 1 
For i = 0 To List1.ListCount - 1
   With List1
      wArray(i) = .ItemData(i) & TrZ & .List(i)
   End With 
Next 

FNr = FreeFile
Open TxtFile For Output As #FNr
'Array komplett schreiben, über Join einen String 
'aus den Elementen bilden getrennt durch CrLf 
If List1.ListCount > 0 Then 
   Print #FNr, Join(wArray, vbCrLf);
End If 
Close #FNr

Listing 23

Einlesen von Listbox-Texten  

Einlesen Zeile für Zeile

Die Textdatei wird Zeile für Zeile ausgelesen. Jede Zeile wird auf das Trennzeichen geprüft. Ist das Trennzeichen vorhanden, werden List und ItemData beschickt, sonst nur List.

TrZ = "|"

FNr = FreeFile
Open TxtFile For Input As #FNr
'auslesen bis zum Dateiende 
Do While Not EOF(FNr)
   'zeilenweise auslesen und übernehmen 
   Line Input #FNr, zw
   'Position des Trennzeichens 
   i = InStr(zw, TrZ)
   If i > 0 Then 
      'eintragen List(Item) und ItemData 
      List1.AddItem Mid(zw, i + 1)
      List1.ItemData(List1.NewIndex) = Left(zw, i - 1)
   Else 
      'eintragen nur List(Item) 
      List1.AddItem zw
   End If 
Loop 
Close #FNr

Listing 24

Einlesen komplett in Array und Übergabe an Listbox

Bei diesen Methoden wird die Textdatei komplett über Input oder Get ausgelesen, gesplittet in ein Array und von dort aus wird die Box beschickt. Die Methode mit Get ist die schnellste.

'die Variable wArray() muss definiert sein
Dim wArray() As String

TrZ = "|"

FNr = FreeFile
Open TxtFile For Input As #FNr
zw = Input(LOF(FNr), #FNr)
Close #FNr

'String in Array übernehmen
wArray = Split(zw, vbCrLf)

For i = LBound(wArray) To UBound(wArray)
   j = InStr(wArray(i), TrZ)
   If j > 0 Then
      'eintragen List(Item) und ItemData
      List1.AddItem Mid(wArray(i), j + 1)
      List1.ItemData(List1.NewIndex) = Left(wArray(i), j - 1)
   Else
      'eintragen nur List(Item)
      List1.AddItem wArray(i)
   End If
Next

Listing 25

Bei der Methode mit Get sind lediglich die folgenden Statements für den Dateizugriff zu wechseln

FNr = FreeFile
Open TxtFile For Binary As #FNr
zw = Space(LOF(FNr))
Get #FNr, , zw
Close #FNr

Listing 26

Funktionen für List- und Combobox  

Funktion zum Speichern der Daten einer List- oder Combobox in eine Textdatei

Private Function ObjBoxSaveToFile _
(objBox As Object, _
TxtFile As String, _
Optional TrZ As String = "|", _
Optional Flags As Integer = 0, _
Optional doAppend As Boolean = False, _
Optional Msg As String = "") As Boolean
'Inhalt einer Listbox oder Combobox in Textdatei schreiben
'Flags: NUR ListBox
'0 = Alle List(Items) schreiben
'1 = OnlySelected = alle ausgewählten Items
'4 = NotSelected  = alle nicht ausgewählten Items

   Dim FNr As Integer
   Dim i As Long
   Dim j As Long
   Dim TrZ As String
   Dim doIt As Boolean
   Dim wArray() As String

      ObjBoxSaveToFile = False
 
      'nur zugelassen Listbox und Combobox
      If Not TypeOf objBox Is ListBox And _
         Not TypeOf objBox Is ComboBox Then
         Msg = "Falscher Objekttyp"
         Exit Function
      End If
    
      'ListCount liefert Anzahl der Elemente
      'List wird aber ab 0 gezählt, deshalb ListCount - 1
      j = -1
      For i = 0 To objBox.ListCount - 1
            doIt = True
         'bei Listbox Flags abchecken
         If TypeOf objBox Is ListBox Then
            If (Flags And 1) = 1 Then
               'nur Selected Items
               If Not objBox.Selected(i) Then
                  doIt = False
               End If
            ElseIf (Flags And 4) = 4 Then
               'nicht Selected Items
               If objBox.Selected(i) Then
                  doIt = False
               End If
            End If
         End If
         If doIt Then
            j = j + 1
            'Array um 1 Element erhöhen
            ReDim Preserve wArray(j)
            With objBox
               If Len(TrZ) > 0 Then
                  wArray(j) = .ItemData(i) & TrZ & .List(i)
               Else
                  wArray(j) = .List(i)
               End If
            End With
         End If
      Next
 
      'Fehlerbehandlung
      On Error Goto Fehler
    
         'freie Dateinummer zuweisen lassen
      FNr = FreeFile
      If Not doAppend Then
         'überschreiben
         Open TxtFile For Output As #FNr
      Else
         'an bestehenden Inhalt anhängen
         Open TxtFile For Append As #FNr
         'ist Zieldatei belegt, Zeilentrenner anfügen
          If LOF(FNr) > 0 And objBox.ListCount > 0 Then
            Print #FNr, ""
         End If
      End If
      'Array komplett schreiben über Join einen String aus
      'den Elementen bilden getrennt durch CrLf
      If objBox.ListCount > 0 Then
         Print #FNr, Join(wArray, vbCrLf);
      End If
      Close #FNr
      ObjBoxSaveToFile = True
      Exit Function
 
Fehler:
      Msg = "Fehler: " & Err.Number & vbCrLf & Err.Description
End Function

Listing 27

Funktion zum Einlesen der Daten einer List- oder Combobox aus einer Textdatei

Private Function ObjBoxLoadFromFile _
(objBox As Object, _
TxtFile As String, _
Optional TrZ As String = "|", _
Optional doBoxClear As Boolean = True, _
Optional Msg As String = "") As Boolean 
'einlesen einer Textdatei in eine Listbox oder Combobox 

   Dim FNr As Integer 
   Dim i As Long 
   Dim j As Long 
   Dim zw As String 
   Dim wArray() As String     

      Msg = ""
      ObjBoxLoadFromFile = False 
 
      'nur Listbox und Combobox zulassen 
      If Not TypeOf objBox Is ListBox And _
         Not TypeOf objBox Is ComboBox Then 
         Msg = "Falscher Objekttyp"
         Exit Function 
      End If 

      'prüfen ob Datei vorhanden 
      If Dir(TxtFile) = "" Then 
         Msg = "Datei '" & TxtFile & " nicht gefunden"
         Exit Function 
      End If 

      'Listbox/Combo löschen 
      If doBoxClear Then 
         objBox.Clear
      End If 
 
      'Flackern vermindern 
      objBox.Visible = False 
 
      'Fehlerbehandlung 
      On Error Goto Fehler
 
      'freie Dateinummer zuweisen lassen 
      FNr = FreeFile
      Open TxtFile For Binary As #FNr
 
      'Datei komplett auslesen 
      zw = Space(LOF(FNr))
      Get #FNr, , zw
      Close #FNr
 
      'String in Array übernehmen 
      wArray = Split(zw, vbCrLf)
 
      For i = LBound(wArray) To UBound(wArray)
         j = InStr(wArray(i), TrZ)
         If j > 0 And Len(TrZ) > 0 Then 
            'eintragen List(Item) und ItemData 
            objBox.AddItem Mid(wArray(i), j + 1)
            objBox.ItemData(objBox.NewIndex) = Left(wArray(i), j - 1)
         Else 
            'eintragen nur List(Item) 
            objBox.AddItem wArray(i)
         End If     
      Next 
 
      objBox.Visible = True 
      ObjBoxLoadFromFile = True 
      Exit Function 
 
Fehler:
      objBox.Visible = True 
      Msg = "Fehler: " & Err.Number & vbCrLf & Err.Description
End Function

Listing 28

Beispiele für den Aufruf der Funktionen

Speichern der Daten einer List- oder Combobox in einer Textdatei

'Inhalt Listbox in Textfile schreiben über Funktion 
 
Dim TxtFile As String 
Dim Msg As String 
 
TxtFile = AppPathGet & "Listbox.txt"
    
If Not ObjBoxSaveToFile(List1, TxtFile, , , , Msg) Then 
   MsgBox Msg, , "Listbox schreiben"
End If 
End Sub

Listing 29

Einlesen der Daten einer List- oder Combobox aus einer Textdatei

'Textfile in Listbox über Funktion einlesen 

Dim TxtFile As String 
Dim Msg As String 
 
TxtFile = AppPathGet & "Listbox.txt"
 
If Not ObjBoxLoadFromFile(List1, TxtFile, , , Msg) Then 
   MsgBox Msg, , "Listbox einlesen"
End If

Listing 30

Speichern von String-Arrays  

1-dimensionales Array

Das Speichern von 1-dimensionalen Array ist vom Prinzip her schon in vorigen Beispielen vorgestellt worden. Das Array wird über die Funktion Join zu einem String zusammengebunden, wobei die Elemente des Arrays durch einen CrLf getrennt werden.

Der Stringinhalt wird über die Print Anweisung gefolgt von einem Strichpunkt in die Datei geschrieben, dadurch wird eine Leerzeile vermieden.

Open TxtFile For Output As #FNr
  Print #FNr, Join(myArray, vbCrLf);
Close #FNr

Listing 31

2-dimensionales Array

Die Join Anweisung ist nur bei einem 1-dimensionalen Array anwendbar, bei einem 2-dimensionalen Array wird deshalb über ein 1-dimensionales Workarray gearbeitet. Die vorgestellten Methoden beziehen sich auf das Muster einer Adressverwaltung im Projekt.

Dimensioniert werden in der 1. Dimension 7 Elemente, in der 2. Dimension läuft der Zähler (Index).

0: Löschkennzeichen
1: Name
2: Vorname etc bis 6: Telefon

Dim AdrArray() As String 
Private Sub Form_Load()
    
   ReDim AdrArray(6, 0)
End Sub

Listing 32

Bei neuen Adressen wird das Array über die Anweisung Redim Preserve um ein Element erweitert.

'1 Element anfügen 
i = UBound(AdrArray, 2) + 1
ReDim Preserve AdrArray(UBound(AdrArray), i)

Listing 33

Anzahl der Elemente

Im ersten Schritt muss die Anzahl der zu schreibenden Elemente ermittel werden. Wenn kein Löschkennzeichen (-1) im Element 0 der 1. Dimension hinterliegt ist, kann die Adresse geschrieben werden.

Dim AnzPut As Long 

For i = 1 To UBound(AdrArray, 2)
   If Val(AdrArray(0, i)) = 0 Then 
      AnzPut = AnzPut + 1
   End If 
Next

Listing 34

Übertragen in ein 1.dimensionales Workarray

Es wird ein Workarray in der benötigten Grösse angelegt, wobei das 1. Element den Index 0 hat.

Das Adressarray wird in der 2. Dimension ab dem Element 1 bis zum Ende durchlaufen. Ist eine Adresse zu speichern, werden die Nutzelemente der Dimension 1 ab Element 1 in einen String gepackt und durch ein Trennzeichen getrennt. Dieser String wird an das Workarray übergeben.

Dim w() As String 
Dim zw As String 
Dim TrZ As String 
Dim i As Long 
Dim j As Long 

TrZ = "|"

'Array anlegen 
ReDim w(AnzPut - 1)
AnzPut = 0
For i = 1 To UBound(AdrArray, 2)    
   If Val(AdrArray(0, i)) = 0 Then 
      'Adresse in String mit Trennzeichen 
      zw = AdrArray(1, i)
      For j = 2 To UBound(AdrArray, 1)
         zw = zw & TrZ & AdrArray(j, i)
      Next 
      'String in Array stellen 
      AnzPut = AnzPut + 1
      w(AnzPut - 1) = zw
   End If 
Next

Listing 35

Schreiben in Textdatei

Das Workarray kann jetzt ganz normal geschrieben werden.

Open TxtFile For Output As #FNr
If AnzPut > 0 Then 
   'Array zu einem String verbinden und schreiben 
   Print #FNr, Join(w(), vbCrLf);
End If 
Close #FNr

Listing 36

Einlesen von String-Arrays  

Einlesen der Textdatei in eine Zwischenvariable

Dim zw As String 
 
Open TxtFile For Binary As #FNr
zw = Space(LOF(FNr))
Get #FNr, , zw
Close #FNr

Listing 37

Übernahme in Array

Im ersten Schritt wird das Adressarray in der 2. Dimension auf die Größe 0 redimensioniert. Wenn Nutzdaten gelesen werden konnten, erfolgt über einen Split die Aufteilung in ein 1-dimensionales Workarray.

Jetzt ist bekannt, wieviele Adressen eingelesen wurden und das Adressarray kann endgültig redimensioniert werden.

In einer Schleife wird das Workarray abgearbeitet. Jedes Element wird über ein weiteres Workarray in die Elemente der 1. Dimension des Adressarrays gesplittet und dahin übertragen.

Beziehung zwischen Array und Listbox herstellen

Parallel dazu werden (in dem Beispiel) die Nutzelemente 1 und 2 (Name, Vorname) per AddItem in eine Listbox eingetragen. Da diese Listbox die Eigenschaft Sorted=True hat, muss eine Beziehung zwischen Adressarray und Listbox hergestellt werden. Das erfolgt über das Datenfeld ItemData der Listbox, bei dem für jeden Eintrag die Index- oder Zählnummer der 2. Dimension des Arrays eingestellt wird.

Dim w() As String 
Dim w1() As String 
 
ReDim AdrArray(UBound(AdrArray), 0)
 
If Len(zw) > 0 Then 
   w() = Split(zw, vbCrLf)
   ReDim AdrArray(UBound(AdrArray), UBound(w) + 1)
   For i = 0 To UBound(w)
      w1() = Split(w(i), TrZ)    
      For j = 0 To UBound(w1)
         AdrArray(j + 1, i + 1) = w1(j)
      Next 
      List2.AddItem AdrArray(1, i + 1) & ", " & AdrArray(2, i + 1)
      List2.ItemData(List2.NewIndex) = i + 1
   Next 
End If

Listing 38

Schlußwort  

Mit Hilfe des vorliegenden Tutorials sollten Sie in der Lage sein, Daten aus Textboxen, List- und Comboboxen oder aus Arrays in Dateien zu speichern und aus diesen wieder auszulesen.

Tutorial und Beispielprojekt als Download [32900 Bytes]

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Frage zum Einlesen - Detlef 26.08.12 18:34 7 Antworten