Validierungsreferenz · 0.2.0

Sechs Fehlercodes und was sie jeweils aussagen.

Jeder Validierungsfehler trägt einen stabilen maschinenlesbaren Code, die DATEV-Feldnummer und die amtliche Spaltenbezeichnung. Hier steht, was den Code auslöst und was zu ändern ist.

Drei Prüftiefen

Die Tiefe ist eine bewusste Entscheidung je Datei. Ein strikterer Modus ändert nie die geschriebenen Bytes, sondern nur, was vorher abgelehnt wird.

Validierungsmodi und die jeweils möglichen Codes
ModusWas geprüft wirdMögliche Codes
NONEKeine semantische Prüfung. Die strukturellen Prüfungen des Exporters — Zeilenbreite, Steuerzeichen, Kodierbarkeit — gelten weiterhin.
FIELD_LEVELJede gefüllte Zelle gegen ihre amtliche Felddefinition.INVALID_FORMAT, VALUE_OUT_OF_RANGE, TEXT_TOO_LONG, UNMAPPABLE_CHARACTER
STRICTAlles davon, zusätzlich Pflichtfelder und Feldabhängigkeiten.alle sechs

Die sechs Codes

Stabile Kategorien von Validierungsfehlern
CodeWird ausgelöst, wennÜbliche Behebung
REQUIRED_FIELDEin vom amtlichen Prüfprogramm als notwendig markiertes Feld ist leer — im strikten Modus auf einem amtlichen Schema.Feld füllen. Betroffen sind nur fünf Spalten: Umsatz, Soll/Haben-Kennzeichen, Konto, Gegenkonto und Belegdatum.
INVALID_FORMATEin Wert entspricht nicht der von DATEV geforderten Darstellung — eine fehlerhafte Zahl, ein Datum ohne realen Kalenderbezug, ein Kennzeichen außerhalb der erlaubten Menge oder ein Steuer- bzw. Zeilentrennzeichen innerhalb einer Zelle.Den Wert so formatieren, wie DATEV ihn erwartet, nicht wie das eigene Locale ihn ausgibt. Zeilenumbrüche und Tabulatoren aus Freitext entfernen.
VALUE_OUT_OF_RANGEDer Wert ist syntaktisch gültig, überschreitet aber seinen Bereich — zu viele Vorkommastellen, zu viele Nachkommastellen oder eine Kontonummer breiter als die konfigurierte Sachkontenlänge.Maximale Länge und Nachkommastellen in der Feldreferenz prüfen und sicherstellen, dass die Sachkontenlänge in den Metadaten zum Mandanten passt.
TEXT_TOO_LONGEin Textwert überschreitet die maximale Zeichenzahl des Feldes.Bewusst in der eigenen Zuordnung kürzen. Es wird nicht still gekürzt, weil der Verlust eines Teils des Buchungstexts eine fachliche Entscheidung ist.
UNMAPPABLE_CHARACTERDer Wert enthält ein Zeichen, das Windows-1252 nicht darstellen kann.Das Zeichen vor dem Export transliterieren oder ersetzen. Die Kodierungsreferenz zeigt, welche Zeichen erhalten bleiben.
DEPENDENT_FIELD_MISSINGIm strikten Modus wurde eine Hälfte eines Feldpaares ohne die andere gefüllt.Beide Hälften füllen — oder keine.

Die Feldpaare

Der strikte Modus erzwingt diese Paare. Wird nur eine Seite gefüllt, entsteht DEPENDENT_FIELD_MISSING auf der fehlenden Seite.

  • Basis-UmsatzWKZ Basis-Umsatz (Felder 5 und 6).
  • Beleginfo - Art nBeleginfo - Inhalt n für n = 1…8.
  • Zusatzinformation - Art nZusatzinformation- Inhalt n für n = 1…20.

Kontext schärft die Prüfungen

Manche Regeln lassen sich nicht allein aus dem Schema entscheiden. Ein Validierungskontext trägt die Angaben, die sie entscheidbar machen; ohne ihn werden genau diese Prüfungen übersprungen statt geraten.

  • Die Sachkontenlänge begrenzt die Breite von Konto und Gegenkonto.
  • Wirtschaftsjahresbeginn und Buchungszeitraum erlauben es, das vierstellige Belegdatum gegen reale Kalenderdaten aufzulösen.
Bestandene Validierung ist keine Importzertifizierung

Diese Prüfungen bestätigen, dass die Datei dem technischen Schema entspricht. Sie sagen nichts darüber aus, ob die Buchungen fachlich richtig sind oder ob ein bestimmtes DATEV-Produkt in einer bestimmten Konfiguration die Datei annimmt.

Fehler im Code auswerten

Eine abgelehnte Zeile löst eine DatevValidationException aus, die die vollständige Fehlerliste trägt. Jeder Fehler behält Code, Feldnummer und amtliche Spaltenbezeichnung, sodass sich Fehler protokollieren oder abbilden lassen, ohne Meldungstexte zu parsen.

import io.github.mrtyldr.datev.core.DatevValidationError;
import io.github.mrtyldr.datev.core.DatevValidationException;

try {
    file.append(columns);
} catch (DatevValidationException failure) {
    for (DatevValidationError error : failure.errors()) {
        log.warn("field {} ({}): {} — {}",
                error.fieldNumber(),
                error.canonicalKey(),
                error.code(),
                error.message());
    }
}