Kapitel 4. Die COBOL-Sprache

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

COBOL ist die Standardsprache für die Entwicklung von Mainframe-Anwendungen. Sie verfügt über die Funktionen, die für geschäftliche Anwendungsfälle wichtig sind, wie z. B. die Verarbeitung von umfangreichen Stapelverarbeitungsaufträgen und Transaktionen.

Die Sprache COBOL hat über 350 Befehle - und viele davon wirst du nicht kennen müssen. Deshalb werden wir in diesem Buch nur eine begrenzte Anzahl behandeln. Das soll aber nicht heißen, dass du im Nachteil bist. Wir werden uns auf die wichtigsten Befehle konzentrieren, die du für praktische Anwendungen kennen musst.

Der Hintergrund von COBOL, in Kürze

COBOL ist eine der ältesten Computersprachen. Dennoch hat sie sich über die Jahre hinweg bewährt und ist nach wie vor von zentraler Bedeutung für die Unternehmensinformatik.

Die Wurzeln der Sprache reichen bis in die späten 1950er Jahre zurück, als eine Vielzahl von Computersprachen aufkam. Viele dieser Sprachen waren sehr komplex. Das bedeutete, dass die Entwicklung zeitaufwändig und teuer war.

Es wurde eine Standardsprache für die Datenverarbeitung benötigt. Um dies zu erreichen, schloss sich das US-Verteidigungsministerium mit einer Gruppe von Computerunternehmen - darunter IBM, Burroughs Corporation, Honeywell und RCA - sowie mit Akademikern und Kunden zusammen und gründete den Ausschuss der Conference on Data Systems Languages (CODASYL). Solche Ausschüsse waren für die Entwicklung der Sprache von entscheidender Bedeutung.

Hinweis

CODASYL betrachtete die Sprache FLOW-MATIC als Vorbild für COBOL. Die legendäre Computerpionierin Grace Hopper schuf FLOW-MATIC, die erste Sprache, die englischsprachige Befehle für die Datenverarbeitung verwendete und für frühe Großrechnersysteme wie UNIVAC I eingesetzt wurde.

Eine der wichtigsten Überlegungen bei der Entwicklung von CODASYL war es, COBOL auf verschiedenen Computern laufen zu lassen. Außerdem war es auf die Bedürfnisse von Unternehmen ausgerichtet, z. B. bei der Buchhaltung und der Kundenberichterstattung. Dieser Schwerpunkt ist auch heute noch derselbe. Tatsächlich kannst du mit COBOL keine Websites oder mobile Apps erstellen. Es geht ausschließlich um Geschäftsanwendungen.

Hinweis

Der CODASYL-Ausschuss brachte mehrere Ideen für die COBOL-Sprache ein. Einige davon waren Information System Language (INFOSYL), Business System (BUSY) und Common Computer Systems Language (COCOSYL). Letztendlich entschied sich der CODASYL-Ausschuss aber für COBOL, obwohl nicht klar ist, warum.

COBOL-Versionen

Die erste Version von COBOL, COBOL 60 genannt, kam 1959 heraus. Sie hatte sicherlich ihre Schwächen, und einige Leute sagten voraus, dass die Sprache nicht lange überleben würde. Aber die Computerindustrie unternahm Schritte, um die Probleme zu lösen und die Sprache zu verbessern, insbesondere durch die Entwicklung von Compilern. Dann wurden neue Funktionen, wie z. B. Tabellen, hinzugefügt.

Als die Sprache jedoch immer beliebter wurde, traten mehr Inkompatibilitäten auf. Deshalb übernahm das America Standards Institute - heute American National Standards Institute (ANSI) - die Aufgabe, einen Standard für COBOL zu erstellen. Dies geschah 1968 und wurde COBOL X3.23 genannt.

Das soll nicht heißen, dass der CODASYL-Ausschuss keine Rolle mehr spielte. Die Organisation würde weiterhin die Sprache erneuern.

Aber in den 1980er Jahren hatte COBOL wieder Probleme mit der Kompatibilität. Deshalb wurde eine neue Version herausgegeben, die COBOL 85 genannt wurde.

In den 1990er Jahren waren weitere Änderungen erforderlich, und es wurde an einer neuen Version gearbeitet, die modernere Ansätze wie die objektorientierte Programmierung übernehmen sollte. Die neue Version der Sprache wurde COBOL 2002 genannt.

Okay, was ist die neueste Version? Es ist COBOL V6.3, das im September 2019 ausgeliefert wurde.

Trotzdem verwenden viele Unternehmen noch ältere Versionen, wie COBOL 85. Deshalb ist es wichtig, die Geschichte der Sprache zu verstehen. Bei Mainframe-Systemen werden neue Ansätze in der Regel langsamer eingeführt. Ein wichtiger Grund dafür ist, dass Unternehmen in der Regel keine größeren Änderungen an ihren geschäftskritischen Systemen vornehmen wollen.

Warum COBOL?

COBOL ist keine Allzwecksprache. Ihr Hauptaugenmerk liegt auf der Datenverarbeitung. Aber die Spezialisierung und die lange Geschichte von COBOL haben dazu geführt, dass die Sprache allgegenwärtig ist. Hier sind einige Zahlen, die du beachten solltest:

  • Jeden Tag werden 200 Mal mehr COBOL-Transaktionen durchgeführt als Google-Suchen.

  • Heute laufen mehr als 220 Milliarden Codezeilen, das sind etwa 80 % der weltweiten Gesamtmenge.

  • Jedes Jahr werden etwa 1,5 Milliarden neue COBOL-Zeilen geschrieben.

Dr. Cameron Seay, Co-Vorsitzender der Open Mainframe Project COBOL Working Group und Lehrbeauftragter an der East Carolina University, sagt: "COBOL ist nach wie vor eine wichtige Sprache für die globale Wirtschaft. Die Liste der Organisationen, die COBOL verwenden, umfasst auch die meisten großen Bundes- und Landesbehörden. Heute ist COBOL unersetzlich, und es gibt keine Anzeichen dafür, dass sich das ändern wird."

Was sind einige der Vorteile von COBOL? Warum hat sich die Sprache so lange bewährt? Hier sind einige der Hauptgründe:

Skala

COBOL ist für die Verarbeitung großer Datenmengen konzipiert. Die Sprache verfügt über eine breite Palette von Funktionen zur Erstellung von Datenstrukturen und zum Zugriff auf diese.

Stabilität

Die COBOL-Sprache ist rückwärtskompatibel. Daher müssen die Unternehmen ihre Systeme nicht regelmäßig neu programmieren.

Einfachheit

Auch hier war die ursprüngliche Vision für COBOL, dass es einfach zu benutzen ist. Man musste kein Mathematiker sein, um es zu lernen. Es stimmt, dass die Sprache wortreich sein kann. Aber das hat auch einen Vorteil. In gewisser Weise ist die Sprache selbstdokumentierend (obwohl es immer noch eine gute Idee ist, eine eigene Dokumentation zu erstellen).

Prüfbarkeit

Auch wenn du COBOL nicht verstehst, kannst du die Befehle lesen und dir einen Überblick über die Arbeitsabläufe verschaffen. Ein entscheidender Vorteil ist, dass ein nicht-technischer Prüfer den Code überprüfen kann.

Struktur

COBOL hat eine Reihe von vordefinierten Möglichkeiten, um Programme zu erstellen, z. B. mit Unterteilungen, Abschnitten und Absätzen (mehr dazu erfährst du in diesem Kapitel). Das macht es für jemanden, der den Code nicht geschrieben hat, einfach, ihn zu verstehen.

Geschwindigkeit

COBOL ist eine kompilierte Sprache, was bedeutet, dass ein Programm auf die 1en und 0en reduziert wird, die ein Computer verstehen kann. Dadurch wird die Leistung im Allgemeinen schneller als bei einer interpretierten Sprache (die einen Zwischenübersetzer enthält, der den Code während der Laufzeit umwandelt).

Flexibilität

Die Standardsprache COBOL verfügt über einen großen Funktionsumfang und hat sich in intensiven Unternehmensumgebungen gut bewährt. Aber es gibt eine Vielzahl von Erweiterungen, z. B. für Datenbanken und Transaktionssysteme. Das hat COBOL vielseitiger gemacht.

Mathe

COBOL hat eine Reihe von Funktionen, die die Währungsmanipulation und -formatierung erleichtern. In anderen Sprachen muss man dafür normalerweise kodieren.

COBOL-Programmstruktur: Spalten

Ein COBOL-Programm hat eine klare Struktur, bei der der Code in 80 Spalten angeordnet ist. Diese Zahl stammt noch aus der Zeit der Lochkarten.Abbildung 4-1 zeigt das Layout.

mmfd 0401
Abbildung 4-1. Das Layout von 80 Spalten für COBOL-Code

Hier ist ein Blick auf die Spalten:

1-6

Das ist für die Zeilennummern. Als noch Lochkarten verwendet wurden, war das hilfreich, da sie manchmal auf den Boden fielen und verstreut wurden. Aber in der heutigen Zeit werden die Spalten 1-6 nicht mehr verwendet.

7

Dies kann für verschiedene Zwecke verwendet werden. Wenn du ein Sternchen (*) in die Spalte setzt, kannst du einen Kommentar schreiben, um den Code zu dokumentieren. Abbildung 4-1 zeigt einen Kommentar in der Sequenzzeile 000012. Du kannst den Bindestrich (-) auch als Fortsetzungszeile für eine lange Zeile von Zeichen, ein sogenanntes Literal, verwenden. Dies dient vor allem der Lesbarkeit. Hier ein Beispiel:

'123ad53535d3506968223dcs9494029dd3393'
- '8301sd0309139c3030eq303'

Die Literale können entweder Zeichenketten oder Zahlen sein.

8-11

Dies ist der sogenannte A-Rand oder Bereich A. Hier platzieren wir die Hauptüberschriften für den Code, zu denen die Abteilungs-, Abschnitts-, Absatz- und Ebenennummern (01 und 77) gehören, über die du später mehr erfahren wirst. In Abbildung 4-1 befinden sich IDENTIFICATION DIVISION und PROCEDURE DIVISION im Bereich A.

12-72

Das ist der sogenannte B-Rand oder Bereich B. Hier wird ein Großteil des Codes eingefügt.

73-80

Dies wird in der COBOL-Entwicklung nicht mehr verwendet.

COBOL-Programmstruktur: Abteilungen

COBOL-Programme sind außerdem in vier Abteilungen unterteilt, die in der folgenden Reihenfolge sein müssen (jede endet mit einem Punkt):

  • IDENTIFICATION DIVISION.

  • ENVIRONMENT DIVISION.

  • DATA DIVISION.

  • PROCEDURE DIVISION.

Jede dieser Ebenen kann weitere Code-Ebenen enthalten. Dazu gehören Abschnitte, Absätze und Sätze. Und alle enden mit einem Punkt, wenn sie sich in einer der Abteilungen befinden, mit Ausnahme von PROCEDURE DIVISION. Ansonsten hat nur der Absatz einen Punkt. Zugegeben, das alles mag etwas verworren und unflexibel erscheinen. Aber wie gesagt, in einem Geschäftsumfeld ist es wichtig, eine solide Struktur zu haben. Außerdem ist der Ansatz von COBOL ziemlich intuitiv, wenn man sich erst einmal daran gewöhnt hat. In den nächsten Abschnitten werden wir uns die Struktur genauer ansehen.

ERKENNUNGSTEIL

Die IDENTIFICATION DIVISION ist die einfachste Division, mit der du arbeiten kannst. Du brauchst nur zwei Zeilen:

IDENTIFICATION DIVISION.
PROGRAM-ID. CUSTRP.

Die PROGRAM-ID ist erforderlich, weil der Name für die Kompilierung des Programms verwendet wird. Der Name kann bis zu 30 Zeichen lang sein und muss eindeutig sein. Aber ein Großrechnerbetrieb hat normalerweise seine eigenen Anforderungen (eine typische Länge sind bis zu acht Zeichen).

Einige Codierer können die IDENTIFICATION DIVISION erweitern, z. B. mit denfolgenden Angaben:

IDENTIFICATION DIVISION.
PROGRAM-ID. CUSTRP.
AUTHOR.  JANE SMITH.
DATE-WRITTEN.  01/01/2021
**************************************************************
*  This program will generate a customer report   *
**************************************************************

Details wie AUTHOR und DATE-WRITTEN sind nicht üblich. Aber ein Kommentarfeld wird oft verwendet.

Hinweis

COBOL unterscheidet nicht zwischen Groß- und Kleinschreibung. Du kannst einen Befehl wie DIVISION als Division oder division oder sogar divIsion schreiben. Es spielt keine Rolle. In den meisten Fällen werden die Befehle in COBOL jedoch groß geschrieben.

UMWELTABTEILUNG

Die ENVIRONMENT DIVISION wird für den Zugriff auf Dateien verwendet, z. B. für die Stapelverarbeitung, was in COBOL üblich ist. In der Regel wird es aber nicht verwendet, wenn ein Programm für Online-Traktionen gedacht ist (das wäre bei Befehlen wie ACCEPT der Fall, um Benutzereingaben zu erhalten).

Die ENVIRONMENT DIVISION besteht aus zwei Teilen. Der eine ist die CONFIGURATION SECTION, die Informationen über den Computer und bestimmte Einstellungen (z. B. für die Währung) enthält:

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
   SOURCE-COMPUTER. IBM ENTERPRISE Z/OS.
   OBJECT-COMPUTER. VAX-6400.
   SPECIAL-NAMES.
   CURRENCY IS DOLLARS.

Als Nächstes folgt die INPUT-OUTPUT SECTION. Hier stellt ein Programm Verbindungen zu Dateien her:

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
 SELECT CUSTOMER-FILE ASSIGN TO CUSTOMERMAST
	ORGANIZATION IS SEQUENTIAL.

CUSTOMER-FILE ist der interne Name, mit dem wir die Datei im COBOL-Code bezeichnen. Dieser Name wird dann mit CUSTOMERMAST verknüpft. So identifiziert das Mainframe-Dateisystem die Datei. Um diese Verbindung herzustellen, erstellst du eine Datendefinitionsanweisung (DD) in der Job Control Language (JCL), die auf diese Datei verweist. Außerdem können der interne Name und der Dateiname identisch sein.

Warum das alles? Der Hauptgrund ist, dass, wenn sich der Name der Datei auf der Festplatte ändert, nur der Name DD in der JCL geändert werden muss. Dadurch kann eine Menge Nacharbeit am Quellcode vermieden werden.

Schließlich kann der Befehl SELECT verschiedene Parameter haben. In unserem Beispiel zeigt ORGANIZATION, wie die Datensätze in der Datei verarbeitet werden (ein Datensatz nach dem anderen).

DATA DIVISION

Wenn du in COBOL entwickelst, verbringst du in der Regel viel Zeit damit, die Datenstrukturen zu erstellen. Dies geschieht in der DATA DIVISION, die aus drei Hauptabschnitten besteht: WORKING-STORAGE SECTION, FILE-SECTION, und LINKAGE-SECTION.

Die ersten beiden werden wir als nächstes behandeln. Die LINKAGE-SECTION- die die Übergabe von Daten an aufgerufene externe Programme ermöglicht - wird später in diesem Buch behandelt.

ARBEITS- UND LAGERBEREICH

In der WORKING-STORAGE SECTION erstellst du die Variablen, die die Daten enthalten. Aber in COBOL werden diese Variablen normalerweise als Felder bezeichnet.

Felder sind außerdem nur global, das heißt, sie sind von überall im Programm zugänglich. Dies steht im Gegensatz zu modernen Sprachen, die sowohl lokale als auch globale Variablen haben. Eine lokale Variable ist nur für eine bestimmte Funktion oder einen bestimmten Codeblock verfügbar.

Es stimmt, dass es nicht ideal ist, nur globale Variablen zu haben, denn das kann zu Problemen führen. Deshalb ist es wichtig, bei der Entwicklung eines COBOL-Programms festzulegen, wie sich Variablen ändern können.

Schauen wir uns nun ein Beispiel für eine Datenstruktur an:

WORKING-STORAGE SECTION.
	01 INVOICE-NUMBER	PIC 99	 	PACKED-DECIMAL 		VALUE 0.

Dies wird als elementares Element bezeichnet, weil es nur ein Feld hat. Die Definition besteht ebenfalls aus fünf Teilen: der Ebenennummer, dem Feldnamen, der PIC Klausel, der USAGE Klausel und der VALUE Klausel. Diese werden im Folgenden beschrieben, gefolgt von einer Diskussion über Datengruppen und spezielle Ebenennummern.

Level Nummer

Sie reicht von 01 bis 49 und bezieht sich auf die Hierarchie der Daten. Jedes Feld hat seine eigene Ebenennummer.

Hinweis

In der Regel werden die Levelnummern in 5er-Schritten vergeben. Das erleichtert das Hinzufügen neuer Stufennummern, wenn sich die Datenstruktur ändert.

Feldname

Dieser kann bis zu 30 Zeichen lang sein. Dies soll beschreibende Namen ermöglichen.

Außerdem kannst du ein Feld ohne Namen haben, wie zum Beispiel dieses:

01 		FILLER		PIC X (100).

Dies ist eine Zeichenkette mit 100 Zeichen. Warum sollte man so etwas haben? Sie kann bei der Erstellung von Berichten nützlich sein.

PIC-Klausel

Die Abkürzung steht für Bild und gibt die Anzahl der Ziffern oder Zeichen an, die ein Feld haben kann. Im vorangegangenen Beispiel kann PIC 99 zwei Ziffern haben. Du kannst es aber auch als PIC 9(2) ausdrücken. Dieses PIC ist als numerisch bekannt und kann nur Zahlen enthalten. Wenn du jedoch S vorangestellt hast - z. B. als PIC S99- kannst du auch + und - verwenden.

Was ist mit Dezimalzahlen? Hierfür verwendest du V. Das ist ein sogenanntes implizites Dezimalsystem. Ein Beispiel ist PIC 99V99, das bis zu zwei Dezimalstellen vorsieht.

Eine Variante der numerischen Felder sind numerisch bearbeitete Felder. Diese Variante wird verwendet, um eine Zahl zu formatieren, z. B. für Währungen, Daten und so weiter. Hier ein Blick auf einige:

++99/99/99++

++$999.99++

Die PIC Klausel kann zwei weitere Datentypen enthalten. Der eine ist alphanumerisch, eine Zeichenkette, die jedes Zeichen enthalten kann. Sie wird als PIC X ausgedrückt. Ja, das wird ein Zeichen enthalten. Oder wenn du PIC XXX oder PIC X(3) angibst, enthält sie drei Zeichen.

Du kannst dann ein bearbeitetes Feld für eine alphanumerische Zahl verwenden. Hier ist ein Beispiel für eine Telefonnummer:

++XXXBXXXBXXXX++

Die B steht für ein Leerzeichen.

Der zweite ist der alphabetische Datentyp. Er erlaubt nur Groß- und Kleinbuchstaben von A bis Z. Ein Beispiel ist PIC A(10). Die meisten COBOL-Programmierer verwenden jedoch keine alphabetischen Datentypen, sondern programmieren mit dem alphanumerischen Typ. Beim Aktualisieren von älterem Code kannst du aber trotzdem einige Buchstaben sehen.

Zweifellos müssen wir noch eine ganze Menge lernen, um PIC Klauseln vollständig zu verstehen. Deshalb ist es wahrscheinlich eine gute Idee, mehr Beispiele zu geben, um ein Gefühl für die Unterschiede und ihre Verwendung zu bekommen; siehe Abbildung 4-2.

mmfd 0402
Abbildung 4-2. Beispiele für die Verwendung von PIC Klauseln

In der zweiten Reihe hat der Name Tom nur Buchstaben. Deshalb verwenden wir einen alphanumerischen Namen. Wir setzen auch die Länge auf 3. Aber bei Namen ist es oft eine gute Idee, mehr Platz für längere Namen einzuplanen.

In der dritten Zeile steht eine Adresse. Obwohl sie Zahlen enthält, hat sie auch Buchstaben. Deshalb verwenden wir ein alphanumerisches Zeichen.

In der nächsten Zeile sind die Bindestriche Zeichen. Wir verwenden also wieder ein alphanumerisches Zeichen, und die Größe ist 12, um die Größe einer Telefonnummer zu berücksichtigen.

Die letzten beiden Zeilen enthalten Zahlen, aber unterschiedliche Typen. Die erste ist eine ganze Zahl, weshalb wir PIC 9(4) verwenden. Die zweite hat jedoch eine Dezimalzahl, deshalb verwenden wir V für die implizite Dezimalzahl.

USAGE-Klausel

Hier wird die Art der Daten angegeben, die gespeichert werden sollen. Wenn du diese Angabe weglässt, ist die Standardeinstellung DISPLAY (auch bekannt als ZONED-DECIMAL DATA). Wie der Name schon sagt, ist dies dafür gedacht, wenn du die Daten ausdrucken möchtest.

PACKED-DECIMAL hingegen ist dafür gedacht, wenn du die Daten für mathematische Zwecke verwenden willst. Zugegeben, DISPLAY kann das auch, aber dann muss der Computer eine Übersetzung vornehmen, was mehr Zeit und Ressourcen benötigt.

Ältere IBM-Systeme haben eine andere Namenskonvention. Ein COMP-3 ist dasselbe wie PACKED-DECIMAL. Es gibt auch COMP-4, was für BINARY steht. Dies wird für die Indizierung von Daten verwendet und ist normalerweise nicht gut für Mathematik, da es Rundungsdifferenzen geben könnte. Seien wir ehrlich: Bei geschäftlichen Transaktionen kommt es auf jeden Cent an. Deshalb ist es in der Regel am besten, sich an PACKED-DECIMAL zu halten, wenn es um Mathematik für COBOL geht.

VALUE-Klausel

Dies ist optional. Wenn du dich aber dafür entscheidest, setzt die VALUE Klausel den Anfangswert fest. Im vorangegangenen Beispiel haben wir dies getan, indem wir INVOICE-NUMBER auf 0 gesetzt haben.

Du kannst die VALUE Klausel auch für eine alphanumerische Zahl verwenden. Hier ist ein Beispiel:

01 FIRST-NAME	PIC X(20) 	VALUE 'Jane'.

Beachte, dass wir nicht PACKED-DECIMAL verwenden. Das liegt daran, dass dies nur für numerische Werte gilt.

Die Datengruppe

In der Wirtschaft werden Daten oft in Gruppen zusammengefasst. Du kannst zum Beispiel einen Kundendatensatz haben, der den Namen, die Adresse, die Telefonnummer, die Kreditkarte und so weiter enthält. COBOL bietet die Möglichkeit, Daten mit Hilfe von Ebenennummern zu gruppieren:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 CUSTOMER-RECORD.
  05  CUSTOMER-NUMBER   PIC 9(5).
  05  CUSTOMER-NAME     PIC X(20).
  05  CUSTOMER-ADDRESS  PIC X(50).

Beachte, dass CUSTOMER-RECORD kein PIC hat. Das liegt daran, dass es sich um eine Gruppenbeschreibung handelt, nicht um eine Variable. Aber du kannst sie trotzdem für interessante Dinge verwenden. Du kannst alles auf Leerzeichen setzen:

MOVE SPACES to CUSTOMER-RECORD.

Oder du kannst deinen eigenen Charakter haben:

MOVE "*" TO CUSTOMER-RECORD

Wie können wir dann den Wert der Felder in der Gruppe ändern? Das können wir folgendermaßen tun:

MOVE 111 TO CUSTOMER-NUMBER

Oder dies:

MOVE "125 MAPLE AVENUE, LOS ANGELES, CA" TO CUSTOMER-ADDRESS

Du kannst auch MOVE verwenden, um einen Kundendatensatz mit einer Zeile zu erstellen:

MOVE "12345Jane Smith         100 Main Street" TO CUSTOMER-RECORD.

Wenn du Gruppen verwendest, kannst du noch detaillierter vorgehen. Hier gibt es mehr Details für CUSTOMER-NAME:

01 CUSTOMER-RECORD.
  05  CUSTOMER-NUMBER PIC 9(5).
  05  CUSTOMER-NAME.
		  10 FIRST-NAME PIC X(10).
		  10 LAST-NAME PIC X(10).
  05  CUSTOMER-ADDRESS PIC X(50).

Besondere Level-Nummern

COBOL hat verschiedene spezielle Level-Nummern. Zwei davon, 66 und 77, werden nur noch selten verwendet. Diejenige, die immer noch relevant ist, ist 88. Level 88 ist eigentlich ziemlich einzigartig für Computersprachen, denn mit ihr kannst du die Verwendung von Bedingungen in deinem Code vereinfachen.

Um dies zu verstehen, lass uns ein Beispiel betrachten. Nehmen wir an, wir haben einen Kundenstamm, der verschiedene Abonnementstufen hat: Free, Premium und Enterprise. Wir können dies mit einer 88er Nummer wie folgt einrichten:

01  CUSTOMER-CODE         PIC X.
  88  FREE-VERSION          VALUE 'F'.
  88  PREMIUM-VERSION       VALUE 'P'.
  88  ENTERPRISE-VERSION    VALUE 'E'.

In der PROCEDURE DIVISION können wir dann die CUSTOMER-CODE mit der Bedingung TRUE bezeichnen und auswerten, wie hier gezeigt:

SET PREMIUM-VERSION TO TRUE
IF (CUSTOMER-CODE = 'P')
DISPLAY 'The customer code is Premium'
END-IF

Indem wir PREMIUM-VERSION auf TRUE setzen, haben wir P für CUSTOMER-CODE ausgewählt.

Beachte, dass du TRUE nur verwenden kannst, wenn es darum geht, welches 88er-Element du haben möchtest. Die Angabe FALSE wäre zweideutig und würde zu einem Fehler führen.

Du kannst mit der Bedingung Level 88 auch andere Ansätze verfolgen. Nehmen wir an, du hast Daten, die mehrere Werte haben, z. B. für die Gruppierung von Regionen für Kunden:

01 		CUSTOMER-REGION			PIC X(2).
  88	NORTH-AMERICA     VALUES 'US' 'CA'.
  88	EUROPE            VALUES 'UK' 'DE' 'FR'.
  88	ASIA              VALUES 'CN' 'JP'.

MOVE 'UK' TO CUSTOMER-REGION

IF EUROPE
	DISPLAY 'The customer is located in Europe'
END-IF

In diesem Fall wurde die Bedingung auf UK gesetzt, und die Bedingung IF wird ausgeführt, da sie in Europa liegt.

Als Nächstes kannst du Bereiche für die 88 Bedingungen verwenden. Hier siehst du, wie das geht:

01  COMMISSIONS PIC 9(2) VALUE ZERO.
  88 UNDER-QUOTA VALUE 0 THRU 10.
  88 QUOTA VALUE 11 THRU 30.
  88 OVER-QUOTA VALUE 31 THRU 99.

MOVE 5 TO COMMISSIONS

IF UNDER-QUOTA
	DISPLAY 'The sales are under the quota.'
END-IF

Dies ist eine Spanne für die Quote eines Verkäufers. Da nur fünf Einheiten verkauft wurden, lag diese Person unter ihrer Quote.

Alles in allem kann eine 88er Bedingung die Logik eines Programms leichter nachvollziehbar machen. Außerdem erfordert sie in der Regel weniger Programmieraufwand, wenn Änderungen vorgenommen werden.

FILE-SECTION

Die FILE-SECTION mag sich wiederholend anhören. Wie wir bereits in diesem Kapitel gesehen haben, verfügt ENVIRONMENT DIVISION über robuste Funktionen für Dateien.

Worum geht es also bei FILE-SECTION? Du kannst einen Dateinamen festlegen, der für die Ausführung des Programms über die JCL verwendet werden soll, und auch die notwendigen Verknüpfungen mit den Datenstrukturen herstellen. Die Speicherung dafür liegt außerhalb des COBOL-Programms und wird erst erstellt, wenn du den Befehl OPEN im PROCEDURE DIVISION verwendest (mehr dazu erfährst du in Kapitel 5).

So sieht eine FILE-SECTION aus:

FILE SECTION.
FD   CUSTMAST.
01   CUSTOMER-MASTER
  05  CUST-NUM     PIC 9(2)
  05  CUST-FNAME   PIC X(20).
  05 CUST-LNAME    PIC X(2).
FD   SALES-REPORT.
01   PRINT-REPORT PIC X(132).

FD ist eine Abkürzung für die Dateidefinition, die der interne Name ist, der in der ENVIRONMENT DIVISION verwendet wird. Damit soll sichergestellt werden, dass auf die richtige Datei zugegriffen wird.

Konstanten

Konstanten sind eine Standardfunktion in den meisten modernen Sprachen. Sie ermöglichen es, feste Werte zu haben (z. B. für den Steuersatz oder pi).

Aber in COBOL gibt es keine Konstanten. Du musst stattdessen ein Feld verwenden, das du jederzeit ändern kannst. Und ja, das ist sicherlich ein Nachteil der Sprache.

Allerdings gibt es in COBOL figurative Konstanten. Diese festen Werte sind in die Sprache eingebaut: ZERO, SPACE, NULL, ALL, HIGH-VALUES, LOW-VALUES, und so weiter.

REDEFINES-Befehl

In manchen Fällen möchtest du ein Feld auf verschiedene Arten definieren. Hier kommt der Befehl REDEFINES ins Spiel:

01  PHONE-NUMBER      PIC 9(10).
01  PHONE-NUMBER-X    REDEFINES PHONE-NUMBER.
  05  AREA-CODE          PIC 9(3).
  05  TELEPHONE-PREFIX   PIC 9(3).
  05  LINE-NUMBER        PIC 9(4).

In diesem Beispiel haben wir zwei Felder für die Telefonnummer - eines ist ein elementares Element und das andere eine Datengruppe, die mehr Granularität bietet.

Wir können die REDEFINES auch für ein alphanumerisches Zeichen verwenden:

01  PRODUCT-PRICE		PIC	$ZZ9.99.
01  PRODUCT-PRICE-X		PIC	REDEFINES PRODUCT-PRICE PIC X(6).

Zuerst stellen wir PRODUCT-PRICE als bearbeitete numerische Zahl ein. Dann wandeln wir sie in eine alphanumerische Zahl um, damit die Formatierungsinformationen wegfallen und die Berechnungen einfacher durchgeführt werden können.

Wenn du REDEFINES verwendest, beziehen sich beide Felder auf die gleichen Bytes im Speicher. Eine Änderung in einem Feld wirkt sich auch auf das andere aus. Außerdem müssen beide die gleichen Levelnummern haben, und du kannst die VALUE Klausel nur für das erste Feld verwenden.

VERFAHRENSABTEILUNG

In der PROCEDURE DIVISION führst du die Logik des Programms aus. Du könntest zwar einfach eine lange Liste von Befehlen schreiben, aber dann wird es schwer lesbar. Deshalb ist es empfehlenswert, COBOL strukturiert zu schreiben. Du unterteilst den Code in Abschnitte, die als subroutines, functions oder procedures bezeichnet werden. Es ist sinnvoll, dass jeder dieser Abschnitte eine bestimmte Aufgabe erfüllt.

Schauen wir uns ein Beispiel an:

IDENTIFICATION DIVISION.
PROGRAM-ID.  PRINTNAME.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 USER-NAME  PIC X(15).
PROCEDURE DIVISION.
100-GET-USER-INPUT.
DISPLAY "Enter the user name"
	ACCEPT USER-NAME.
200-PRINT-USER-NAME.
DISPLAY "The user name is " USER-NAME.
300-PRINT-PROGRAM-END.
GOBACK.

Dies ist ein einfaches Programm, aber es bietet eine Möglichkeit, eine modulare Struktur zu erstellen. Eine COBOL-Konvention ist es, ein Programm in Absätze zu unterteilen. Diese haben eine Überschrift - z. B. 100-GET-USER-INPUT-, die die Aufgabe beschreibt. Die Reihenfolge der Absätze spielt keine Rolle. In COBOL ist es jedoch üblich, sie in der gleichen Reihenfolge wie den Arbeitsablauf anzuordnen, und jeder Absatz hat eine Nummer. Wenn du zum Beispiel eine moderne IDE verwendest, zeigt sie eine Gliederungsansicht des Codes an, die auf der Reihenfolge der Absätze basiert. Wie du in unserem Codebeispiel sehen kannst, haben die Befehle in einem Absatz keinen Punkt, außer am Ende. Dies wird als punktlose Kodierung bezeichnet. Damit sollen Probleme wie ungewollte Abschlüsse eines Absatzes vermieden werden.

Hinweis

Der Befehl DISPLAY wird oft zur Fehlersuche verwendet. Er ist eine einfache Möglichkeit, Felder auszudrucken, um zu sehen, ob alles korrekt verarbeitet wird. Ein Beispiel ist DISPLAY "X field is = " X.

Es ist eine COBOL-Konvention, einen Absatz ohne Code (300-PRINT-PROGRAM-END) zu haben, um das Ende des Programms zu markieren. Der Befehl GOBACK beendet das Programm. Für den Rest des Kapitels werden wir uns also die wichtigsten Befehlsarten und Arbeitsabläufe für das PROCEDURE DIVISION ansehen.

MOVE-Befehl

Eine moderne Sprache hat Variablenzuweisungen. In Python kannst du zum Beispiel so etwas tun:

price = 100

Aber COBOL hat keine Variablenzuweisungen. Was ist dann die Alternative? Wie kannst du die Werte für ein Feld festlegen?

Du kannst den Befehl MOVE verwenden. Anstatt den Wert von rechts nach links zu verschieben, ist es umgekehrt, wie hier zu sehen, was in der PROCEDURE DIVISION wäre:

MOVE "SMITH" TO LAST-NAME.

Oder du kannst den Wert von von einem Feld in ein anderes Feld übertragen:

MOVE LAST-NAME TO LAST-NAME-2.

Der Wert von LAST-NAME wird auf LAST-NAME-2 kopiert. Das heißt, LAST-NAME hat weiterhin SMITH.

Wenn du die Anweisung MOVE verwendest, kannst du mit mehreren Feldern arbeiten. So wird zum Beispiel 0 in COUNTER, X und Y kopiert:

MOVE   0   TO  COUNTER X Y

Aber du musst vorsichtig sein, wenn du MOVE mit Feldern verwendest, die unterschiedliche Typen haben. Werfen wir zunächst einen Blick auf die Arbeit mit einem alphanumerischen Feld. Wir werden ein Feld wie folgt in der DATA DIVISION erstellen:

01	LAST-NAME	     PIC X(7)     VALUE	"COOK".

Dann machen wir folgendes MOVE in der PROCEDURE DIVISION:

MOVE  "Davis"   To    LAST-NAME.

LAST-NAME hat nun den Wert Davis. Doch es gibt noch etwas anderes zu beachten. Da Davis weniger Zeichen hat als PIC X, fügt der Compiler Leerzeichen in das Feld ein (der * steht für ein Leerzeichen). Du kannst die Ausgabe in Abbildung 4-3 sehen.

mmfd 0403
Abbildung 4-3. Wenn das Feld weniger Zeichen hat als zugewiesen, fügt COBOL am Ende Leerzeichen hinzu

Das kann zu Formatierungsproblemen führen, zum Beispiel bei den Abständen in einem Bericht. Es gibt jedoch Möglichkeiten, dies zu korrigieren, die du später in diesem Buch kennenlernen wirst.

Was ist, wenn wir ein Feld haben, das mehr Zeichen hat als PIC X? Das kann ein noch größeres Problem verursachen. Nehmen wir an, wir haben Folgendes:

MOVE 	"Dumbledore"	TO		LAST-NAME.

Das Ergebnis ist Abbildung 4-4.

mmfd 0404
Abbildung 4-4. Wenn eine Zeichenfolge zu groß für PIC ist, werden die zusätzlichen Zeichen abgeschnitten

Wie du siehst, wird der Name abgeschnitten, was als Trunkierung bezeichnet wird. Deshalb ist eine gut durchdachte Datenstruktur so wichtig.

Das Gleiche gilt für Zahlen. Nehmen wir an, wir haben dies in der DATA DIVISION:

01 	PRICE		PIC	9(3)V99.

Das bedeutet, dass wir ein Feld mit fünf Ziffern haben, das zwei Nachkommastellen enthält. Schauen wir uns nun einige MOVE Anweisungen an:

MOVE	57.2 		TO	PRICE

Abbildung 4-5 zeigt, was der Compiler zuweist.

mmfd 0405
Abbildung 4-5. Wenn eine Zahl kleiner ist als in der PIC 9 Deklaration angegeben, werden 0s von links nach rechts hinzugefügt

Wenn eine Zahl nicht zu der in PIC 9 angegebenen Länge passt, werden 0s hinzugefügt.

Wir können auch trunkieren, z. B. mit :

MOVE	8803.257 		TO	PRICE

Abbildung 4-6 zeigt das Ergebnis.

mmfd 0406
Abbildung 4-6. Wenn eine Zahl größer ist als die PIC 9 Zuweisung, werden die zusätzlichen Zahlen abgeschnitten

Die Zahl wird zuerst entlang des Dezimalkommas ausgerichtet. Da 8803 zu groß für die drei vorgesehenen Stellen ist, wird die 8 nicht mitgerechnet. Die 7 in der Dezimalstelle wird ebenfalls nicht berücksichtigt, und es wird nicht gerundet.

Bei mathematischen Berechnungen kommt es häufig zu Ausreißern. Daher ist es wichtig, beim Zusammenstellen der Datenstrukturen an die möglichen Ausreißer bei den Berechnungen zu denken. Der Befehl ON SIZE ERROR kann helfen, diese Probleme zu vermeiden, und wir werden uns das später in diesem Kapitel ansehen.

Du kannst MOVE verwenden, wenn es verschiedene PICs gibt, solange das Sendefeld eine Ganzzahl ohne Vorzeichen ist. Dies sind die Optionen:

  • Alphanumerisch zu numerisch

  • Alphanumerisch zu numerisch bearbeitet

  • Numerisch zu alphanumerisch

Hier ist ein Beispiel für die erste Variante. Gib dies für die DATA DIVISION ein:

01		ALPHA-NUM		PIC X(2)		VALUE '50'.
01		NUM-VALUE		PIC 9(2)		VALUE 0.

Dann verwende dies in der PROCEDURE DIVISION:

MOVE ALPHA-NUM TO NUM-VALUE

Das Ergebnis wird sein, dass NUM-VALUE den Wert von 50 hat.

Mathe-Befehle

COBOL hat zwei Hauptansätze für Mathe. Es gibt eine Reihe von Befehlen wie ADD, SUBTRACT, MULTIPLY und DIVIDE. COMPUTE ermöglicht anspruchsvollereBerechnungen.

ADD, SUBTRACT, MULTIPLY und DIVIDE

Um zu sehen, wie die Befehle ADD, SUBTRACT, MULTIPLY und DIVIDE funktionieren, haben wir zunächst die folgenden Deklarationen für die DATA DIVISION:

01	WITHDRAWAL     PIC 9(3)	VALUE 0.
01	DEPOSIT        PIC 9(3)	VALUE 0.
01	BALANCE        PIC 9(3)	VALUE 0.

Mit ADD können wir dies dann im PROCEDURE DIVISION tun:

MOVE 50 TO DEPOSIT
ADD DEPOSIT TO BALANCE

BALANCE wird nun 50 sein. Oder wir können dies mit unserem DEPOSIT tun:

ADD 25 TO DEPOSIT GIVING BALANCE

Damit fügen wir 25 zu DEPOSIT hinzu und ersetzen den Wert von BALANCE durch 75.

Werfen wir einen Blick auf und SUBTRACT:

MOVE 60 TO WITHDRAWAL
SUBTRACT WITHDRAWAL FROM BALANCE

Da BALANCE auf 75 gesetzt wurde, würde das neue Ergebnis 15 lauten.

Angenommen, wir haben drei Schecks mit den Beträgen 100, 125 und 395. So können wir den Befehl ADD verwenden:

ADD 100 125 359 TO DEPOSIT GIVING BALANCE

Die Zahlen ergeben zusammen 584, und BALANCE wird durch diese Zahl ersetzt. Du kannst auch GIVING mit SUBTRACT verwenden. Angenommen, wir haben drei Abhebungen über 50, 125 und 200 sowie eine Einzahlung von 450:

MOVE 500 TO DEPOSIT
SUBTRACT 50 125 200 FROM DEPOSIT GIVING BALANCE

Die Gesamteinlagen von 375 werden von 500 subtrahiert und ergeben 125. BALANCE ist dann gleich diesem Betrag.

Als Nächstes sehen wir uns den Befehl MULTIPLY an. Wir erstellen zunächst zwei Felder in der DATA DIVISION:

01  INCOME       PIC 9(5)V99		VALUE 500.
01  NET-INCOME   PIC 9(5)V99		VALUE 0.

Nehmen wir an, dass der Steuersatz 10% beträgt. Dann können wir in der PROCEDURE DIVISION Folgendes angeben:

MULTIPLY .10 BY INCOME

Das Ergebnis, das 50 ist, wird in INCOME eingefügt. Oder wir können den Befehl GIVING verwenden:

MULTIPLY .10 BY INCOME GIVING NET-INCOME

NET-INCOME wird durch 50 ersetzt.

Bei der Aufteilung gibt es jedoch einige Unterschiede. Du kannst zwei Hauptansätze verwenden: DIVIDE INTO oder DIVIDE BY.

Hier ist ein Blick auf die erste, die dies für die DATA DIVISION hat:

01  SALES		PIC 9(5)		VALUE 10000.
01  UNITS		PIC 9(4)		VALUE 500.
01  SALES-PER-UNIT	PIC 9(5)		VALUE 0.

Dann ist dies für die PROCEDURE DIVISION:

DIVIDE UNITS INTO SALES

Damit ist SALES jetzt gleich 20. Oder wir können den Befehl GIVING verwenden, der uns das gleiche Ergebnis liefert, aber in SALES-PER-UNIT einfügt:

DIVIDE UNITS INTO SALES GIVING SALES-PER-UNIT

Nehmen wir an, wir ändern die Werte in der PROCEDURE DIVISION wie folgt:

MOVE 2000 TO SALES
MOVE 192 TO UNITS

Auf diese Weise können wir die Berechnung durchführen:

DIVIDE SALES BY UNITS GIVING SALES-PER-UNIT ROUNDED

Das Ergebnis dieser Formel ist 10,41666. Da PIC 9 für SALES-PER-UNIT aber keine Dezimalstelle hat, haben wir die Zahl gerundet, was uns 10 ergibt.

Wir können auch den Rest einer Division ermitteln. In der DATA DIVISION haben wir folgendes Beispiel:

01  QUOTIENT    PIC 999		VALUE 0.
01  REM         PIC 999		VALUE 0.

Dann haben wir dies für die PROCEDURE DIVISION:

DIVIDE 100 BY 9 GIVING QUOTIENT REMAINDER REM.

Dabei ist die QUOTIENT 11 und die REMAINDER ist 1.

COMPUTE

Die Verwendung von mathematischen Befehlen wie ADD und SUBTRACT sind einzigartig für moderne Sprachen. Aber der Befehl COMPUTE sieht eher so aus, wie du es in Python oder C# sehen würdest.

Um zu sehen, wie der Befehl COMPUTE funktioniert, wollen wir zunächst einige Felder in der DATA DIVISION einrichten:

01  DISCOUNTED-PRICE     PIC 9(5)      VALUE 0.
01  RETAIL-PRICE         PIC 9(5)      VALUE 0.
01  DISCOUNT             PIC 9(2)V99   VALUE 0.

Nun lass uns die Berechnung in der PROCEDURE DIVISION durchführen:

MOVE 0.25 TO DISCOUNT
MOVE 100 TO RETAIL-PRICE
COMPUTE DISCOUNTED-PRICE = RETAIL-PRICE * (1 - DISCOUNT)

Wir setzen DISCOUNT für dieses Produkt auf 25% und RETAIL-PRICE auf 100. Dann ziehen wir mit der COMPUTE Formel subtrahieren wir 1 von DISCOUNT und multiplizieren das Ergebnis mit RETAIL-PRICE. So erhalten wir DISCOUNTED-PRICE.

Die mathematischen Operatoren für COBOL sind ähnlich wie in anderen modernen Sprachen. Du kannst sie in Tabelle 4-1 finden.

Tabelle 4-1. Die mathematischen Operatoren für COBOL
Mathematischer Operator Funktion

+

Zusatz

-

Subtraktion

/

Abteilung

*

Multiplikation

**

Exponent

Hinweis

Die Verwendung eines Exponenten wird wie folgt ausgedrückt: COMPUTE A = 2**2. Das ist 2 hoch 2 oder 2 zum Quadrat.

Wenn du die Klammern verwendest, werden die Berechnungen innerhalb der Klammern zuerst ausgeführt. Danach beginnt die Reihenfolge der Operationen mit den Exponenten, dann folgen Multiplikation, Division, Subtraktion und Addition. In den meisten Fällen verlassen sich Programmierer auf die Klammern.

Ein häufiges Problem mit COMPUTE tritt auf, wenn die Felder nicht groß genug sind, um die Zahlen aufzunehmen. Wie wir gesehen haben, führt dies zu einer Abschneidung. Eine Möglichkeit, damit umzugehen, ist die ON SIZE ERROR Klausel. Schauen wir uns ein Beispiel an, bei dem die folgenden Daten in der DATA DIVISION stehen:

01		SALES		PIC 9(4)		VALUE 0.
01		PRICE		PIC 9(1)		VALUE 5.
01		UNITS		PIC 9(4)		VALUE 5000.

Dann ist hier die PROCEDURE DIVISION:

COMPUTE	SALES = PRICE * UNITS ON SIZE ERROR
DISPLAY "The amount is too large for the SALES field."

Das Ergebnis dieser Formel ist 25000. Das Feld SALES kann jedoch nur bis zu vier Ziffern enthalten. Aus diesem Grund wird die ON SIZE ERROR Klausel ausgelöst. Dies kann eine effektive Methode sein, um den Absturz eines Programms zu vermeiden.

Mathe-Funktionen

COBOL verfügt über einen umfangreichen Satz von 42 mathematischen Funktionen, z. B. für Finanzen, Statistik und Trigonometrie. Du verwendest den Befehl FUNCTION, um sie auszuführen, und es können null, ein, zwei oder mehr Argumente angegeben werden.Tabelle 4-2 zeigt eine Liste der gängigen Funktionen.

Tabelle 4-2. Gemeinsame mathematische Funktionen in COBOL
Funktion Was sie tut

SUM

Summe der Argumente

SQRT

Quadratwurzel eines Arguments

MEAN

Durchschnitt des Arguments

SIN

Sinus eines Arguments

VARIANCE

Abweichung eines Arguments

STANDARD-DEVIATION

Standardabweichung einer Gruppe von Argumenten

RANGE

Maximales Argument minus das minimale Argument

MAX

Wert des größten Arguments

MIN

Kleinstes Argument

LOG

Natürlicher Logarithmus

Schauen wir uns einige Beispiele an, die auf PROCEDURE DIVISION zu finden sind:

DISPLAY FUNCTION SUM (50 59 109 32 99)
DISPLAY FUNCTION SQRT (100)

Die Ergebnisse sind 349 bzw. 10. Du kannst die Funktionen auch mit dem Befehl COMPUTE verwenden.

Konditionale

Das IF/THEN/ELSE Konstrukt ist das Herzstück aller Sprachen. Es ist ein wichtiger Teil der Steuerung des Ablaufs eines Computerprogramms und basiert auf der booleschen Logik, die prüft, ob etwas entweder wahr oder falsch ist.

Aber COBOL hat seinen eigenen Ansatz - und der kann knifflig sein. Ein guter Weg, um Konditionale zu erklären, sind daher einige Beispiele:

DATA DIVISION.
WORKING-STORAGE SECTION.
01  TEMPERATURE PIC 9(3) VALUE 0.
PROCEDURE DIVISION.
DISPLAY "Enter the temperature : "
ACCEPT TEMPERATURE
IF TEMPERATURE <= 32 THEN
  DISPLAY "It is freezing"
ELSE
  DISPLAY "It is not freezing"
END-IF

GOBACK.

In COBOL nennt man das eine allgemeine Beziehungsbedingung. Trotz ihres langen Namens ist diese Bedingung ganz einfach. Der Befehl ACCEPT nimmt eine Benutzereingabe entgegen, die in diesem Fall die aktuelle Temperatur ist. Wenn die Temperatur 32 Grad oder weniger beträgt, ist es eiskalt.

COBOL hat englische Versionen von Konditionalen. Anstelle von > kannst du zum Beispiel GREATER THAN verwenden. Tabelle 4-3 enthält eine Liste der Konditionale.

Tabelle 4-3. Konditionale in COBOL
Kurzschrift Englischsprachige Version

>

GREATER THAN

<

LESS THAN

=

EQUAL TO

>=

GREATER THAN OR EQUAL TO

LESS THAN OR EQUAL TO

Not>

NOT GREATER THAN

Not<

NOT LESS THAN

Not=

NOT EQUAL TO

Du kannst komplexere Bedingungen schreiben, indem du AND und OR verwendest, die zusammengesetzte bedingte Ausdrücke genannt werden. Um zu sehen, wie das funktioniert, ist hier ein Beispielprogramm für die Genehmigung von Rechnungen:

DATA DIVISION.
WORKING-STORAGE SECTION.
01  INVOICE-AMOUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
DISPLAY "Enter the invoice amount : "
ACCEPT INVOICE-AMOUNT
IF INVOICE-AMOUNT > 0 AND INVOICE-AMOUNT < 5000 THEN
  DISPLAY "No approval is needed"
ELSE
  DISPLAY "There must be approval"
END-IF
GOBACK.

Bei diesem Code ist keine Genehmigung erforderlich, wenn die Rechnung zwischen 0 und 5.000 USD liegt.

Auch das ist einfach und ähnelt dem, was du in anderen Sprachen sehen würdest. Wie sieht es nun mit den verschiedenen Arten von Bedingungen aus? Eine davon ist die Klassenbedingung. Das Wort Klasse bezieht sich jedoch nicht auf die objektorientierte Programmierung.

Weiter oben in diesem Kapitel haben wir gesehen, wie die Klassenbedingung verwendet wurde. Dabei wurden die Zahlen der Ebene 88 verwendet, um einen Werte- oder Textbereich festzulegen, und eine Bedingung wurde ausgelöst, wenn ein Wert in diesen Bereich fiel.

Etwas anderes, das wir für eine Bedingung verwenden können, ist der Befehl EVALUATE. Er ähnelt einem Switch/Case-Konstrukt, das in anderen Sprachen zu finden ist. Wenn es eine Vielzahl von Möglichkeiten gibt, kann EVALUATE viel einfacher zu verwenden sein als eine einfache IF/THEN/ELSE Struktur.

Nehmen wir an, wir erstellen eine App, mit der wir Kundendaten verfolgen können, und möchten eine Möglichkeit haben, die Art der Geschäftseinheit zu bestimmen:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 BUSINESS-NUMBER 		PIC 99 VALUE ZERO.
01 BUSINESS-TYPE 	 	PIC X(20).
PROCEDURE DIVISION.
DISPLAY "Enter the business number"
ACCEPT BUSINESS-NUMBER
EVALUATE BUSINESS-NUMBER
WHEN 1 MOVE "Sole Proprietor" TO BUSINESS-TYPE
WHEN 2 MOVE "Single-Member LLC" TO BUSINESS-TYPE
WHEN 3 MOVE "S Corporation" TO BUSINESS-TYPE
WHEN 4 MOVE "C-Corporation" TO BUSINESS-TYPE
WHEN 5 MOVE "Partnership" TO BUSINESS-TYPE
WHEN 6 MOVE "Trust/Estate" TO BUSINESS-TYPE
WHEN OTHER MOVE 0 TO BUSINESS-TYPE
END-EVALUATE
DISPLAY "The business type is " BUSINESS-TYPE
GOBACK.

In diesem Programm gibt der Benutzer eine Zahl zwischen 1 und 6 ein, die jeweils einer Geschäftsart entspricht. Die Anweisung EVALUATE geht dann zu der ausgewählten Zahl und ändert den Wert von BUSINESS-TYPE. Die letzte Bedingung ist WHEN OTHER, die der Standardwert ist, wenn der Benutzer etwas auswählt, das nicht im Wertebereich liegt.

Nachdem ein Benutzer etwas ausgewählt hat, geht das Programm zur Anweisung END-EVALUATE und die Anweisung DISPLAY wird ausgeführt.

Die Struktur von EVALUATE kann eine komplizierte Logik beinhalten. Deshalb kann es eine gute Idee sein, zuerst eine Entscheidungstabelle zu erstellen. Nehmen wir zum Beispiel an, wir wollen eine Provisionsstruktur wie in Abbildung 4-7 erstellen.

mmfd 0407
Abbildung 4-7. Eine Entscheidungstabelle kann bei der Erstellung von Konditionalen hilfreich sein

Das macht es einfacher, die bedingte Logik zu erstellen:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 COMMISSIONS PIC 99 VALUE ZERO.
 88 UNDER-QUOTA VALUE 0 THRU 10.
 88 QUOTA VALUE 11 THRU 30.
 88 OVER-QUOTA VALUE 31 THRU 99.
PROCEDURE DIVISION.
DISPLAY "Enter the number of units sold"
ACCEPT COMMISSIONS
EVALUATE TRUE
WHEN UNDER-QUOTA
DISPLAY "Commission is 10% and this is under the quota."
 WHEN QUOTA
DISPLAY "Commission is 15% and this meets the quota."
 WHEN OVER-QUOTA
DISPLAY "Commission is 20% and this is over the quota."
 WHEN OTHER
DISPLAY "This is the default"
END-EVALUATE.
GOBACK.

In der DATA DIVISION verwenden wir ein Gruppenfeld mit 88 Stufennummern. Eine Verkäuferin oder ein Verkäufer kann drei Stufen von Provisionen erhalten. In PROCEDURE DIVISION richten wir eine Struktur mit EVALUATE TRUE ein und geben dann die drei Bedingungen für UNDER-QUOTA, QUOTA und OVER-QUOTA an. Wenn der Benutzer 15 eingibt, wird die Meldung für QUOTA ausgeführt usw.

Mit der Anweisung EVALUATE ist es möglich, auch zusammengesetzte Bedingungen zu berücksichtigen:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 BUSINESS-NUMBER   PIC 99 VALUE ZERO.
01 VIP-CUSTOMER      PIC X.
01 UNITS             PIC 9(3).
01 DISCOUNT          PIC 9(2)V9(2).
PROCEDURE DIVISION.
DISPLAY "Enter the number of units sold"
ACCEPT UNITS
DISPLAY "A VIP customer (Y/N)?"
ACCEPT VIP-CUSTOMER
EVALUATE UNITS ALSO VIP-CUSTOMER
 WHEN 1 THRU 20 ALSO "Y"
  MOVE .20 TO DISCOUNT
 WHEN 21 THRU 50 ALSO "Y"
  MOVE .25 TO DISCOUNT
 WHEN GREATER THAN 50 ALSO "Y"
  MOVE .30 TO DISCOUNT
END-EVALUATE
DISPLAY "The discount is " DISCOUNT

Mit dem Schlüsselwort ALSO können wir verschiedene Bedingungen aneinanderreihen. In unserem Beispiel umfasst dies eine Bedingung für die verkauften Einheiten und eine Bedingung dafür, ob ein Kunde an einem VIP-Programm teilnimmt.

In COBOL kannst du verschachtelte IF/THEN/ELSE Blöcke haben. Es gibt zwar keine Beschränkungen für die Anzahl der Blöcke, aber in der Regel ist es am besten, nicht mehr als drei zu verwenden. Andernfalls könnte der Code extrem schwer zu verfolgen sein.

Hier ist ein Beispiel für einen verschachtelten IF/THEN/ELSE Block:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 USERNAME		PIC X(20).
01 PASSWORD		PIC X(20).
PROCEDURE DIVISION.
DISPLAY "Enter your user name"
ACCEPT USERNAME
DISPLAY "Enter your password"
ACCEPT PASSWORD
IF USERNAME = "Tom68"
 IF PASSWORD = "12345"
  DISPLAY "Login successful!"
 ELSE
	 DISPLAY "Incorrect password."
 END-IF
ELSE
 DISPLAY "Incorrect user name."
END-IF.
GOBACK.

Die erste Bedingung ist für USERNAME. Wenn sie korrekt ist, wird die nächste Bedingung ausgelöst. Wenn die Bedingung nicht korrekt ist, wird die ELSE am Ende ausgeführt. Die nächste Bedingung prüft das Passwort.

Wenn du verschachtelte IF/THEN/ELSE Bedingungen aufstellst, ist es wichtig, dass du den Code richtig aneinanderreihst und jeden Block mit einem END-IF abschließt. Wenn nicht, wird der Code wahrscheinlich falsche Ergebnisse liefern. Wenn wir zum Beispiel das END-IF in der verschachtelten Bedingung weglassen, wird die erste ELSE ausgeführt, wenn die USERNAME nicht korrekt ist.

Schleifen

Die Schleife ist ein Teil jeder Sprache. Wie der Name schon sagt, kannst du mit dieser Struktur etwas durchlaufen, z. B. einen Datensatz. In COBOL lautet der Befehl für eine Schleife PERFORM, den es in verschiedenen Varianten gibt.

Die erste, die wir uns ansehen werden, ist PERFORM TIMES, die ähnlich wie eine for Schleife in anderen Sprachen ist. Das bedeutet, dass sie eine feste Anzahl von Malen ausgeführt wird, die als Feld oder als Literal ausgedrückt werden kann:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 COUNTER PIC 9(1) VALUE 0.
PROCEDURE DIVISION.
PERFORM 5 TIMES
ADD 1 TO COUNTER
 DISPLAY "Loop number " COUNTER
END-PERFORM
GOBACK.

Die Schleife wird fünfmal durchlaufen und das Feld COUNTER wird bei jedem Durchlauf um eins erhöht. Der Wert wird gedruckt.

Eine andere Möglichkeit, PERFORM zu verwenden, ist die Schleife eines Absatzes oder Unterprogramms:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 COUNTER PIC 9(1) VALUE 0.
PROCEDURE DIVISION.
100-PARAGRAPH-LOOP.
 PERFORM 200-PRINT-COUNTER 5 TIMES.
 GOBACK.
200-PRINT-COUNTER.
 ADD 1 TO COUNTER
 DISPLAY "Loop number " COUNTER.

Dieses Programm macht das Gleiche wie das erste, aber es hat einen modularen Aufbau. Wir haben zwei Absätze. Der erste verwendet PERFORM, um eine Schleife durch den zweiten Absatz zu ziehen.

Hinweis

COBOL hat einen GOTO Befehl, der einen Absatz aufrufen kann. Aber es ist keine gute Idee, ihn zu benutzen, vor allem weil der Befehl nicht an die Stelle zurückkehrt, an der du ihn aufgerufen hast. Dadurch kann der Code chaotisch werden - er ähnelt dann eher einem "Spaghetti-Code".

Als nächstes können wir eine Bedingung für eine Schleife festlegen. Wir können zum Beispiel PERFORM UNTIL verwenden, genauso wie wir die while Schleife in anderen Sprachen verwenden:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 COUNTER PIC 9(1) VALUE 0.
PROCEDURE DIVISION.
PERFORM UNTIL COUNTER >= 5
ADD 1 TO COUNTER
	DISPLAY "Loop number " COUNTER
END-PERFORM
GOBACK.

Dieses Programm zählt von 1 bis 5 und hört dann auf. Aber du musst mit PERFORM UNTIL vorsichtig sein. Wenn COUNTER bereits über 5 liegt, wird die Schleife nicht ausgeführt.

Aber es gibt eine Alternative: PERFORM WITH TEST AFTER. Diese garantiert, dass es mindestens eine Schleife gibt. Diese Struktur ist ähnlich wie die do-while Schleife in anderen Sprachen. Mit unserem Programm können wir also Folgendes tun:

PERFORM WITH TEST AFTER UNTIL COUNTER >= 5
ADD 1 TO COUNTER
 DISPLAY "Loop number " COUNTER
END-PERFORM

Auch wenn COUNTER über 5 liegt, wird der Code ausgeführt und COUNTER wird um 1 erhöht.

Als Nächstes: PERFORM VARYING ist im Wesentlichen eine Variation der traditionellen for Schleife. Es gibt jedoch einige wichtige Unterschiede. COBOL erlaubt die Verwendung von drei Zählfeldern für die Schleife, die Prüfung der Bedingung kann vor oder nach der Ausführung der Schleife erfolgen und die Bedingung für den Abbruch der Schleife muss nicht COUNTER lauten.

Das ist eine ganze Menge. Um ein Verständnis für diese Struktur zu bekommen, schauen wir uns ein Beispiel an:

DATA DIVISION.
WORKING-STORAGE SECTION.
01 YEAR PIC 9(2) VALUE 0.
01 BALANCE PIC 9(4) VALUE 1000.
PROCEDURE DIVISION.
PERFORM VARYING YEAR FROM 1 BY 1
 UNTIL YEAR > 10
 COMPUTE BALANCE = BALANCE * 1.05
 DISPLAY "Balance is $" BALANCE
END-PERFORM.
GOBACK.

Dieses Programm zeigt, wie sich der Wert einer Investition von 1.000 USD über einen Zeitraum von 10 Jahren entwickelt. Wir setzen BALANCE auf 1000 und YEAR auf 0, die bis zum Jahr 10 um 1 erhöht werden. Bei jeder Iteration wird eine COMPUTE Anweisung verwendet, um BALANCE um einen Zinssatz von 5% zu erhöhen.

Was wäre, wenn wir stattdessen eine PIC 9 für YEAR einstellen würden? Die Schleife würde nie bei 10 ankommen. Tatsächlich würde das eine Endlosschleife erzeugen und das Programm zum Absturz bringen. Deshalb ist es so wichtig, dass du die Verwendung der Daten in deinen Programmen gut durchdenkst.

Als Nächstes können wir mit unserem Programm die Schleife in umgekehrter Reihenfolge durchführen, indem wir die folgenden Änderungen an der PROCEDURE DIVISION vornehmen:

PERFORM VARYING YEAR FROM 10 BY -1
 UNTIL YEAR <= 0
 COMPUTE BALANCE = BALANCE * 0.95
 DISPLAY "Balance is $" BALANCE
END-PERFORM

Der Wert von BALANCE wird 10 Jahre lang reduziert, bis der Wert auf 595 $ sinkt.

Und du kannst die Struktur PERFORM VARYING verwenden, um ein Unterprogramm aufzurufen. Nehmen wir eine Variation des vorherigen Codebeispiels:

PROCEDURE DIVISION.
100-BALANCE-LOOP.
PERFORM 200-DEPOSIT-CALC VARYING YEAR FROM 1 BY 1
 UNTIL YEAR > 10
 GOBACK.
200-DEPOSIT-CALC.
 COMPUTE BALANCE = BALANCE * 1.05
 DISPLAY "Balance is $" BALANCE.

Schließlich kannst du den Befehl THRU mit PERFORM verwenden, um eine Reihe von Absätzen aufzurufen:

PROCEDURE DIVISION.
100-FIRST-PARAGRAPH.
 PERFORM 200-SECOND-PARAGRAPH THRU 400-FOURTH-PARAGRAPH.
200-SECOND-PARAGRAPH.
 DISPLAY 'Paragraph 2'.
300-THIRD-PARAGRAPH.
 DISPLAY 'Paragraph 3'.
400-FOURTH-PARAGRAPH.
 DISPLAY 'Paragraph 4'.
GOBACK.

Wie du siehst, führt PERFORM THRU die 200-SECOND-PARAGRAPH, 300-SECOND-PARAGRAPH und 400-FOURTH-PARAGRAPHaus - in dieser Reihenfolge.

Hinweis

IBM hat großartige Ressourcen zu COBOL. Sieh dir das Programmierhandbuch und dieSprachreferenz an.

Fazit

In diesem Kapitel haben wir schon eine Menge behandelt. Du hast die wichtigsten Arten von Strukturen kennengelernt, die du wissen musst, um ein COBOL-Programm zu erstellen oder zu bearbeiten. Um ein erfolgreicher Programmierer zu sein, musst du nicht den gesamten Befehlssatz kennen. Einige Befehle sind doppelt vorhanden, und andere werden nur selten verwendet.

COBOL hat zwar viele Ähnlichkeiten mit modernen Sprachen, aber es gibt auch einige große Unterschiede. Und ja, die Sprache kann wortreich sein, aber das ist beabsichtigt.

In diesem Kapitel konnten wir die Arten von Mathematik abdecken, die du kennen musst, sei es durch die Verwendung von Befehlen wie ADD und SUBTRACT oder durch die Verwendung von COMPUTE, das mehr Vielseitigkeit bietet. Dann haben wir uns angeschaut, wie man mit der IF/THEN/ELSE Struktur Konditionale in COBOL-Programmen einsetzt. Wir haben uns auch anspruchsvollere Entscheidungsanweisungen wie EVALUATE angesehen.

Schließlich haben wir gesehen, wie man Schleifen verwendet, zum Beispiel mit dem Befehl PERFORM. Wir haben auch gezeigt, wie man damit strukturierte Programmieransätze durchsetzen kann.

Im nächsten Kapitel befassen wir uns mit der Handhabung von Dateien.

Get Moderne Mainframe-Entwicklung now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.