German CSV Datei lesen und an Variablen übergeben

pjo12345

Active Member
Licensed User
Hallo!

Brauche mal wieder eure Hilfe.

Ich möchte eine CSV Datei lesen und die gelesenen Daten an ein String Array übergeben. Die CSV Datei hat das Format:

aaa,1
bbb,2
ccc,3

Diese Werte möchte ich Zeile für Zeile an Variablen übergeben. So das es zum Schluss so aussieht:

X(0) = aaa
Y(0) = 1

X(1) = bbb
Y(1) = 2

X(2) = ccc
Y(2) = 3

Ich komme da nicht weiter. Egal wie ich es anstelle, meine Variablen enthalten nur [Ljava.lang.String;@52a738f8 oder so ähnlich.

Danke schon mal....
 

klaus

Expert
Licensed User
Du hättest deinen Code mit einer Testdatei senden sollen damit wir sehen können was Du wie gemacht hast und wie die Datei gespeichert ist !

Das könnte so aussehen:
B4X:
Sub Process_Globals
   Dim FilePath = File.DirAssets As String
   Dim FileName = "test.csv" As String
   Dim X(10), Y(10) As String
End Sub

Sub Activity_Create(FirstTime As Boolean)
   LoadCSV(FilePath, FileName)
End Sub

Sub LoadCSV(FPath As String, FName As String)
    Dim txt, lines(), str(2)As String
    txt = File.ReadString(FPath, FName)
     lines = Regex.Split(Chr(13) & Chr(10), txt)
    Dim X(lines.Length), Y(lines.Length) As String
    Dim i As Int
     For i = 0 To lines.Length - 1
        str = Regex.Split(",", lines(i))
        X(i) = str(0)
        Y(i) = str(1)
    Next
End Sub
Chr(10) ist vielleicht nicht nötig.
Die Routine nimmt an dass die Datei in UTF-8 gespeichert ist.
Ansonsten muss man dann noch txt umwandeln.
 

pjo12345

Active Member
Licensed User
Eigentlich dachte ich, dass man das mit Stringutils und Loadcsv macht. Was spricht dagegen? Lesen wollte ich die Datei dann so:
B4X:
Sub CSV_lesen
    Dim k As Int
    Dim i As Int
    Liste=su.LoadCSV(File.DirAssets,"test.csv",",")
    For i = 0 To Liste.Size-1
        x(i)=Liste.Get(k)
        y(i)=Liste.Get(k+1)
        Log(x(i))
        Log(y(i))
        k=k+2
    Next
End Sub
Aber da kommt nur Müll zu Stande.

Anbei mal meine csv Datei.
 

Attachments

klaus

Expert
Licensed User
Eigentlich dachte ich, dass man das mit Stringutils und Loadcsv macht. Was spricht dagegen?
Nichts ! Ich erinnerte mich nicht mehr an die LoadCSV Funktion in StringUtils.

Ich befürchte dass Du die Dokumentation nicht richtig gelesen hast!
LoadCSV: Loads a CSV file and stores it in a list of string arrays.
Das heisst jeder Eintag in Liste ist ein String Array mit allen Zellen in der Zeile !
Ich überlasse es dir deinen Code dem nach zu ändern.
 

peternmb

Active Member
Licensed User
Hallo,

für was benötigst du LoadCSV?

Ich arbeite viel mit CSV-Dateien, bei mir sind die i.d.R. mit Strichpunkt separiert - dann siehst das so aus:
B4X:
List = File.readlist(AppDir,"text.csv")
For i = 0 To List.Size-1
   str_array = List.Get(i)                
   arr_zeile = Regex.Split(";",str_array)
   '
   ' hier kannst du die Elemente jeder Zeile auswerten und an deine Variablen übergeben
   ' die einzelnen Elemente sind dann z.B. arr_zeile(3) oder arr_zeile(4)
   '
Next
 

arnold steger

Member
Licensed User
Ich probierte es mit csv und jetzt auch mit txt.
Schon sobald listtemp.Get die einzelnen Zeichen einliesst steht � anstatt der Umlaute.

B4X:
        Dim ZeitView As ListView
Dim listtemp,ZeitListe As List
        Dim Zeit(3),Stri As String
        listtemp = File.readlist(File.DirInternal,"data_Zeit.txt")
        For i = 0 To listtemp.Size-1
  ZeitListe = listtemp.Get(i)
        Zeit = Regex.Split(";",ZeitListe)
        ZeitView.AddTwoLines(Zeit(0),Zeit(1)&" bis "&Zeit(2))
        Next
Woran kanns liegen?
Weiters habe ich noch "(String)" vor Zeit(0) stehen.
 

Attachments

klaus

Expert
Licensed User
Das Problem ist, wie DonManfred es schon gesagt hat, das Encoding !
Deine Datei ist mit ANSI Encoding gespeichert !
Du musst sie mit UTF-8 Encoding speichern.
Das kannst Du entweder mit NotePad machen oder besser mit NotePad+.
In NotePad+ kannst Du die Datei im Menü Encoding mit Convert to UTF-8 without BOM konvertieren.
BOM (Byte Order Mark) sind drei Bytes die am Anfang an die UTF-8 Datei hinzugefügt werden, siehe HIER.
Mit der Konvertierung Convert to UTF-8 without BOM werden dies nicht hinzugefügt.
 

arnold steger

Member
Licensed User
danke, das war mein Problem.
Nur habe ich noch am Anfang meines Textes "(String)" stehen.
Hängt anscheinend nicht mit dem Format zusammen.
 

klaus

Expert
Licensed User
Nur habe ich noch am Anfang meines Textes "(String)" stehen.
Wo hast Du ein String ?
In deiner Textdatei ist kein 'String' drin, das muss von wo anders her kommen.
Ich habe das getestet bevor Ich die Lösung gesendet habe !
Und ohne deinen kompletten Code zu sehen ist es unmöglich eine konkrete Antwort zu geben.
 

arnold steger

Member
Licensed User
ZeitListe = listtemp.Get(i)
hier ist der Datensatz noch richtig.

Zeit = Regex.Split(";",ZeitListe)
nach dieser Zeile steht '(String)' vorne dran.
 

Attachments

DonManfred

Expert
Licensed User
Du liest die Zeile einer Datei (die eigentlich mit regex gesplittet werden sollte) erst nochmal in eine list rein. Das ist falsch.
Hier eine angepasste version

B4X:
    Dim listtemp As List
    listtemp = File.readlist(ruta,"data_Zeit.txt")
    For i = 0 To listtemp.Size-1
        Dim Zeit() As String = Regex.Split(";",listtemp.Get(i))
        ZeitView.AddTwoLines(Zeit(0),Zeit(1)&" bis "&Zeit(2))
    Next
 

arnold steger

Member
Licensed User
ich möchte noch die Bezeichnung in der ersten Zeile grün anzeigen wenn das aktuelle Datum im bereich der importierten Zeit(1) und Zeit(2) liegt.
wegen verschiedener formate funktioniert dieser code nicht. gibt es eine andere möglichkeit für meine auswertung?
B4X:
Dim listtemp As List
Dim label1 As Label
Dim tagHeute,tagBeginn,tagEnde As Long
DateTime.DateFormat="dd.MM.yyyy"
tagHeute=DateTime.GetDayOfYear(DateTime.Now)
    listtemp = File.readlist(ruta,"data_Zeit.txt")
    For i = 0 To listtemp.Size-1
        Dim Zeit() As String = Regex.Split(";",listtemp.Get(i))
                                tagBeginn=DateTime.GetDayOfYear(Zeit(1))
                                tagEnde=DateTime.GetDayOfYear(Zeit(2))
                               
                        If tagHeute > tagBeginn AND tagHeute < tagEnde Then
                                label1 = ZeitView.TwoLinesLayout.Label
                                label1.TextColor = Colors.Green
                                label1.Gravity = Gravity.LEFT
        ZeitView.AddTwoLines(Zeit(0),Zeit(1)&" bis "&Zeit(2))
                        Else
                                label1 = ZeitView.TwoLinesLayout.Label
                                label1.TextColor = Colors.LightGray
                                label1.Gravity = Gravity.LEFT
        ZeitView.AddTwoLines(Zeit(0),Zeit(1)&" bis "&Zeit(2))
                        End If
    Next
 

DonManfred

Expert
Licensed User
Mit Listview bekommste das nicht hin.
Listview bitetet dir drei Designmöglichkeiten
- Singleline
- Twolines
- Twolinesandbitmap

Dabei gilt: Du kannst immer nur ALLE Items einer Sorte mit einem bestimmten Layout versehen.

Sprich: Ein Twolines layout mit einer roten Firstline und einer Gelben Secondline hat also immer diese Farben. Dann kannst du nicht "per item" verändern.

Abhilfe hilft dir hier nur ein CustomListView. Bei einem CLV kannst Du jedem Item ein anderes Layout verpassen wenn du magst; ist jedoch (zumindest am Anfang) ein bisschen komplizierter in der Anwendung.
 

arnold steger

Member
Licensed User
Hast du für die Auswertung des Datums mit den verschiedenen Formaten Long und String auch einen Tipp?
Weiters habe ich noch bedenken wenn ich bei GetDayOfYear ein Datum des nächsten Jahres stehen habe müsste ich irgendwie noch die 365 dazu addieren.
Ist nicht ganz eine saubere Lösung, müsste aber so ungefähr funktionieren.
 

DonManfred

Expert
Licensed User
Hast du für die Auswertung des Datums mit den verschiedenen Formaten Long und String auch einen Tipp?
Was genau willst Du realisieren? Ein paar Beispiele was deine Quelldaten sind und was du damit anstellen willst um dann ein bestimmtes Ergebnis zu erhalten wäre sinnvoll.

Bei einer konkreten Fragestellung ist es einfacher zu antworten.
 

arnold steger

Member
Licensed User
Für jede Zeile wird eine Beschreibung, DatumBeginn und DatumEnde aus der Datei eingelesen.
Wenn ich mich mit den heutigen Datum innerhalb des Zeitraums Beginn und Ende befinde soll die im CustomListView dazugefügten Zeile grün sein,
die übrigen sollen grau erscheinen.
In meinem beispiel müssten alle grau erscheinen. vom 1.5.2015 bis zum 2.5.2015 wäre die fünfte Zeile grün.
 

DonManfred

Expert
Licensed User
B4X:
    DateTime.DateFormat = "dd.MM.yyyy"
    DateTime.TimeFormat = "HH:mm"
    Dim dstart As Long = DateTime.DateTimeParse("01.5.2015","00:00")
    Dim dende As Long = DateTime.DateTimeParse("02.5.2015","23:59")
    Dim heute As Long = DateTime.Now
    If heute >= dstart AND heute <= dende Then
        Log("Heute ist 'im Bereich': -> GRÜN")
    Else
        Log("Heute ist nicht 'im Bereich': -> GRAU")
    End If
PS: Wenn ein Post hier im Forum hilfreich für Dich ist dann ist es üblich das man die Bemühungen des helfenden mit einem "Like" belohnt wenn die Antwort hilfreich war ;)
 
Last edited:
Top