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.
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
undPROCEDURE 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.
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.
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.
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.
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.
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.
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.
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 PIC
s 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
.
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.
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.
Funktion | Was sie tut | |
---|---|---|
|
Summe der Argumente |
|
|
Quadratwurzel eines Arguments |
|
|
Durchschnitt des Arguments |
|
|
Sinus eines Arguments |
|
|
Abweichung eines Arguments |
|
|
Standardabweichung einer Gruppe von Argumenten |
|
|
Maximales Argument minus das minimale Argument |
|
|
Wert des größten Arguments |
|
|
Kleinstes Argument |
|
|
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.
Kurzschrift | Englischsprachige Version | |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
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-PARAGRAPH
aus - 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.