- Thema
- Kommandozeilen-Tools
- Business Terms
- BT-1 Rechnungsnummer BT-2 Rechnungsdatum BT-3 Code für den Rechnungstyp BT-10 Referenz des Käufers BT-72 Tatsächliches Lieferdatum BT-106 Summe der Nettobeträge aller Rechnungspositionen BT-109 Rechnungsgesamtbetrag ohne Umsatzsteuer BT-112 Rechnungsgesamtbetrag einschließlich Umsatzsteuer
- Codebeispiele
- Kommandozeile, Delphi
- Veröffentlicht
Kurz: Ihre Anwendung – egal ob Delphi, VB6, Access, COBOL oder eine andere Sprache – schreibt die Rechnungsdaten in vier CSV-Dateien und ruft das Kommandozeilenwerkzeug zugcmd auf. zugcmd liest die Dateien, erzeugt das E-Rechnungs-XML nach EN 16931 (XRechnung 3.0, Syntax CII) und bettet es in Ihre vorhandene PDF-Rechnung ein. Heraus kommt eine hybride ZUGFeRD-Rechnung (PDF/A-3), die Sie wie gewohnt per E-Mail versenden. Eine Programmierung gegen das SDK ist dafür nicht nötig.
Der Ablauf
- Ihre Anwendung erzeugt die PDF-Rechnung wie bisher.
- Sie schreibt die Rechnungsdaten in die CSV-Dateien (siehe unten).
- Sie startet zugcmd und wertet den Rückgabewert aus (0 = Erfolg).
- zugcmd schreibt das XML und die ZUGFeRD-PDF mit eingebettetem XML.
- Ihre Anwendung versendet die ZUGFeRD-PDF per E-Mail. Den Versand übernimmt zugcmd nicht.
Ohne vorhandenes PDF kann zugcmd das PDF auch aus einer Word-Vorlage (DOCX) erzeugen; das beschreibt die zugcmd-Seite.
Welche CSV-Dateien braucht zugcmd?
| Datei | Inhalt | Parameter | Pflicht |
|---|---|---|---|
seller.csv | Verkäufer: Name, Anschrift, Kontakt, USt-ID, Bankverbindung | -s | ja – ändert sich kaum, kann als Stammdatei liegen bleiben |
buyer.csv | Käufer / Rechnungsempfänger | -b | ja |
items.csv | Rechnungspositionen, eine Zeile je Position | -p | ja |
totals.csv | Rechnungskopf, Summen und Umsatzsteuer-Aufschlüsselung | -t | ja |
allowances.csv | Zu- und Abschläge auf Rechnungsebene | -z | nur bei Bedarf |
deliverto.csv / deliverfrom.csv | abweichende Liefer- bzw. Versandanschrift | -h / -g | nur bei Bedarf |
Aufbau der CSV-Dateien
- Erste Zeile = Spaltennamen, darunter die Daten. In
items.csvfolgt eine Zeile je Position, in den anderen Dateien genau eine Datenzeile. - Zuordnung über den Spaltennamen: Groß-/Kleinschreibung und Reihenfolge der Spalten spielen keine Rolle. Nicht benötigte Spalten lassen Sie einfach weg.
- Beträge mit Punkt als Dezimaltrennzeichen (
59.50), Datumswerte alsJJJJMMTT. - Trennzeichen mit
-yangeben (z. B.,oder;). Werte, die das Trennzeichen enthalten, in Anführungszeichen setzen. - Zeichensatz mit
-cangeben: Standard istutf8; Programme, die Windows-ANSI schreiben (z. B. Delphi 5 bis 2007, VB6), nutzen-c ansi. - Mehrere Steuersätze: In
totals.csvstehen bis zu 11 Steuersätze – der erste in den SpaltenTAX…, weitere inTAX…1bisTAX…10(z. B.TAXBasisAmount1).
Getestetes Minimalbeispiel
Eine Rechnung über 10 × 5,00 € netto zu 19 %. Mit diesen vier Dateien erzeugt das SDK ein XML, das der KoSIT-Validator (XRechnung 3.0.2) ohne Fehler und ohne Warnungen annimmt (geprüft am 16.10.2026 mit der Funktion ImportCSV, die auch zugcmd verwendet).
seller.csv
Name,personname,Street1,city,phone,email,vat,country,postcode,iban,bic,paymentmeans,paymentdescription,accountname
Muster GmbH,Erika Muster,Hauptstr. 1,Hamburg,+49 40 123456,rechnung@muster.example,DE123456789,DE,20095,DE02120300000000202051,BYLADEM1001,58,SEPA-Überweisung,Muster GmbH
buyer.csv
id,Name,Street1,city,email,country,postcode
K-1001,Kunde AG,Marktplatz 5,München,einkauf@kunde.example,DE,80331
items.csv
AssignedID,productname,description,quantity,unit,netprice,netbasisquantity,netbasisunit,taxpercent,taxtypecode,taxcategorycode,totalamount
ART-100,Papier A4,500 Blatt,10,C62,5.00,1,C62,19,VAT,S,50.00
totals.csv
type,currency,invoiceid,invoicedate,DeliveryDate,leitwegid,LineTotalAmount,ChargeTotalAmount,AllowanceTotalAmount,TaxBasisTotalAmount,TaxTotalAmount,GrandTotalAmount,TotalPrepaidAmount,DuePayableAmount,PaymentTerms,duedate,TAXCalculatedAmount,TAXTypeCode,TAXBasisAmount,TAXCategoryCode,TAXRateApplicablePercent
380,EUR,RE-2027-0001,20270104,20270104,K-1001,50.00,0.00,0.00,50.00,9.50,59.50,0.00,59.50,Zahlbar innerhalb 30 Tagen netto,20270203,9.50,VAT,50.00,S,19
Die wichtigsten Spalten und ihre Business Terms
| Datei | Spalte | Bedeutung |
|---|---|---|
| totals.csv | type | Rechnungsart, BT-3 (380 Rechnung, 381 Gutschrift, 875 Abschlagsrechnung Bau) |
| totals.csv | invoiceid / invoicedate | Rechnungsnummer BT-1 / Rechnungsdatum BT-2 |
| totals.csv | currency | Währung, BT-5 |
| totals.csv | DeliveryDate | Leistungsdatum, BT-72 |
| totals.csv | leitwegid | Käuferreferenz bzw. Leitweg-ID, BT-10 |
| totals.csv | PaymentTerms / duedate | Zahlungsbedingungen BT-20 / Fälligkeitsdatum BT-9 |
| totals.csv | LineTotalAmount | Summe der Positionen, BT-106 |
| totals.csv | AllowanceTotalAmount / ChargeTotalAmount | Summe Abschläge BT-107 / Zuschläge BT-108 |
| totals.csv | TaxBasisTotalAmount | Nettobetrag, BT-109 |
| totals.csv | TaxTotalAmount | Umsatzsteuer gesamt, BT-110 |
| totals.csv | GrandTotalAmount / DuePayableAmount | Bruttobetrag BT-112 / Zahlbetrag BT-115 |
| totals.csv | TAXBasisAmount / TAXCalculatedAmount | Steuerbasis BT-116 / Steuerbetrag BT-117 je Steuersatz |
| totals.csv | TAXCategoryCode / TAXRateApplicablePercent | Steuerkategorie BT-118 (S, Z, E, AE, K …) / Steuersatz BT-119 |
| items.csv | quantity / unit | Menge BT-129 / Mengeneinheit BT-130 (z. B. C62 Stück, H87 Stück, KGM Kilogramm) |
| items.csv | netprice / netbasisquantity / netbasisunit | Nettopreis BT-146 je Basismenge BT-149 in Einheit BT-150 |
| items.csv | totalamount | Nettobetrag der Position, BT-131 |
Alle weiteren Spalten (Bestellnummer, Projekt, Vertrag, Rabatte je Position, globale Artikelnummer …) beschreiben die Seiten der einzelnen Dateien, verlinkt in der Tabelle oben.
Für eine gültige XRechnung braucht es außerdem die Käuferreferenz bzw. Leitweg-ID (leitwegid, BT-10), beim Verkäufer einen Kontakt mit Name, Telefon und E-Mail (personname, phone, email) und bei beiden Parteien eine E-Mail-Adresse.
Summen berechnet Ihre Anwendung
zugcmd übernimmt die Summen so, wie sie in totals.csv stehen. Die häufigsten Fehler:
- Steuerbasis bei Rabatten:
TAXBasisAmountist der Nettobetrag nach Abschlägen und Zuschlägen dieses Steuersatzes, nicht die Summe der Positionen – siehe BR-S-08, BR-S-09 und BR-CO-17. - Gerundete Positionen:
LineTotalAmountist die Summe der gerundeten Positionsbeträge (BR-CO-10). - Rundung nur auf den Zahlbetrag: siehe BR-CO-15 und BR-CO-16.
zugcmd aus der eigenen Anwendung starten
Sie müssen zugcmd nicht von Hand auf der Kommandozeile starten; Ihre Anwendung ruft es selbst auf. Neben zugcmd.exe enthält das Paket zugcmd_wnd.exe, die ohne Konsolenfenster läuft – praktisch für den Aufruf aus Programmen mit Oberfläche. Ein Aufruf für eine Rechnung (in einer Zeile):
zugcmd_wnd.exe -s "C:\ERechnung\stamm\seller.csv" -b "C:\ERechnung\RE-2027-0001\buyer.csv" -p "C:\ERechnung\RE-2027-0001\items.csv" -t "C:\ERechnung\RE-2027-0001\totals.csv" -i "C:\ERechnung\RE-2027-0001\RE-2027-0001.pdf" -x "C:\ERechnung\RE-2027-0001\RE-2027-0001.xml" -o "C:\ERechnung\RE-2027-0001\RE-2027-0001_zugferd.pdf" -y "," -c ansi -l IHR-LIZENZSCHLUESSEL
Immer vollständige Pfade angeben (mit Laufwerk und Ordner) oder mit -d ein Basisverzeichnis setzen, gegen das bloße Dateinamen aufgelöst werden. Ein bloßer Dateiname ohne -d wird nicht gefunden.
Den Erfolg erkennen Sie am Rückgabewert (ExitCode): 0 bedeutet Erfolg, z. B. 57 „Eingabe-PDF nicht gefunden“ oder 59 „XML konnte nicht erstellt werden“. Die vollständige Liste steht auf der zugcmd-Seite. Funktionen wie ShellExecute (Delphi) oder Shell (VB6) liefern den Rückgabewert nicht; nutzen Sie CreateProcess mit GetExitCodeProcess. Beispiel für Delphi (ab Version 5):
uses Windows, SysUtils;
function StarteZugcmd(const Parameter: string): DWORD;
var
SI: TStartupInfo;
PI: TProcessInformation;
Cmd: string;
begin
Result := DWORD(-1);
Cmd := '"C:\zugcmd\zugcmd_wnd.exe" ' + Parameter;
FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(SI);
if CreateProcess(nil, PChar(Cmd), nil, nil, False, 0, nil, nil, SI, PI) then
begin
WaitForSingleObject(PI.hProcess, INFINITE); // warten, bis zugcmd fertig ist
GetExitCodeProcess(PI.hProcess, Result); // 0 = Erfolg
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
end;
Dateinamen und Mengen
- Dateinamen bestimmt Ihre Anwendung mit
-x(XML) und-o(PDF), am besten mit der Rechnungsnummer. Ohne Angabe heißen die DateienOutputXML.xmlundOutputPDF.pdf; eine automatische Nummerierung gibt es nicht. - Viele Rechnungen (z. B. einige hundert pro Tag) sind kein Problem: ein Aufruf je Rechnung. Legen Sie die CSV-Dateien jeder Rechnung in einen eigenen Ordner oder geben Sie ihnen eindeutige Namen, damit sich parallele Aufrufe nicht gegenseitig überschreiben.
- Vorhandene Dateien überschreibt zugcmd standardmäßig; mit
-f falsebleiben sie erhalten.
Tipp: Zuordnung an einer echten Rechnung ansehen
zugcmd arbeitet auch rückwärts: -r rechnung.xml (oder ein ZUGFeRD-PDF) zerlegt eine vorhandene E-Rechnung in genau diese CSV-Dateien. So sehen Sie an einem echten Beispiel, welches Feld in welche Spalte gehört. Das Download-Paket zugcmd.zip (Downloads) enthält außerdem Beispiel-CSV-Dateien, bei denen die BT-Nummern direkt in den Werten stehen, zwei komplette Beispielsätze (Überweisung, Bankeinzug) und die readme.txt mit allen Parametern.
Wer lieber direkt programmiert, nutzt das SDK über COM: mit Delphi oder mit VB6, VB5 und VBA.
Häufige Fragen
Brauche ich Programmierkenntnisse für das SDK, um zugcmd zu nutzen?
Nein. Ihre Anwendung schreibt CSV-Dateien und startet zugcmd mit Parametern. Programmiert wird nur das Schreiben der CSV-Dateien und der Aufruf.
Gibt es eine Beschreibung der CSV-Spalten?
Ja. Jede Datei hat eine eigene Seite mit allen Spalten und Business Terms: seller.csv, buyer.csv, items.csv, totals.csv und allowances.csv. Die Spalten werden über ihren Namen zugeordnet, die Reihenfolge ist beliebig.
Muss zugcmd auf der Kommandozeile gestartet werden?
Nein. Jede Anwendung kann zugcmd als Prozess starten. zugcmd_wnd.exe läuft ohne Konsolenfenster; der Rückgabewert 0 bedeutet Erfolg.
Wie werden die erzeugten Dateien benannt?
So, wie Ihre Anwendung sie mit -x (XML) und -o (PDF) angibt, zum Beispiel nach der Rechnungsnummer. Ohne Angabe heißen sie OutputXML.xml und OutputPDF.pdf.
Schafft zugcmd 200 Rechnungen am Tag?
Ja. Pro Rechnung genügt ein Aufruf. Wichtig ist nur, dass jede Rechnung eigene CSV- und Ausgabedateien hat.
Verschickt zugcmd die Rechnung auch per E-Mail?
Nein. zugcmd erzeugt das XML und die ZUGFeRD-PDF; den Versand übernimmt Ihre Anwendung oder Ihr Mailprogramm.
Business Terms in diesem Artikel: BT-1 BT-2 BT-3 BT-10 BT-72 BT-106 BT-109 BT-112 BT-115 BT-116 BT-117 BT-5 BT-9 BT-20 BT-107 BT-108 BT-110 BT-118 BT-119 BT-129 BT-130 BT-131 BT-146