Die Volkswagenbank und das 21. Jahrhundert

Vor einigen Jahren hat der Kunde, der mir erlaubt hat das alles hier zu veröffentlichen, ein Konto bei der Volkswagenbank (im neuen Fenster öffnen) eröffnet. Kostenlose Kontoführung, recht sichere Handhabung durch die Benutzung eines etwas umständlichen aber recht Phishing (im neuen Fenster öffnen)-resistenten Hardware-TAN-Generator, von der Bank liebevoll 'Bankey' genannt. Und - Volkswagen ist ja auch kein Unbekannter.

Das Online-Banking erfolgt per Browser und - nur per Browser. Und genau hier fangen die Probleme an. Andere Banken bieten für ihre Privat- und kleineren Geschäftskunden Schnittstellen zu Homebankingsoftware und PC-gestützter Kontoführung an. HBCI (im neuen Fenster öffnen) ist hier das Stichwort. Die  Volkswagenbank bisher leider nicht. Auf Nachfrage antwortet die Hotline schon seit Jahren mit 'derzeit nicht geplant'. Für Großkunden gibt es die FTAM (im neuen Fenster öffnen)-Schnittstelle. Da diese aber in Homebankingsoftware eher selten und dann auch nur mit saftigen Aufpreisen verfügbar ist, ist es für Privatkunden keine Option.

Leider werden die Datensätze online von der Bank nur 6 Monate lang bereitgestellt.  Zwar können sie in diesem Zeitraum auch im CSV-Format exportiert werden, alle älteren Daten stehen dann nur noch in Form eines Kontoauszugs im PDF-Format zur Verfügung. Diese Kontoauszüge werden 2 Jahre vorgehalten und wer sie nicht lokal gesichert hat, kann auf ältere Transaktion überhaupt nicht mehr zugreifen. Das wird dann zum Problem, wenn man beispielsweise für das Finanzamt oder eine Versicherung bestimmte Aufstellungen über in der Vergangenheit liegende bereitstellen muss. Am PC ist so ein Report in aller Regel innerhalb von Sekunden fehlerfrei erstellt, die manuelle Methode (durchlesen, identifizieren und rausschreiben) dagegen kann schon einmal mehrere Stunden oder Tage dauern; fehleranfälliger ist es auch.

Das Kunde bat mich um ein Idee, wie er seine alten Daten, die ihm nur noch als PDF-Kontoauszug vorlagen, in den PC bekommt. Ich habe ihm darauf hin eine kleine und sehr günstige Lösung gebaut, die zweistufig arbeitet.

In der ersten Stufe wird aus dem Kontoauszug der Text im ASCII-Format unter weitestgehender Beibehaltung des Layouts mit Hilfe des Programmes Xpdf  (im neuen Fenster öffnen) extrahiert.

In der zweiten Stufe nimmt ein kleines Perl-Script diesen ASCII-Text, identifiziert die Kontobewegungen und schreibt diese als CSV-Datei auf die Festplatte. Von da an können die Daten mit Excel oder einer Datenbank weiterverarbeitet bzw. ausgewertet werden.

Zum Üben empfehle ich das Schnupperkonto, dessen Zugang auf der Homepage der Volkswagenbank zu finden ist. Dort lässt sich auch, unter dem Menüpunkt 'Nachrichten', im Posteingang ein Muster-Kontoauszug herunterladen.

Achtung, wichtiger Hinweis: dieses Programm ist gedacht für erfahrene PC-Anwender oder Programmierer mit Perl-Kenntnissen. Wer nicht weiß was er da ließt, sollte das Programm auf gar keinen Fall einsetzen. Ich lehne jede Haftung für Schäden, die durch den unsachgemäßen Einsatz des Programmes entstehen, ab. Insbesondere sollten, auch wenn nur lesend darauf zugegriffen wird, die Kontoauszüge vor dem Programmlauf mit einer entsprechenden Datensicherung weggesichert werden. Details zur Benutzung des Scripts sind in den Kommentaren im Programmcode zu finden. Ich biete für das Programm weder Support noch Unterstützung.

 #!perl
 #
 # Programmname: vwb-data2csv
 # Beschreibung und Anleitung:
 # Ein Programm um die im Pdf-Format vorliegenden und als Textdatei umgewandelten Kontoauszüge der Volkswagenbank
 # in CSV Dateien umwandelt um sie danach in Excel oder eine Datenbank weiter zu verwalten.
 # Um die Dateien aus dem Pdf-Format in eine Textformat zu überführen, wird zusätzlich die frei Software
 # Xpdf benötigt. Sie können Xpdf hier herunterladen: http://www.foolabs.com/xpdf/
 # Aus dem Paket wird nur die Datei pdftotext.exe benötigt. Sie wird folgendermassen
 # aufgerufen: pdftotext -layout [Dateiname der Pdf-Datei]. Als Ergebnis erhalten Sie eine Datei mit dem gleichen
 # Namen und der Endung txt. Diese Datei wird dann von vwb-data2csv weiterverarbeitet.
 #
 # Copyright: Robert Krauss, Hemmingen, 2009.
 #
 # Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License,
 # wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder
 # gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
 #
 # Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber
 # OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
 # FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
 #
 # Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten
 # haben. Falls nicht, schreiben Sie an die
 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
 
 
 use strict;
 use warnings;
 
 #Im Debugfall mehr andrucken
 my $debug = 1;
 
 # Variablendeklaration
 my $INFILE_filename;
 my $OUTFILE_filename;
 
 # ggf. anpassen, unter Windows muss der backslash maskiert werden!
 my $importdir = "C:\\pfad\\zu\\den\\ascii-dateien";
 
 my $number;
 my $date1;
 my $text;
 my $date2;
 my $amount;
 my $text2;
 my $firsttime;
 my $firstline;
 my @filelist;
 my @files;
 my $file;
 
 # Alle Dateinamen einlesen die in dem Verzeichnis liegen und die dem Muster entsprechen. Ggf. anpassen.
 opendir (DIR,"$importdir") || die "Opendir $importdir not possible: $!";
 @files = grep(/Ko.*\.txt$/,readdir(DIR));
 closedir(DIR);
 
 # Im Debugfall mehr andrucken
 if ($debug) {
             foreach $INFILE_filename (@files) {
                print "Infile: $INFILE_filename\n";
                $OUTFILE_filename = $INFILE_filename;
                $OUTFILE_filename =~ s/^(\w+-\d+)-.*/$1.csv/;
                print "Outfile: $OUTFILE_filename\n";
             }
         }
 
 # Für jede Datei im verzeichnis wird die Schleife einmal durchlaufen.
 foreach $INFILE_filename (@files) {
                             open(IN,'<',"$importdir/$INFILE_filename") or die  "$0 : failed to open  input file $INFILE_filename : $!\n";
 # Dateinamensaufbau bei der VW-Bank: Kontoauszug-[Kontonummer]-[Jahr]-[Monat]
 # Die Ausgabedatei sammelt die Daten in der Datei Kontoauszug-[Kontonummer].csv
                              $OUTFILE_filename = $INFILE_filename;
                              $OUTFILE_filename =~ s/^(\w+-\d+)-.*/$1.csv/;
 # Durch die Angabe von >> werden neue Daten an die Datei angehängt
                             open ( OUT, '>>', "$importdir\\$OUTFILE_filename" ) or die "$0 : failed to open  output file $OUTFILE_filename : $!\n";
                             print "start\n";
 # Flag setzen um zu bemerken wann die Routine das erste mal komplett durch eine Kontobewegung durch ist. Erst dann darf gedruckt bzw. ausgegeben werden.
                             $firsttime = 1;
                             while(<IN>){
 # Zeilenumbruch abschneiden
                                         chomp;
 # Regulärer Ausdruck um die erste Zeile eine Kontobewegung zu erfassen und die durch
 # Klammern zwischengespeicherte Teilwerte für die weitere Bearbeitung vorzubereiten
                                         if ($_ =~ /^ *(\d+) +(\d{2}\.\d{2}\.\d{4}) (.*?) (\d{2}\.\d{2}\.\d{4}) +(-?[.\d]+,?\d*)$/) {
 # Flag setzen, die erste Zeile einer Kontobewegung ist erfasst.
                                             $firstline = 1;
 # Nur wenn die Routine bereits einmal vollständig durchlaufen wurde, darf ausgegeben werden.
                                             if (not $firsttime) {
 # Ausgabe einer Datenzeile in die Ausgabedatei.
                                                 print OUT "$number|$date1|$date2|$amount|$text\n";
                                             }
                                             $firsttime = 0;
 # Variablenwerte übernehmen
                                             $number = $1;
                                             $date1 = $2;
                                             $text= $3;
                                             $date2 = $4;
                                             $amount = $5;
 # Mit diesem Regex werden vor und nach dem Text eventuell vorhandene Leerzeichen entfernt
                                             $text =~ s/(?:^ +)||(?: +$)//g;
 # Fertig? Dann nächste Zeile einlesen.
                                             next;
                                             }
 # Zweite und folgende Zeile einer Kontobewertung erkennen und wegspeichern. Es gibt die bisher ungelöste Prtoblematik,
 # das sich der Einzug der Folgezeilen hin und wieder verändert. Dadurch wird, insbesondere bei Seitenübergängen, auch Text weggeschrieben,
 # der eigentlich mit der Kontobewegung nichts mehr zu tun hat. Da mich das nicht stört, ist das Problem noch nicht behoben.
                                         if (($_ =~ /^\s{19,60}(\S.*)$/) && ($firstline)) {
                                             $text2 = $1;
 # Leerzecihen vor und nach dem Wort löschen
                                             $text2 =~ s/(?:^ +)||(?: +$)//g;
                                             $text = $text . " " . $text2;
 # nach max. 100 Zeichen wird der Buchungstext abgeschnitten. Normale Einträge sind nicht so lang.
                                             $text =~ s/^(.{0,100}\S*).*$/$1/;
                                             }
                                         }
 # Eingabedatei schließen
                             close IN or warn "$0 : failed to close input file $INFILE_filename : $!\n";
 # Fertigen Buchungssatz ausgeben.
                             if (not $firsttime) {
                                 print OUT "$number|$date1|$date2|$amount|$text\n";
                             }
                         }
 # Ausgabedatei schließen. Ende.
 close ( OUT ) or warn "$0 : failed to close output file $OUTFILE_filename : $!\n";
 
 print "stop\n";