Mehrere "Tabellen" aus einer CSV Datei lesen

Domi741

Mitglied
Hallo zusammen,

ich habe eine recht interessante Konstallation.

Ich habe hier mehrere CSV-Dateien als Export aus einer TK-Anlage.
In dieser CSV sind mehrere "Tabellen" enthalten, welche unterschiedlich lang sind. Für ein besseres Bild hier dmal ein Beispiel einer CSV Datei:
Code:
/TABLE;tabellenname;162
/FIELDS
Spalte1;Spalte2;Spalte3;Spalte4;Spalte4;Spalte5;Spalte6
Zeile1;Zeile1;Zeile1;Zeile1;Zeile1;Zeile1;Zeile1
Zeile2;Zeile2;Zeile2;Zeile2;Zeile2;Zeile2;Zeile2
Zeile3;Zeile3;Zeile3;Zeile3;Zeile3;Zeile3;Zeile3
//END OF TABLE;tabellenname;162

/TABLE;tabellenname2;145
/FIELDS
Spalte1;Spalte2;Spalte3;Spalte4;Spalte4;Spalte5;Spalte6
Zeile1;Zeile1;Zeile1;Zeile1;Zeile1;Zeile1;Zeile1
Zeile2;Zeile2;Zeile2;Zeile2;Zeile2;Zeile2;Zeile2
Zeile3;Zeile3;Zeile3;Zeile3;Zeile3;Zeile3;Zeile3
//END OF TABLE;tabellenname2;145

Zur Erklärung: Spalte 1-6 Sind im Prinzip die Feldnamen und die Zeilen sind die jeweiligen Einträge mit den entsprechenden Werten pro Spalte.

Nun mein Anliegen:
Wie schaffe ich es die Tabellen auszulesen, teilweise zu kombinieren und dann entsprechend auszugeben? Es gibt einen Werte in den Tabellen der für eine Verknüpfung zum eindeutigen zuordnen benutzbar sind.

Ich hoffe mein Problem ist verständlich und man das vorhaben ist überhaupt lösbar.

Danke im voraus!

Lg Dominic
 
Hi

Vielleicht ist es ja nicht wichtig, aber was ist die Zahl hinter dem Tabellennamen?

Wie sollen Daten zB. kombiniert werden?
(zB. gibt es für die "ID" in Tabelle A min/max/genau soundsoviel Einträge in Tabelle B,
alle nehmen oder nur den wo irgendein Wert maximal ist,
was machen wenn es einen A-Eintrag ohne irgendeinen B-Eintrag gibt
usw.usw.)

Soll die Ausgabe wieder in dem Format in eine Datei sein, oder formatiert ins HTML, oder...?

Sollen mit einmal geladenen Daten mehrere verschiedene Sachen gemacht werden, dass es sich evt. lohnen könnte das Ganze in eine DB einzufügen und die Kombinierungen dort machen zu lassen (deutlich schneller als in PHP, nur das Reinladen braucht auch Zeit)?
 
Hi,

alsoooo:
Die Zahl hinter dem Tabellennamen scheint soetwa wie eine ID zu sein, da sie bei jeder Tabelle anders ist.

Hier mal ein richtiges Beispiel mit Demodaten:
Code:
/TABLE;Benutzer;162
/FIELDS
Benutzer-ID;Nummer;Name
1;10;Digital 1
2;11;Digital 2
3;13;DECT 1
4;14;DECT 2
5;15;DECT 3
6;19;Analog 1
//END OF TABLE;Benutzer;162

/TABLE;Endgerät;163
/FIELDS
Endgerät-ID;Beschreibung;Endgerättyp
1;Digital 1;7
2;Digital 2;7
3;DECT 1;0
4;DECT 2;0
5;DECT 3;0
6;Analog 1;5
//END OF TABLE;Endgerät;163

/TABLE;Zuweisung Benutzer-Endgerät;164
/FIELDS
Benutzer-ID;Endgerät-ID
1;1
2;2
3;3
4;4
5;5
6;6
//END OF TABLE;Zuweisung Benutzer-Endgerät;164

/TABLE;Systemendgerätedaten;168
/FIELDS
Endgerät-ID;Typ
1;23
2;23
3;20
4;19
5;8
//END OF TABLE;Systemendgerätedaten;168

Nun zur Erklärung:
Ich möchte eine Liste der Benutzerausgeben aus der Telefonanlage mit folgenden Daten: Nummer, Name, Engerätetyp

zum Ablauf: Es müssen aus Tabelle 162 der Name und die Nummer genommen werden. Anhand der Benutzer-ID muss eine Verknüpfung zu Tabelle 164 hergestellt werden zum auslesen der Endgeräte-ID. Diese Endgeräte-ID muss dann in Tabelle 163 gucken, sofern dort beim Endgeräte-Typ eine 0 oder 7 steht, soll er zusätzlich noch den Typ aus Tabelle 168 dazunehmen, welchen er mit anhand eines vorgegeben Arrays in Klartext umwandelt.

Was die Ausgabe betrifft, bin ich da flexibel, erstmal reicht es mir wenn er das dann als HTML Tabelle ausgibt, aber irgendwann werde ich es dann sicher umbauen, dass er eine PDF-Datei daraus generiert. Mehr soll mit den Daten nicht geschehen. Keine sonstige Verarbeitung etc.


Ich hoffe das klärt die Fragen. Ich weiß es ist recht komplex und Umfangreich, aber ich habe echt keine Idee wie ich das Umsetzen soll.

Danke und Gruß Dominic
 
Leider noch nicht alles geklärt:
Kann es in Tab164 für einen Benutzer mehrere Einträge geben (dann alle separat ausgeben oder...)?
Kann es in Tab164 für einen Benutzer keinen Eintrag geben (was dann tun...)?

(Ich nehme an, dass die IDs von 162, 163 und 168 eindeutig sind,
und sicher vorhanden falls woanders angegeben, einfach weils Sinn macht)

Und noch einmal zur Performance:
Soll einmal alles für jeden Benutzer gemacht werden und dann nie wieder,
oder je nach Wunscheingabe auf der PHP-Seite für bestimmte Benutzer?

Wenn letzteres: Wechseln die Grunddaten ab und zu?

Wieviel Datensätze gibts, größenordnungsmäßig (bzw. wieviel "kanns geben"? (Hundert, 1 Million, 10 Milliarden)...?


Soo komplex wird das nicht,
 
Zuletzt bearbeitet:
Kein Thema :)

Also es kann in Tab164 mehrere Einträge geben (max 16 Stk.) und es kann auch mal vorkommen, dass in Tab164 nichts für den Benutzer steht, dann soll er zwar den Benutzer Auflisten und beim Endgerät in der Ausgabe einfach schreiben "kein EG"

Was die Ausgabe betrifft, das ist nur zur einfachen bequemen Ausgabe der Benutzer einer TK-Anlage sind immer mal einmalige Ausgaben und dann immer ALLE auf einmal in einer Liste.

Die Menge der Datensätze sind im Bereich 5-200 jenach Anlagengröße.
 
Sooo ich habe mal ein wenig an dem Ausgabescript gearbeitet und habe nun ein Ergebnis, wie die Daten die das Script zusammenstellt aus den Tabellen aussehen sollen:

Ich hätte gerne ein Mehrdimensionales-Array welches wie folgt aufgebaut ist:
PHP:
$data=array(array(Nummer(162),Name(162),Endgerätetyp(163),Typ(168)),array(Nummer(162),Name(162),Endgerätetyp(163),Typ(168)));

Wobei die Zahlen in der Klammer nur hier zur Veranschaulichung dienen, aus welcher Tabelle ich das Feld brauche.

Bei dem "Typ" aus Tabelle 168 steht natürlich nur etwas drin, wenn der Endgerätetyp (aus Tabelle 163) 0 oder 7 ist!

Stellt sich nur die alles entscheidende Frage, wie verabeite ich die CSV Datei mit obengenanntem Aufbau, dass ich so ein Array zustande kriege, da steh ich leider echt aufm Schlauch =/
Vielleicht hat hier ja jemand einen Lösungsansatz und/oder Tips?!

Lg Dominic

P.S. Mit statischen Daten klappt die Ausgabe so wie ich sie gerne hätte :) (es wird nun übrigens eine PDF)
 
Ich hatte gerade etwas Langeweile und habe mal schnell folgenden Parser geschrieben:
PHP:
<?php
  class Table implements Countable, Iterator {
    private $columns = array();
    private $rows    = array();
    private $table_name;
    private $table_id;

    public function __construct( $table_name, $table_id, array $columns ) {
      $this->table_name = $table_name;
      $this->table_id   = (int) $table_id;
      $this->columns    = $columns;
    }

    # gibt den Tabellennamen zurück
     public function get_table_name() {
      return $this->table_name;
    }

    # gibt die ID der Tabelle zurück
     public function get_table_id() {
      return $this->table_id;
    }

    # gibt die Namen der Spalten zurück
     public function get_columns() {
      return $this->columns;
    }

    # fügt eine neue Zeile hinzu
     public function add_row( array $values ) {
      $this->rows[] = $values;
    }

    # gibt alle Zeilen der Tabelle zurück
     public function get_rows() {
      return $this->rows;
    }

    # gibt die Anzahl der Zeilen in der Tabelle zurück
     public function count() {
      return count( $this->rows );
    }

    # Iterator-Methode
     public function current() {
      return current( $this->rows );
    }

    # Iterator-Methode
     public function key() {
      return key( $this->rows );
    }

    # Iterator-Methode
     public function next() {
      next( $this->rows );
    }

    # Iterator-Methode
     public function rewind() {
      reset( $this->rows );
    }

    # Iterator-Methode
     public function valid() {
      return $this->key() !== null;
    }
  }

  class TableSet {
    final private function __construct() {}
    final private function __clone() {}

    # parset die angegeben Daten
     public static function parse( $content, $lineending = "\r\n" ) {
      $lines            = explode($lineending, $content);
      $tables           = array();
      $current_table    = null;
      $current_table_id = null;

      while ( list( $index, $line ) = each( $lines ) ) {
        # leere Zeilen ignorieren
         if ( trim($line) === '' ) {
          continue;
        }

        # Tabellen-Metainformationen
         if ( $line[0] === '/' ) {
          # Start einer Tabelle
           if ( substr( $line, 1, 5 ) === 'TABLE' ) {
            # vorherige Tabelle wurde nicht korrekt abgeschlossen
             if ( $current_table !== null ) {
              throw new Exception( 'parsing error: unexpected start of table definition' );
            }

            # ermittelt den Namen und die ID der Tabelle
             list( , $current_table, $current_table_id ) = explode( ';', $line, 4 );
            $current_table_id = (int) $current_table_id;
            next($lines);
            # erzeugt ein neues Tabellen-Objekt
             $tables[$current_table] = new Table( $current_table, $current_table_id, explode( ';', current($lines) ) );
            next($lines);

          # Ende einer Tabelle
           } elseif ( substr( $line, 1, 13 ) === '/END OF TABLE' ) {
            # kein Ende erwartet
             if ( $current_table === null ) {
              throw new Exception( 'parsing error: unexpected end of table definition' );
            }

            # ermittelt den Namen und die ID der Tabelle
             list( , $table, $table_id ) = explode( ';', $line, 4 );
            $table_id = (int) $table_id;

            # vergleicht den Namen und die ID mit jenen, die in der ersten Zeile der Tabellendefinition standen
             if ( $table !== $current_table || $table_id !== $current_table_id ) {
              throw new Exception( 'parsing error: end of table definition does not match start' );
            }

            # definiert Leseprozess für diese Tabelle als beendet
             $current_table = $current_table_id = null;

          }
        } else {
          # unerwartete Zeile mit Inhalt
           if ( $current_table === null ) {
            throw new Exception( 'parsing error: unexpected table body' );
          }

          # fügt Zeile der aktuellen Tabelle hinzu
           $tables[$current_table]->add_row( explode( ';', $line ) );
        }
      }

      # letzte Tabelle wurde nicht korrekt beendet
       if ( $current_table !== null ) {
        throw new Exception( 'parsing error: missing end of table definition' );
      }

      return $tables;
    }
  }
Und dann einfach so verwenden:
PHP:
<?php
  $tables = TableSet::parse(file_get_contents('path/to/file.csv'));
  print_r( $tables['Benutzer']->get_rows() ); # zeigt alle Zeilen der Tabelle "Benutzer" an
 
Zuletzt bearbeitet:
:eek: was kommt denn noch alles dabei raus wenn du langeweile hast und mal schnell was schreibst?! :D

Das ist ja mal richtig genial und es funktioniert!!! :)

Gibts nur 1 Problem, die bösen Umlaute. Tabellen mit nem Umlaut kann er nicht ausgeben. Nen Tip wo ich suchen soll? =)

Aufjedenfall schonmal ein riesiges Danke!!!!
 
Wenn man seit zehn Jahren programmiert, dann gibt es nur noch drei Arten von Problemen: die gefühlt meisten sind die, die man einfach nur in einer bestimmten Programmiersprache ausformulieren muss – weil man ähnliche Probleme schon oft gelöst hat –, dann gibt es die, bei denen man auch einmal einige Tage nachdenken muss, die erst den Nervenkitzel, die Schweißausbrüche und die Verzweiflung bringen, und dann gibt es die Probleme, von denen man noch gar nicht weiß, dass man sie hat oder das es sie gibt, die aber wirklich den Großteil der Probleme darstellen – man weiß es nur (noch) nicht ;)
 
Zurück