Infrastruktur-Nachrichten für den EDIFACT-Austausch: Empfangsquittungen, Fehlermeldungen und Freitext. Diese Nachrichten sind kein Geschäftsinhalt, sondern die technische Kommunikationsebene zwischen zwei EDI-Partnern.
import std.edi.messages;
import std.alloc;
import std.string;
fn Feld(p: int64, l: int64): pchar {
var b: int64 := alloc(l + 1);
var i: int64 := 0;
while (i < l) { poke8(b + i, peek8(p + i)); i := i + 1; }
poke8(b + l, 0);
return b as pchar;
}
fn main(): int64 {
var out: int64 := alloc(2048);
// 1. Positive Syntaxquittung auf den Interchange IC000042
var n: int64 := EdiContrlOk("IC000042"c, "4098765000004"c,
"4012345000009"c, out, 2048);
PrintLn(Feld(out, n));
var res: int64 := alloc(EDI_CONTRL_SIZE);
EdiContrlRead(out, n, res);
PrintLn(StrConcat("Status: ", IntToStr(peek64(res + EDI_CONTRL_STATUS))));
// 2. Ablehnung: Pflichtsegment fehlt, Segmentposition 12
n := EdiContrlErr("IC000042"c, 12, EDI_ERR_MISSING_SEG, out, 2048);
PrintLn(Feld(out, n));
EdiContrlRead(out, n, res);
PrintLn(StrConcat(StrConcat("Status: ", IntToStr(peek64(res + EDI_CONTRL_STATUS))),
StrConcat(" Fehlercode: ", IntToStr(peek64(res + EDI_CONTRL_ERRCODE)))));
// 3. Fachliche Ablehnung (APERAK)
n := EdiAperakWrite("BST-2026-0815"c, 14,
"Artikel 04012345678918 unbekannt"c, out, 2048);
PrintLn(Feld(out, n));
var ap: int64 := alloc(EDI_APERAK_SIZE);
EdiAperakRead(out, n, ap);
PrintLn(StrConcat("APERAK-Text: ", Feld(peek64(ap + EDI_APERAK_TEXT), peek64(ap + EDI_APERAK_TEXTLEN))));
return 0;
}
UNB+UNOA:1+4098765000004+4012345000009+000000:0000+IC000042'UNH+1+CONTRL:1:901:UN'UCI+IC000042+4012345000009+4098765000004+7'UNT+3+1'UNZ+1+IC000042'
Status: 7
UNB+UNOA:1+++000000:0000+IC000042'UNH+1+CONTRL:1:901:UN'UCI+IC000042+++4+25+12'UNT+3+1'UNZ+1+IC000042'
Status: 4 Fehlercode: 25
BGM+313++9'RFF+ACE:BST-2026-0815'ERC+14'FTX+AAO++Artikel 04012345678918 unbekannt'
APERAK-Text: Artikel 04012345678918 unbekannt
CONTRL bringt seinen Umschlag selbst mit.EdiContrlOkundEdiContrlErrschreiben einen vollständigen Interchange von UNB bis UNZ — anders als die Fachnachrichten (ORDERS, INVOIC …), die nur den Rumpf liefern und den Umschlag ausstd.edi.corebrauchen. Das Datum bleibt dabei auf000000:0000; wer ein echtes Datum braucht, baut die Quittung von Hand mitEdiUnbWrite.
EdiContrlErrträgt keine Partner-IDs ein (die Felder bleiben leer) — für den Versand an einen konkreten Partner den Umschlag selbst erzeugen.
std.edi.corestd.alloc| Offset-Konstante | Inhalt |
|---|---|
EDI_CONTRL_STATUS | Status: 7=akzeptiert, 4=abgelehnt (Gruppen-Ebene), 5=abgelehnt (Nachrichten-Ebene) |
EDI_CONTRL_ERRCODE | UN/EDIFACT-Fehlercode (0 = kein Fehler) |
EDI_CONTRL_SEGPOS | Position des fehlerhaften Segments (0 = Interchange-Ebene) |
EDI_CONTRL_ICREF / EDI_CONTRL_ICREFLEN | Zeiger auf die ICR des quittierten Interchange |
Status-Konstanten:
| Konstante | Wert | Bedeutung |
|---|---|---|
EDI_CONTRL_ACCEPTED | 7 | Interchange vollständig akzeptiert |
EDI_CONTRL_REJECTED4 | 4 | Funktionale Gruppe abgelehnt |
EDI_CONTRL_REJECTED5 | 5 | Nachricht abgelehnt |
Standard-Fehlercodes (UN/EDIFACT S005):
| Konstante | Wert | Bedeutung |
|---|---|---|
EDI_ERR_SYNTAX_VER | 2 | Syntax-Version nicht unterstützt |
EDI_ERR_TEST_FLAG | 7 | Testflag-Mismatch |
EDI_ERR_INVALID_VALUE | 14 | Ungültiger Wert |
EDI_ERR_MISSING_SEG | 25 | Pflicht-Segment fehlt |
| Offset-Konstante | Inhalt |
|---|---|
EDI_APERAK_ERRCODE | Anwendungs-Fehlercode |
EDI_APERAK_REFMSG / EDI_APERAK_REFLEN | Zeiger auf referenzierte Nachrichten-ID |
EDI_APERAK_TEXT / EDI_APERAK_TEXTLEN | Zeiger auf Fehlertext |
| Offset-Konstante | Inhalt |
|---|---|
EDI_GENRAL_SUBJECT / EDI_GENRAL_SUBJLEN | Betreff (aus BGM/C002) |
EDI_GENRAL_BODY / EDI_GENRAL_BODYLEN | Textkörper — alloziert, Caller muss freigeben |
EDI_GENRAL_REFMSG / EDI_GENRAL_REFLEN | Referenz auf die zugrundeliegende Nachricht |
Achtung GENRAL-Body: EdiGenralRead alloziert einen Puffer für den zusammengesetzten FTX-Inhalt. Nach der Verarbeitung freigeben mit:
free(peek64(result + EDI_GENRAL_BODY), peek64(result + EDI_GENRAL_BODYLEN));
| Signatur | Beschreibung |
|---|---|
EdiContrlOk(icRef: int64, senderId: int64, receiverId: int64, out: int64, outMax: int64): int64 | Schreibt positive CONTRL-Quittung (UCI-Status 7) |
EdiContrlErr(icRef: int64, segPos: int64, errCode: int64, out: int64, outMax: int64): int64 | Schreibt negative CONTRL-Quittung mit Fehlerposition und -Code |
EdiContrlRead(buf: int64, bufLen: int64, result: int64): int64 | Parst CONTRL; befüllt result (EDI_CONTRL_SIZE). Gibt EDI_OK oder Fehlercode. |
| Signatur | Beschreibung |
|---|---|
EdiAperakWrite(refMsgId: int64, errCode: int64, errText: int64, out: int64, outMax: int64): int64 | Schreibt APERAK-Nachricht; errText ist null-terminiert (oder 0 für kein Text) |
EdiAperakRead(buf: int64, bufLen: int64, result: int64): int64 | Parst APERAK; befüllt result (EDI_APERAK_SIZE) |
| Signatur | Beschreibung |
|---|---|
EdiGenralWrite(subject: int64, body: int64, refMsgId: int64, out: int64, outMax: int64): int64 | Schreibt GENRAL; body wird als FTX-Segmente eingebettet |
EdiGenralRead(buf: int64, bufLen: int64, result: int64): int64 | Parst GENRAL; alloziert Puffer für Body — nach Gebrauch freigeben |
import std.edi.messages;
import std.alloc;
import std.string;
fn main(): int64 {
var out: int64 := alloc(2048);
var n: int64 := EdiContrlErr("IC000042"c, 5, EDI_ERR_INVALID_VALUE, out, 2048);
var res: int64 := alloc(EDI_CONTRL_SIZE);
EdiContrlRead(out, n, res);
if (peek64(res + EDI_CONTRL_STATUS) == EDI_CONTRL_ACCEPTED) {
PrintLn("Interchange akzeptiert.");
} else {
PrintLn(StrConcat("Interchange abgelehnt, Fehlercode: ",
IntToStr(peek64(res + EDI_CONTRL_ERRCODE))));
PrintLn(StrConcat("Fehlerhaftes Segment: ",
IntToStr(peek64(res + EDI_CONTRL_SEGPOS))));
}
free(res, EDI_CONTRL_SIZE);
free(out, 2048);
return 0;
}
Interchange abgelehnt, Fehlercode: 14
Fehlerhaftes Segment: 5
EdiAperakWrite kürzt den Fehlertext auf EDI_FTX_MAX (512 Zeichen).EdiGenralRead legt für den zusammengesetzten FTX-Text einen eigenen Puffer an. Nach Gebrauch mit free(peek64(result + EDI_GENRAL_BODY), peek64(result + EDI_GENRAL_BODYLEN)) freigeben — das ist die einzige Stelle in std.edi, an der die Bibliothek selbst alloziert."IC000042"c as int64); nur segPos und errCode sind echte Zahlen.| Unit | Datei |
|---|---|
std.edi.messages | std/edi/messages.lyx |
Letzte Aktualisierung: 2026-08-13 — Beispiele lauffähig gemacht und ausgeführt (lyxc 1.0.17K); festgehalten, dass CONTRL einen vollständigen Interchange erzeugt (Fachnachrichten dagegen nur den Rumpf) und dass EdiContrlErr keine Partner-IDs setzt
Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die pub fn-Signaturen in aurum/std gehalten, 0 Abweichungen).