Importierte CSV Datei richtig Filtern

Duergy

Mitglied
Frohes Neues und schönen Montag,

ich sitze seit letzter Woche an einen Problem und ich hoffe ihr könnt mir helfen.

Folgende Situation. Ich habe aus WinData ein CSV File welches ein Kontoauszug ist.
Ich möchte alle Einträge behalten, welche
  1. positiven Umsatz haben (Zahlungseingang)
  2. in einer der Betreffzeilen eine Zahl zwischen 1900-2999 ist

Ich habe noch weitere kleiner Filter eingebaut.

PHP:
// $zeile[0] = Empfänger BLZ
// $zeile[3] = Buchungsdatum
// $zeile[4] = Umsatz (Also der Betrag)
// $zeile[26] = Fortlaufende Nummer die das Programm vergibt
// $zeile[8];$zeile[9]$zeile[10] = Betreffzeilen

$fp = fopen("".$_FILES['datei']['tmp_name']."", "r");
$zeilen = array();

  while( !feof($fp) ) {
    $zeilen[] = fgetcsv  ( $fp  , 4096 , ";" , "\"" );
  }
  for ($i=0; $i<count($zeilen); $i++){

    if(!is_numeric($zeilen[$i]['0']) OR empty($zeilen[$i]['26']) OR empty($zeilen[$i]['4']) OR preg_match('/[-]/', $zeilen[$i]['4']))
    {
      unset($zeilen[$i]);
    }
  }
  rsort($zeilen);reset($zeilen);
  for ($i=0; $i<count($zeilen); $i++){
    $betreff1=preg_match('/\b[1-2][0-9]{3}(?![0-9])\b/', $zeilen[$i][8], $resnr1);
    $betreff2=preg_match('/\b[1-2][0-9]{3}(?![0-9])\b/', $zeilen[$i][9], $resnr2);
    $betreff3=preg_match('/\b[1-2][0-9]{3}(?![0-9])\b/', $zeilen[$i][10], $resnr3);
    if(empty($resnr1[0]) AND empty($resnr2[0]) AND empty($resnr3[0])){
      unset($zeilen[$i]);
    }
  }
  rsort($zeilen);reset($zeilen);
  for ($i=0; $i<count($zeilen); $i++){
    if(!empty($zeilen[$i]['26'])){
      $betreff1=preg_match('/\b[1-2][0-9]{3}(?![0-9])\b/', $zeilen[$i][8], $resnr1);
      $betreff2=preg_match('/\b[1-2][0-9]{3}(?![0-9])\b/', $zeilen[$i][9], $resnr2);
      $betreff3=preg_match('/\b[1-2][0-9]{3}(?![0-9])\b/', $zeilen[$i][10], $resnr3);
      $buchungen[]=array(
      "Buchungsdatum" => "".$zeilen[$i]['3']."",
      "Umsatz" => "".$zeilen[$i]['4']."",
      "Betreff1" => "".$zeilen[$i]['8']."",
      "Betreff2" => "".$zeilen[$i]['9']."",
      "Betreff3" => "".$zeilen[$i]['10']."",
      "Reservierungsnummer" => "".$resnr1['0']."".$resnr2['0']."".$resnr3['0'].""
      );
    }
  }
  if(count($buchungen)==0){echo"<div align=\"center\">Keine Zahlung zum verbuchen Vorhanden.</div>";}
  foreach($buchungen as $buchung){
  echo"<div style=\"width:500px; border: 1px solid black; margin: 0 auto; padding: 10px;\">
  <span style=\"text-decoration: underline;\">Datensatz mit folgenden Daten:</span><br>
  Datum: ".$buchung['Buchungsdatum']."<br>
  Umsatz: ".$buchung['Umsatz']."<br>
  Betreff: ".$buchung['Betreff1']."<br>
  Betreff: ".$buchung['Betreff2']."<br>
  Betreff: ".$buchung['Betreff3']."<br>
  Reservierungsnummer: ".$buchung['Reservierungsnummer']."</div>";
              }

Nun ist es so, das die Filter nicht wirklich so Funktionieren wie sie sollten.
 
Ein Beispiel-CSV wäre evtl. hilfreich. Zusammen mit der Erklärung, was denn nun genau nicht so funktioniert, wie es soll.
 
Die Problematik ist, das mir teilweise (nicht immer!?) auch Datensätze mit negativen Umsatz angezeigt werden und auch welche ohne Reservierungsnummer (resnr)

Ich habe mal eine Beispieldatei ANgehägt in der ich ein bisschen was Rausgelöscht habe. Schließlich sind es ja Bankdaten. In dem Konkreten File werden mir 2 Einträge ohne Reservierungsnummer angezeigt.
 

Anhänge

Es gibt die nette Funktion array_filter()

Da ich nicht gerne mit unleserlichen Nummern als Feldindexe arbeite habe ich in meinem Beispiel die Zeilen mit Spaltennamen deklariert. So muss man beim ändern der Dateistruktur auch nur einmal die Spaltendefinition anpassen und nicht im ganzen Code Zahlen ersetzen.

Hier mal mein kleiner Test
PHP:
<?php
//Spaltennamen definieren
$fieldDef = array('id', 'value', 'desc', 'flag');

$fp = fopen("test.csv", "r");
$zeilen = array();
while(($row = fgetcsv  ( $fp  , 4096 , ';' , '"' ))!==false) {
    //Zeile als Array mit den Spaltennamen speichern
    $rows[] = array_combine($fieldDef, $row);
}
fclose($fp);

//Filtern nach positivem Wert im Feld value
$filteredRows = array_filter($rows, 'filterValues');
//Filtern nach einer Zahl in der desc
$filteredRows = array_filter($filteredRows, 'filterDesc');

print_r($filteredRows);

//Filter: value ist positiv
function filterValues($row){
    return $row['value'] >= 0;
}

//Filter: desc Enthält eine Zahl zwischen 100 und 400
function filterDesc($row){
    $pattern = '/([[:digit:]]+)/is';
    preg_match_all($pattern, $row ['desc'], $numbers);
    foreach($numbers[1] as $number){
        if($number >= 100 && $number <=400) return true;
    }
    return false;
}
?>
Und mein test.csv
Code:
"1";"100";"abcd123";"0"
"2";"200";"abcd456";"1"
"3";"-300";"abcd";"1"
"4";"400";"abcd345";"0"
ergibt
Code:
Array
(
    [0] => Array
        (
            [id] => 1
            [value] => 100
            [desc] => abcd123
            [flag] => 0
        )

    [3] => Array
        (
            [id] => 4
            [value] => 400
            [desc] => abcd345
            [flag] => 0
        )
)
 
Zurück