Buchempfehlung
MySQL kurz & gut
MySQL kurz & gut
Das preiswerte Taschen- buch stellt MySQL-rele- vante Inhalte systematisch und knapp dar, sodass es sich optimal zum Nach- schlagen beim Pro- grammieren eignet. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Datenbanken

CSVLoader

Lizenz:Erster Autor:Letzte Bearbeitung:
FBPSLMitgliedchutullu 05.12.2009

CSVLoader - Version 1.

dieses kleine Programm lädt komplette CSV-Datei mit konstanter Spalten bzw. Zeilenanzahl in ein eindimmensionales
StringArray.

Die Adressierung erfolgt über aktuelle Zeile * max Spaltenanzahl + aktuelle Spalte und der Speicher des Arrays
berechnet ganz einfach nach : max. Spaltenzahl * max. Zeilenanzahl .

Es findet keine Dateiprüfung nach Existenz oder Inhalt statt ! Sollte in eigenen Projekten beachtet werden.

CSVLoader - Version 2.

Aus performanten Gründen habe ich den Loader komplett überarbeitet. Datenstrukur nur durch Speicher begrenzt, ansonsten sehr schnell. Weiterhin können die einzelnen Zeilen unterschiedlich lang sein, keine feste CSV(y*x) Struktur mehrnotwendig.

CODE Version 1.

/'
  (c) 2009 chutullu (chutullu2(at)yahoo(dot)de) / FreeBASIC-Portal.de
  
  stringSplit - benötigt stringSplit.bi
  
  Version .1
  
  CSVLoader   Datentype
  
  CSVLoader   Objekt
    * Version    - Kennung
    * filename   - Dateiname
    * seperator  - Trennzeichen
    * filelength - Zeilenanzahl der Datei
    * CSVlength  - Länge der Zeile
    - init(filename, seperator) - alles initialisieren
    - countlines                - Zeilen zählen
    - loadCSV (arrayString())   - lädt CSV in Array
    + [integer] = getFileLength - gibt die Zeilenanzahl der Datei zurück
    + [integer] = getCSVLength  - gibt Spaltenzahl der Datei zurück
'/

Type CSVLoader

  Version    As Double = 0.1
  filename   As String
  seperator  As String * 1
  filelength As Integer
  CSVlength  As Integer

  Declare Sub init (ByVal filename As String, ByVal seperator As String)
  Declare Sub countLines ()
  Declare Sub loadCSV (strlst() As String)

  Declare Function getFileLength () As Integer
  Declare Function getCSVLength  () As Integer

End Type

Sub CSVLoader.init (ByVal filename As String, ByVal seperator As String)
  /'
    Aufruf    : obj.init (filename,seperator)
    Ergebnis  : speichert Dateiname + Seperator, zählt Spalten
    Variablen : filename-Dateiname;sperator-Trennzeichen
  '/

  This.filename  = filename
  This.seperator = seperator
  This.countLines()
End Sub
Sub CSVLoader.countLines ()
  /'
    Aufruf    : obj.countLines
    Ergenis   : zählt "klassisch" Zeilen einer Textdatei (d.h. Zeile für Zeile);
                bestimmt weiterhin die Spaltenzahl der Datei
    Variablen : f-nächste freie Dateinummer;dummy-DummyString;csvLine-stringSplit Objekt
                this.filelenght-Anzahl der Zeilen,this.CSVlength-Zeilenanzahl
  '/

  Dim f       As Integer
  Dim dummy   As String
  Dim csvLine As splitString

  f               = FreeFile
  This.filelength = 0

  Open This.filename For Input As #f
    Do: This.filelength+= 1
        Line Input #f, dummy
    Loop Until Eof(f)
  Close #f

  csvLine.spl (dummy,This.seperator)
  This.CSVlength = csvLine.items

End Sub
Sub CSVLoader.loadCSV (strlst() As String)
  /'
    Aufruf    : obj.loadCSV (arrayString)
    Ergebnis  : lädt Daten in ein eindimmensionales Array;
                Indizierung : y * max Spalten + aktuelle Zeie
    Variablen : x-aktuelle Spalte;y-aktuelle Spalte;_pos-aktuelle Adresse im array;
                f-nächste freie Dateinummer;dummy-dummyString;max-max Anzahl Spalten
                splitting-Liste auf aktuelle Spalten
  '/

  Dim x         As Integer
  Dim y         As Integer
  Dim _pos      As Integer
  Dim f         As Integer
  Dim dummy     As String
  Dim max       As Integer

  f = FreeFile
  y = 0
  Open this.filename For Input As #f
    Do
      Line Input #f, dummy

          Dim splitting As splitString
              splitting.spl(dummy,This.seperator)
        max = splitting.items
          x   = 0
        While splitting.Split->nxt <> 0

            _pos = y * max + (max - x)

           strlst(_pos) = splitting.Split->item
           splitting.Split=splitting.Split->nxt
           x += 1

        Wend
          strlst(y * max + 1 ) = splitting.Split->item

        y += 1

    Loop Until Eof(f)
  Close #f

End Sub
Function CSVLoader.getFileLength () As Integer
  /'
    Ergebnis : gibt Zeilenanzahl zurück
  '/

  Return This.filelength
End Function
Function CSVLoader.getCSVLength  () As Integer
  /'
    Ergebnis : gibt Spaltenanzahl zurück
  '/

  Return This.CSVlength
End Function


Anwendung

zu beachten ist das neben dem eigentlichen CSVLoader auch der stringSplitter benötigt wird (Programm anbei).
Die Geschwindigkeit ist relativ flott, ich denke damit lassen sich schnell auch größere Mengen in kurzer Zeit
laden und ggf. bearbeiten bzw. verändern.

#Include "stringSplit.bi"
#Include "CSVLoader.bi"


Dim wholeCSV As CSVLoader
    wholeCSV.init("beispiel.csv",";")

Dim y As Integer = wholeCSV.getFileLength
Dim x As Integer = wholeCSV.CSVlength

Dim csvArray(0 To y * x) As String
    wholeCSV.loadCSV(csvArray())

Dim a As Integer
Dim b As Integer

For a = 1 To y
  Print a;",";
  For b = 1 To x
     Print csvArray(a * x + b);",";
  Next
  Print
  Print
Next
sleep
End 0

stringSplitter

#######################################################################################################
/'
  (c) 2009 chutullu (chutullu2(at)yahoo(dot)de) / FreeBASIC-Portal.de
  
  stringSplit
  
  Version .2
  
  SplitList   Datentype
  
  SplitString Objekt
    * Zerteilt String in mit "sperator" getrennte Teile
    * Zerteilen erfolgt Byte-Weise  
    * einfache stackListe (filo)
    
    Struktur
      * toSplit   As String           - String welcher zerteilt werden soll
      * seperator As String           - Trenner
      * Split     As SplitList Ptr    - Liste
      * items     As Integer          - Anzeil der Strings in der Liste
      - spl (string2split, seperator) - zerteilt die Liste
      - addString (istring)           - fügt Element an die Liste an
      
'Anwendung

Dim splitting As splitString
Dim csvLine   As String = "52;27.12.2008;24;11;31;16;13;3;6;0;57.529.108,50;0;4.759.241,90;8;287.645,50;53;27.136,30;2036;1.836,60;6040;95,20;98986;29,00;138499;16,60;1592121;7,90"

splitting.spl(csvLine,";")

Dim array (1 To splitting.items) As String  
Dim a                            As Integer
 
  a = 0
  While splitting.Split->nxt <> 0
     array(splitting.items-a) = splitting.Split->item      
     splitting.Split=splitting.Split->nxt    
     a+=1  
  Wend  
  array(1) = splitting.Split->item
  
  For a = 1 To UBound (array)
     Print a, array(a)
  Next
  
Sleep        
'/



Type SplitList
  item      As String
  nxt       As SplitList Ptr
End Type
Type splitString
  Version   As Double = 0.2
  toSplit   As String
  seperator As String * 1
  Split     As SplitList Ptr
  items     As Integer

  Declare Constructor ()
  Declare Sub  spl (ByVal string2split As String, ByVal seperator As String)
  Declare Sub  addString (ByVal istring As String)
End Type

Constructor splitString ()
  This.Split = 0
  This.items = 0
End Constructor

Sub splitString.spl (ByVal string2split As String, ByVal seperator As String)
  /'
    Aufruf    : obj.spl ("asdf,gadsfg,asfas",",")
    Ergebnis  : zerteilt übergebenen String in mit seperator getrennte Teile
    Variablen : a-Laufvariable; char-einzelnes Zeichen; dummy-Dummy-String
  '/

  Dim a     As Integer
  Dim char  As String * 1
  Dim dummy As String

  This.toSplit   = string2split
  This.seperator = seperator

  For a = 1 To Len(This.toSplit)          'solange bis ende der zeichenkette ereicht
    char = This.toSplit[a-1]              '  zeichen = zeichnkette[a]
    If char = This.seperator Then         '  falls zeichen = seperator
        If Len (dummy) = 0 Then dummy = "0" '    0-String verhindern (stack overflow)
        This.addString (dummy)              '    string an Liste hängen
        This.items += 1                     '    items zählen
        dummy = ""                          '    dummy = "" und weiter
    Else                                  '  falls nicht
        dummy += char                       '    zeichen zu dummy zählen
    EndIf
  Next
End Sub

Sub splitString.addString (ByVal istring As String)
  /'
    Aufruf    : obj.addString ("adsfa")
    Ergebnis  : fügt String vorn an die Liste an
    Variablen : istring-neuer String; this.Split-Liste
                dummy-neues Listenelement
  '/

  If This.Split = 0 Then                  'falls Liste leer
                                           '  liste anlegen
     This.Split       = Callocate (SizeOf ( SplitList ))
    This.Split->item = istring
    This.Split->nxt  = 0
  Else                                    'falls nicht
    Dim dummy As SplitList Ptr            '  neues Element erzeugen

    dummy       = Callocate (SizeOf ( SplitList ))
    dummy->item = istring
    dummy->nxt  = This.Split              '  Element nach vorn schieben


    This.Split  = dummy                   '  Anfang der Liste = neues Element

  EndIf

End Sub

CODE Version 2.

Type toExplode
  Const version = 2.02

  array  As String Ptr
  csv    As String
  lenght As UShort
  Declare Sub split (ByVal Istring As String, ByVal Isep As String)
  Declare Sub arrayFree ()
End Type
Sub toExplode.split (ByVal Istring As String, ByVal Isep As String)
/'
  Ergebnis : Formatiert einen CSV String =>
             Beispiel        
             csv := "ab;abc;abcd" => csv := chr(2)+"ab"+chr(3)+"abc"+chr(4)+"abcd"
               Länge String 1         --------+     |     |     |      |      |
               String 1               --------------+     |     |      |      |
               Länge String 2         --------------------+     |      |      |
               String 2               --------------------------+      |      |
               Länge String 3         ---------------------------------+      |
               String 3               ----------------------------------------+
                                        
  Aufruf   : toExplode.split("ab;abc;abcd",";")
  Variable : a=Laufvar.; str_len=Länge des Strings;ct=Länge Teilstring&akteller Arrayeintrag
             items=Länge des Vektors; dummy=DummyString; Istring=Eingangsstring; Isep=Seperator
'/



  Dim a       As UShort  'Laufvariable
  Dim b       As UShort
  Dim str_len As UShort  'Länge des Strings
  Dim ct      As UShort  'Länge Teilstring
  Dim items   As UShort  'Anzahl der Arrayeinträge
  Dim dummy   As String = Istring 'dummy

  str_len  = Len(dummy)
  items Xor= items

  For a = 0 To str_len - 1
       b = str_len-a
      If Mid(dummy,b,1) = Isep Then
         Mid(dummy,b,1) = Chr(ct)
           ct          Xor= ct
           items         += 1
      Else
           ct            += 1
      EndIf
  Next a
  dummy       = Chr(ct) + dummy
  This.lenght = items + 1
  This.csv    = dummy

  This.array  = Callocate (SizeOf(String) * This.lenght)
  ct       Xor= ct


  For a = 0 To str_len - 1
     This.array[ct] = Mid(dummy,2+a,dummy[a])
     a += dummy[a]
     ct += 1
  Next a
End Sub
Sub toExplode.arrayFree ()
/'
  Ergebnis : gibt Speicher frei                          
  Aufruf   : toExplode.arrayFree ()
  Variable : toExplode.array[]-Array welches aufgelöst wird
'/

  DeAllocate (This.array)
  This.csv    = ""
  This.lenght = 0
End Sub


Type CSV
  Const Version = 2.0

  csv_matrix As toExplode Ptr
  csv_lines  As String Ptr
  y          As UInteger
  x          As UInteger

  Declare Sub oFile (ByVal filename As String, ByVal sep As String)
End Type

Sub CSV.oFile (ByVal filename As String,ByVal sep As String)
/'
  Ergebnis  : lädt ganze CSV
  Aufruf    : [toExplode].oFile("dateiname.csv",";")
  Variablen : a,b - Laufvariablen; f-Dateinummer; dummy-String;ex - Dummy
              csv_lines - alle Zeilen als String; csv_matrix - Datei als Matrix
              filename - dateiname; sep - Trennzeichen
'/

  Dim a     As UInteger
  Dim b     As UInteger
  Dim f     As Integer
  Dim dummy As String
  Dim ex    As toExplode

  f = FreeFile
  Open filename For Input As #f

    Line Input #f, dummy
    ex.split (dummy,sep)
    Seek #f, 1
    This.x  = ex.lenght
    ex.arrayFree

    a    Xor= a
    Do: a+= 1
        Line Input #f, dummy
    Loop Until Eof(f)
    Seek #f, 1


    This.csv_lines = Callocate (SizeOf(String) * a)
    This.y         = a
    a    Xor= a
    Do:
      Line Input #f, dummy
      This.csv_lines[a] = dummy
      a+=1
    Loop Until Eof(f)
  Close (f)

  This.csv_matrix = Callocate (SizeOf(toExplode) * This.y)
  For a = 0 To This.y-1
     This.csv_matrix[a].split(This.csv_lines[a],sep)
  Next a
  Exit Sub

noOpen:
  Print "file not found"
  End -1
ed:
Print "hier"
End Sub

/'Anwendung'/
Dim test As CSV
Dim a As Integer
Dim b As Integer
test.oFile("myFile.csv",";")

For a = 0 To test.y -1
  For b = 0 To test.csv_matrix[a].lenght -1
    Print test.csv_matrix[a].array[b];
  Next b
  Print
Next a
Sleep
End 0

Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 15.11.2009 von Mitgliedchutullu angelegt.
  • Die aktuellste Version wurde am 05.12.2009 von Mitgliedchutullu gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen