Die normierte Programmierung (NP) beschreibt eine standardisierte Ablaufsteuerung eines Datenverarbeitungsprogramms. Sie war in DIN 66220 genormt und wurde mit DIN 66260 in Richtung strukturierte Programmierung weiterentwickelt. Beide Ansätze unterstützten die modulare Programmierung.

Normierte Programmierung ist eine verallgemeinerte Programmablaufsteuerung, die die Teilaufgaben eines Stapelprogrammes wie Dateneingabe, Gruppenkontrolle, Verarbeitung / Ausgabe in ein einheitliches, logisch klares, funktionelles Schema gliedert. Für Programme mit solchen Aufgaben lässt sich dieses Schema unabhängig von der fachinhaltlichen Aufgabenstellung und „technologieneutral“ (z. B. in jeder imperativen/prozeduralen Programmiersprache) anwenden.

Historischer Rückblick Zur Zeit der Entstehung der normierten Programmierung Ende der 1960er Jahre für die kommerzielle Datenverarbeitung gab es lediglich Stapelprogramme: sequentielle Dateien, in denen je nach Aufgabenstellung unterschiedliche 'Satzarten' gemischt/hintereinander auftraten, weil z. B. nur eine Magnetbandstation oder ein Lochkartenleser für die Eingabe verfügbar war. Ein Mischen im Programm war so nicht erforderlich und wäre bei Arbeitsspeichern von z. B. 64 KB inkl. Betriebssystem auch zu aufwändig gewesen. So las das Programm 'seine' Eingabedatei und verarbeitete einen Datensatz nach dem anderen. Über ein Datenfeld 'Satzart' wurden die Datenarten (Kunde, Bestellung …) inhaltlich unterschieden und über Ordnungsbegriffe einander zugeordnet. Das Programm 'lief' (mit GOTO) je nach Datenkonstellation zu bestimmten Stellen, zum Beispiel zu Rechenvorgängen, zum Drucken einer Listenzeile, um Daten nachzulesen und ebenfalls zu verarbeiten – und letztlich zum Programmende. Die Programme waren oft 'Spaghetticode', folgten kaum einheitlichen Strukturvorgaben und waren deshalb intransparent, fehleranfällig und änderungsunfreundlich.

Leistungsfähigere Rechner, neue Programmiersprachen, aber auch Fortschritte in den Methoden zur Softwareentwicklung führten sukzessive zu besseren Lösungen: Es entstanden Vorschläge für eine standardisierte Struktur von Stapelprogrammen. Darin war die gesamte Steuerung des Programms in eindeutig definierte 'Routinen' zergliedert, die die aufgabenspezifischen Verarbeitungsteile des Programms aufrufen – die 'Normierte Programmierung'.

Allerdings werden in der Praxis der (individuellen) Softwareentwicklung derart standardisierte Verfahren oft nicht angewendet – mit der Folge, dass das Erstellen des Programmcodes zur Programmsteuerung in vielen Fällen eine besondere Herausforderung bzw. 'Problemstellung' für die Entwickler blieb, die nicht selten hohen Entwicklungsaufwand verursacht und beim Softwaretest Fehler zutage fördert.

Zielsetzung

Laut einem kleinen Lehrbuch eines großen BUNCH-Computerherstellers von 1971 mit dem Titel Logik der Programmierung, Normierte Programmierung, mit dem damals angehende Programmierer und Systemanalytiker ausgebildet wurden, wurden als Ziele der normierten Programmierung bezeichnet. Dementsprechend sind diese Ziele dann von Bedeutung, wenn in einer Organisation mehrere/viele Entwickler Software mit Entwicklungswerkzeugen herstellen, in denen die Steuerungsfunktionen der Normierten Programmierung nicht als integrierter Bestandteil enthalten sind.

Die normierte Programmierung Kernstück der normierten Programmierung ist die Programmablaufsteuerung. Die normierte Programmierung erzwingt die logische und funktionelle Ordnung eines Programms durch eine vereinheitlichte Programmablaufsteuerung, die unabhängig vom jeweiligen Programmierer ist. Da die Ablaufsteuerung explizit vom Programmierer festgelegt wird, lässt sich die Softwareentwicklung nach der normierten Programmierung dem Programmierparadigma der imperativen/prozeduralen Programmierung zuordnen.

Stapelprogramme haben dabei unabhängig von ihrer individuellen Aufgabenstellung immer dieselbe Struktur. Das heißt: Identische Bezeichnungen für die Verarbeitungsprozeduren; identische Steuerungslogik (die Blöcke B bis E sind nur auf die konkrete Aufgabenstellung wie Anzahl Dateien, Gruppenbegriffe … eingestellt). Die aufgabenspezifische Verarbeitung ist ausschließlich in Prozeduren der Blöcke G bis J, ggf. A und F enthalten.

Das Schema der Programmablaufsteuerung rechts|Blockunterteilung der normierten Programmierung Der Programmablauf ist in Blöcke unterteilt, wobei jeder Block einen funktional zusammengehörigen Teil eines Programmes darstellt. Die Unterteilung stellt sozusagen den „natürlichen“ Aufbau eines kommerziellen Programms dar: Vor Beginn der eigentlichen Verarbeitung sind Anfangswerte zu setzen und Steuerinformationen auszuwerten, dann sind Eingabedaten zu lesen, der nächste Satz zur Verarbeitung ist auszuwählen, eventuell müssen Gruppenwechsel behandelt werden, schließlich ist der Datensatz zu verarbeiten und gegebenenfalls sind Daten auszugeben. Jeder Block stellt eine in sich geschlossene Einheit dar. Ein Block kann zur besseren Übersicht aus mehreren Unterblöcken bestehen. Der abgebildete Programmablaufplan zeigt folgende Blöcke:

A: Vorprogramm für alle einmalig durchzuführenden Programmschritte B: Eingabe; sie besteht aus so vielen Unterblöcken wie es serielle Eingabedateien gibt. In jedem dieser Blöcke wird nicht nur die eigentliche Eingabe abgehandelt, sondern auch Plausibilitätsprüfungen und Reihenfolgekontrolle. C: Satzfreigabe; aus den gelesenen Sätzen je Datei wird ausgewählt, welcher Datensatz als nächster zu verarbeiten ist – und (vorher) zur Feststellung von Gruppenwechseln verwendet wird. D: Gruppenkontrolle und Aufruf der Gruppenwechsel-Unterprogramme für alle Gruppenstufen. E: Einzelverarbeitung; sie ist wiederum entsprechend der Anzahl Eingabedateien in Unterblöcke unterteilt. F: Schlussprogramm für alle einmalig nach dem eigentlichen Programmablauf zu durchlaufenden Programmbefehle. G: Unterprogramme der Gruppenverarbeitung; es gibt so viele Unterprogramme wie es Gruppenstufen gibt, jeweils für Vorläufe und Nachläufe getrennt. H: Unterprogramme der Einzelverarbeitung; diese Unterprogramme sollten möglichst klein und übersichtlich sein. J: Unterprogramme der sequentiellen Ausgabe und der wahlfreien Ein-/Ausgabe; für jede der genannten Dateien gibt es ein Unterprogramm.

Die Datenzufuhrsteuerung Eine wesentliche Teilfunktion in der Normierten Programmierung ist die Automatik der ‚Datenzufuhr‘. Aus jeder Eingabedatei wird jeweils genau ein Datensatz gelesen – bis zum Dateiende inklusive. Aus den aktuellen (zuletzt gelesenen) Sätzen aller Dateien wird der nächste zu verarbeitende Satz ermittelt und der Verarbeitung zugeführt. Anschließend wird exakt aus dieser Datei wieder nachgelesen. Umgesetzt wird diese Art der Datenzufuhr in den Blöcken Eingabe und Satzfreigabe.

Gruppenbegriffsfelder rechts|Gruppenbegriffsfelder Normierte Programmierung Der zentrale Schlüssel für die Steuerung des Programmablaufs ist der Gruppenbegriff, der in jedem Satz der Eingabedateien enthalten sein muss. Da die Gruppenbegriffe an unterschiedlichen Positionen der Eingabedateien liegen können, werden bei der normierten Programmierung die Gruppenbegriffe aus den Datensätzen herausgeholt und in separaten dateibezogenen Gruppenbegriffsfeldern von links nach rechts nach der Gruppenstufenhierarchie absteigend gespeichert. Es gibt für jede Eingabedatei ein solches, bei allen Dateien gleich großes und gleich-formatiges Gruppenbegriffsfeld – deshalb dateibezogen. Im Beispiel besteht das Gruppenbegriffsfeld der Eingabedatei 2 von rechts nach links aus der Dateinummer L2D („2“), den Gruppenbegriffen L21 (Untergruppenbegriff), L22 (Hauptgruppenbegriff), L23 (Übergruppenbegriff), L24 (ein noch höherer Gruppenbegriff) und aus dem Feld L2S für den Dateistatus. Die Felder Ln1 bis Ln4 können gemeinsam als LnM zur Paarigkeitsprüfung herangezogen werden. Die Namen der Felder wurden in Anlehnung an die damals weit verbreitete Terminologie von RPG (Report Program Generator) vergeben (L für Level, Gruppenstufe).

Neben den dateibezogenen Gruppenbegriffsfeldern gibt es zwei weitere, dateineutrale Felder, die für die Gruppenkontrolle verwendet werden: LA enthält den Gruppenbegriff des letzten verarbeiteten Satzes LN enthält den Gruppenbegriff des nächsten zu verarbeitenden Satzes Die Größe stimmt mit der Größe der dateibezogenen Felder L0, L1, … voll überein. Lediglich die Definition der Felder ist aus Zweckmäßigkeitsgründen für die Gruppenkontrolle anders gewählt worden. Im Beispiel dient das Feld LN1 zur Kontrolle der Untergruppe, das Feld LN2 der Kontrolle der Hauptgruppe usw.

Die Datei-Nummer Nach Eingabe eines Satzes von jeder Datei muss von allen Sätzen jener ausgewählt werden, der als Nächstes verarbeitet werden soll. Bei unterschiedlichen Gruppenbegriffen ist die Lösung einfach, der Satz mit dem kleinsten Gruppenbegriff ist als nächster zu verarbeiten. Sind die Gruppenbegriffe jedoch gleich (paarig), muss entschieden werden, welche Datei die höhere Priorität hat, d. h. die Dateinummer bestimmt die Priorität. Bei dem klassischen Fall einer Gegenüberstellung von Stamm- (z. B. Teilestamm) und Bewegungsdaten (z. B. Lagerbewegungen) bestimmen die Bewegungsdaten, ob die Stammdaten bearbeitet werden müssen oder nicht, der Bewegungssatz muss also als erster verarbeitet werden. Die Dateinummer – eine Konstante – bestimmt bei Paarigkeit der restlichen Gruppenbegriffe die Reihenfolge (Priorität) der Verarbeitung.

Der Datei-Status Der Dateistatus unterscheidet vier Zustände: 0 = Satz nachziehen 1 = Satz nicht nachziehen 2 = Datei abgeschlossen 3 = Datei nicht vorhanden Am Anfang stehen die Zustände aller Eingabedateien auf 0 („Satz nachziehen“). Nach dem Nachziehen einer Datei wird ihr Status auf 1 gesetzt. Erst wenn sie zur Verarbeitung freigegeben wird, wird der Status wieder auf 0 gesetzt. Der Status 3 kann z. B. auf Grund von Vorlaufdaten Ablaufvarianten mit unterschiedlichen oder vorhandenen/nicht vorhandenen Dateien steuern.

Der Steuerungsmechanismus Die Steuerung des Programms geschieht (grob) nach der Logik wie sie im Schaubild 'Blockunterteilung der normierten Programmierung' dargestellt ist. Von hier aus werden alle Subroutinen der Verarbeitung (A bis G) angesteuert. Grundlage dazu sind die dateibezogenen und die dateineutralen Gruppenbegriffsfelder, wie sie beim Lesen und in der Satzfreigabe bereitgestellt werden.

Der Aufbau der Blöcke Block A: Vorprogramm Hier werden Aktionen durchgeführt, die zu Beginn des Programms erforderlich sind. Beispiele: Einlesen von Parametern (z. B. als 'Vorlaufkarten' zur Festlegung des Laufdatums oder von Laufvarianten); Initialisieren/Laden von Lookup-Tabellen und anderen Datenbereichen; Dateien eröffnen (OPEN); Schalter setzen; einmalige Ausgabe von Titelzeilen; kurz alle einmaligen Arbeiten vor Beginn des von den Eingabedaten abhängigen Verarbeitungszyklus.

Block B: Eingabe Der Block B ist je nach der Anzahl der sequentiellen Eingabedateien in Unterblöcke B0, B1, B2, … unterteilt, die nacheinander durchlaufen werden. Je nach Dateistatus wird ein Satz gelesen oder nicht. Direkt nach dem Lesen erfolgt die Prüfung auf Dateiende. Falls ja, wird der Dateistatus auf „Dateiende“ gesetzt, andernfalls auf „nicht nachziehen“ und die dateispezifischen Gruppenbegriffsfelder werden gefüllt.

Wenn nicht gesichert ist, dass eine Eingabedatei immer in der richtigen Sortierfolge vorliegt, sollten in diesem Block eine Reihenfolgekontrolle oder andere Plausibilitätsprüfungen stattfinden – ggf. mit vorzeitigem Programmabbruch.

Auch kann hier evtl. ein Filtern, d. h. Überlesen bestimmter Datensätze stattfinden – die damit auch keine Gruppenwechsel auslösen.

Block C: Satzfreigabe mini|Datenzufuhrsteuerung und Gruppenwechselverarbeitung