VB6 - Datei auslesen

Daniel5

Grünschnabel
Hi, ich habe eine spiele-datei die solch einen Aufbau aufweißt-

Beispiel:
name alter punktestand datum
Tom # 22 # 2500 # 30.09.2006

max. 10 Einträge (Top 10)
Die Datei ist eine Textdatei mit dat-Endung


Das ganze soll jetzt in VB6 eingelesen werden und in dynamischen textfelder ausgegeben werden...jedenfalls soll das geändert werden können und wieder in die datei zurück geschrieben werden.
Ich dachte textfelder (max. 40 Stück) eigenen sich dafür am besten, oder geht das mit einem anderen besser?

Das problem an der sache ist ich kann die datei am stück einlesen aber damit komm ich nicht weiter, das muss ja alles in die textfelder rein.

Hat jemand ein tipp oder ein beispiel für mich...
Bis denne!
 
Hi,

auslesen geht mit
Code:
' form 1'
Private Type TData
    sName As String
    nOlder As Integer
    sPoints As Integer
    dDate As Date
End Type


Private Function GetDataFromFile(ByVal sFile As String, _
                            Optional ByVal sDelimeter As String = "#" _
) As TData()
    
    Dim FNr         As Integer
    Dim i           As Long
    Dim s           As String
    Dim sTmp()      As String
    Dim udtData()   As TData
    
    FNr = FreeFile
    
    Open sFile For Input As #FNr
    i = 0
    ReDim udtData(i)
    While Not EOF(FNr)
        
        Line Input #FNr, s
        ReDim Preserve udtData(i)
        sTmp() = Split(s, sDelimeter)
        With udtData(UBound(udtData))
            .sName = sTmp(0)
            .nOlder = sTmp(1)
            .sPoints = sTmp(2)
            .dDate = sTmp(3)
        End With
        i = i + 1
    Wend
    Close #FNr
    GetDataFromFile = udtData
End Function

Ich würde
- die Daten in einem ListView darstellen (MSComLibControls)
- bei Click auf ein Item die Daten in 4 Textfelder schreiben
- Change Event der Textbox nutzen um ggf. Änderung zu erfahren
- entsprechende Zeile in Datei updaten

Datei lesen, schreiben etc.:
Umgang mit Textdateien
 
Hi DevHB

Ich hab mich in dem script irgendwie verfahren, das ist etwas zu kompliziert für mich, ich kann dem garnicht so recht folgen!

Ich hab nun versucht eine list1 einzufügen, das klappt soweit, aber da kommt nur der erste eintrag der datei und dann: index ausserhalb des gültigen Bereichs

Die ListView bekomm ich erst garnicht zum laufe, die hab ich noch nie benutzt.
Ich bin in vb6 noch ziemlich am Anfang.

Dein Script sieht jetzt so aus:

Code:
Option Explicit
'Dateibeispiel:
'Tom|22|2500|30.09.2006
'Peter|26|2100|17.09.2006
'Klaus|17|1500|12.09.2006
'Tim|22|1900|28.09.2006
'Tom|22|3200|30.09.2006

Private Type TData
  sName As String
  nOlder As Integer
  sPoints As Integer
  dDate As Date
End Type

Private Function GetDataFromFile(ByVal sFile As String, _
  Optional ByVal sDelimeter As String = "|") As TData()
  
  Dim FNr        As Integer
  Dim i          As Long
  Dim s          As String
  Dim sTmp()     As String
  Dim udtData()  As TData
    
  FNr = FreeFile
  Open sFile For Input As #FNr
  i = 0
  ReDim udtData(i)
  
  While Not EOF(FNr)
    Line Input #FNr, s
    ReDim Preserve udtData(i)
    sTmp() = Split(s, sDelimeter)
    With udtData(UBound(udtData))
      .sName = sTmp(0)
      .nOlder = sTmp(1)
      .sPoints = sTmp(2)
      .dDate = sTmp(3)
    End With
    i = i + 1
  Wend
  Close #FNr
  
  '''''''''''''''''''''''''''''''
  'Wafür ist diese Zeile hier?
  GetDataFromFile = udtData
  '''''''''''''''''''''''''''''''
  
  List1.Clear
  For i = 0 To UBound(udtData)
    List1.AddItem sTmp(i)
    'List1.AddItem sOlder(i)
    'List1.AddItem sPoints(i)
    'List1.AddItem sDate(i)
    
    'ListView1.ListItems sTmp(i)
  Next
End Function


Private Sub Command1_Click()
  Call GetDataFromFile(App.Path + "\test1.txt", "|")
End Sub

das ist ja komplizierter als ich das dachte!
 
Hi,

das ist eine Funktion, die ein Array vom Typ "TData" zurückliefert.
Also wäre die Anwendung folgendermaßen:

Code:
Option Explicit
'Dateibeispiel:
'Tom|22|2500|30.09.2006
'Peter|26|2100|17.09.2006
'Klaus|17|1500|12.09.2006
'Tim|22|1900|28.09.2006
'Tom|22|3200|30.09.2006

Private Type TData
  sName As String
  nOlder As Integer
  sPoints As Integer
  dDate As Date
End Type

Private Function GetDataFromFile(ByVal sFile As String, _
  Optional ByVal sDelimeter As String = "|") As TData()
  
  Dim FNr        As Integer
  Dim i          As Long
  Dim s          As String
  Dim sTmp()     As String
  Dim udtData()  As TData
    
  FNr = FreeFile
  Open sFile For Input As #FNr
  i = 0
  ReDim udtData(i)
  
  While Not EOF(FNr)
    Line Input #FNr, s
    ReDim Preserve udtData(i)
    sTmp() = Split(s, sDelimeter)
    With udtData(UBound(udtData))
      .sName = sTmp(0)
      .nOlder = sTmp(1)
      .sPoints = sTmp(2)
      .dDate = sTmp(3)
    End With
    i = i + 1
  Wend
  Close #FNr
  
' --> Hier wird der Rückgabewert gesetzt
  GetDataFromFile = udtData

End Function


Private Sub Command1_Click()
'  Call GetDataFromFile(App.Path + "\test1.txt", "|")
   ' zum verketten von Strings in VB nimmt man das & - Zeichen
   ' ansonsten ist es eine Addition von 2 Strings, das kann zu Fehlern führen
   Dim udtData() As TData
   udtData = GetDataFromFile(App.Path & "\test1.txt", "|")

   Call FillListView(Listview1, udtData)
End Sub

Private Sub FillListView(ByVal oListview As listview, _
                         ByRef udtData() As TData _
)
    
    Dim i   As Long
    Dim LI  As ListItem
    
    With oListview
        
        .Visible = False
        .View = lvwReport
        .Checkboxes = False
        .Sorted = False
        ' list löschen
        Call .ListItems.Clear
        Call .ColumnHeaders.Clear
        
        ' spaltenüberschriften
        Call .ColumnHeaders.Add(, , "Name", 1500)
        Call .ColumnHeaders.Add(, , "Alter", 1500, lvwColumnCenter)
        Call .ColumnHeaders.Add(, , "Punkte", 1500, lvwColumnCenter)
        Call .ColumnHeaders.Add(, , "Datum", 1500, lvwColumnCenter)
        
        ' Array durchlaufen, liste füllen
        For i = LBound(udtData) To UBound(udtData)
            ' 1. Item = LI
            Set LI = .ListItems.Add(, i & "x", udtData(i).sName)
            ' subitems fangen ab 1 an!
            LI.SubItems(1) = udtData(i).nOlder
            LI.SubItems(2) = udtData(i).sPoints
            LI.SubItems(3) = udtData(i).dDate
        Next i
        
        .Visible = True
    End With
End Sub

Das ListView ist bei den "MS Common Controls dabei" (STRG+T für Komponenten, dann suchen ;-) ).
 
DevHB

Mann, das ist ja komplizierter als ich dachte! Das muss ich erstmal durchstudieren wen das soweit fertig ist.
Die ListView hab ich schon mal gefunden, ich hab ihr jetzt eine Schriftart verpasst:

With oListview
.Font = "courier new"

Schriftgröße gibt es da allerdings nicht
.FontSize = ungültige Eigenschaft

Trotz den 4 Spalten hat die ListView 5 Spalten, die letzte ist leer...egal wie lange ich die form in die Breite ziehe, die ListView hört ja nie auf!


Ok DevHB dann bedanke ich mich erstmal für die klasse Arbeit!
Mit dem Ändern und zurückschreiben wird das so wohl nichts, ich lass mit das nochmal in einer normalen List1 anzeigen und ändere das dort - die ListView ist für mich Neuland.

Frage: Die Spaltennamen oben kann man die zu was gebrauchen? ZumBeispiel wenn man draufklickt das das die sName sortiert6 werden oder sind die nur zur Oprischen Schönhaeit da?

Vielen Dank nochmal, hast mir viel geholfen!
 
Hi,

Font im ListView:

Code:
    With oListview
        
        .Visible = False
        .View = lvwReport
        .Checkboxes = False
        .Sorted = False
        
       ' entweder
        With .Font
            .Size = 14
            .Name = "Arial"
            .Bold = True
            .Italic = True
            .Underline = True
        End With
        
        ' oder die lange Variante
        .Font.Size = 14 'usw...
    End With

5 Statt 4 Spalten
Das ist normal, das ist die nicht verwendete Spalte, die ist immer da, kann man nix gegen machen.

Änderungen
Die Änderungen machst Du in den Textboxen, schreibst das in die entsprechende Zeile und rufst dann einfach nochmal die Funktion "FillListView" auf, dann sind die Änderungen (neu aus der Datei gelesen) im ListView.

Spaltennamen/ Sortierung
Das ListView kann standardmäßig nur alphanumerisch sortieren, bei Zahlen und Datum kommt nur Müll raus, bei Bedarf kann ich Dir eine Funktion dafür geben.

Standardsortierung des ListViews verwenden:
Code:
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
    
    With ListView1
        If (ListView1.SortOrder = lvwAscending) Then
            ' absteigend
            .SortOrder = lvwDescending
            
        Else
            ' aufsteigend
            
            .SortOrder = lvwAscending
            
        End If
        .Sorted = True
    End With
End Sub
 
Hallo DevHB

Das hat soweit alles funktioniert.

Bei der sortierung ist es so das immer nur die erste spalte sortiert wird, selbst wenn man eine andere spalte klickt, ist das so gewollt?

Ich hab mir gedacht, die listview ist ja schön und gut, aber ausser dem optischen aspekt bringt die ja nicht viel!
Dann könnte ich das ja gleich in textboxen ausgeben lassen - die kann ich dann gleich anklicken und den inhalt ändern.

Ich hab mich da drann versucht, aber da kommt nichts gescheites raus.
Zu testzwecken hab ich mir das hier aufgebaut:

Code:
Private Sub Form_Load()
  Dim tIndex As Long
  Dim i As Integer, j As Integer
  
  
'For j = 0 To UBound(udtData)
  'For i = LBound(udtData) To UBound(udtData)
For j = 1 To 3
  For i = 1 To 3
 
   tIndex = tIndex + 1
    Load txt1(tIndex)
    txt1(tIndex).Left = txt1(0).Left + txt1(0).Width * (tIndex) - 16 * (tIndex)
    txt1(tIndex).Text = "Text1(" & Trim$(tIndex) & ")"
    txt1(tIndex).Visible = True

  Next i
Next j

End Sub

Damit sollen soviel textboxen pro zeile erstellt werden wie auch spalten in der textdatei drin sind und auch soviel reihen wie die textdatei enthällt......naja, das klappt aber
nicht, ich bekomm das bereits ohne inhalt schon nicht zum laufen!

Kannst du mir da weiterhelfen? Ich denke das nennt sich steuerelemente in echtzeit erstellen.
 
Hallo...

Das script sollte zählen wieviele zeilen die datei enthällt und auch wieviele spalten jede zeile enthält (trennzeichen ist = |).

Daraus soll für jede spalte eine textbox generiert werden, nach jedem zeilenende soll ein zeilenumbruch gemacht werden und dann für die nächste zeile alle erforderlichen spalten generiert werden.

Das letzt script von mir macht eine zeile von textboxen und dann bereits keinen zeilenumbruch - kanns auch nicht, ich hab keine ahnung wie ich den zeilenumbruch machen soll. Normalerweise macht man das mit vbCrLf.
Ich hab das erst mal mit 2 for-schleifen machen möchten um zu sehen ob erst mal die textboxen alle generiert werden - ja und da happerts schon.

Das letzte script von DevHB funktioniert super mit einer ListView, die bringt mir aber wenig, da man dort nichts auf die schnelle ändern kann, deshalb möchte ich die weglassen und den gesamten arrayinhalt in textboxen erzeugen, dann kann man das ja sofort editieren und danach speichern.

Jetzt sollte das verständlich sein, ansonsten kann ich alles nochmal posten.
Danke erstamal
 
Hi,

das mit den Textboxen widerspricht jeglicher Softwarequalität.
Wer hat den Lust, die Boxen nach dem entspr. Eintrag zu durchsuchen?
Aber wenn Du es so haben willst:

Code:
' 4 Textboxen auf eine Form, jeweils Index= 0
' txtSpalte1, txtSpalte2, txtSpalte3, txtSpalte4, 
Private Sub LoadTxtBoxes(ByRef udtData() As TData)
    Dim i       As Long
    
    udtData = GetDataFromFile(App.Path & "\Text.dat", "|")
    
    For i = LBound(udtData) To UBound(udtData)
        If (i = 0) Then
            txtSpalte1(i).Text = udtData(i).sName
            txtSpalte2(i).Text = udtData(i).nOlder
            txtSpalte3(i).Text = udtData(i).dDate
            txtSpalte4(i).Text = udtData(i).sPoints
        Else
        
            Call Load(txtSpalte1(i))
            With txtSpalte1(i)
                .Left = txtSpalte1(i - 1).Left
                .Top = txtSpalte1(i - 1).Top + .Height + 50
                
                .Text = udtData(i).sName
                
                .Visible = True
            End With
            Call Load(txtSpalte2(i))
            With txtSpalte2(i)
                .Left = txtSpalte2(i - 1).Left
                .Top = txtSpalte2(i - 1).Top + .Height + 50
                .Text = udtData(i).nOlder
                .Visible = True
            End With
            Call Load(txtSpalte3(i))
            With txtSpalte3(i)
                .Left = txtSpalte3(i - 1).Left
                .Top = txtSpalte3(i - 1).Top + .Height + 50
                .Text = udtData(i).dDate
                .Visible = True
            End With
            Call Load(txtSpalte4(i))
            With txtSpalte4(i)
                .Left = txtSpalte4(i - 1).Left
                .Top = txtSpalte4(i - 1).Top + .Height + 50
                .Text = udtData(i).sPoints
                .Visible = True
            End With
            
        End If
        
    Next i
  
End Sub
 
Zurück