# Programmeren in COBOL/Printversie

Programmeren in COBOL
DISPLAY "Hallo Wereld!"
In dit deel van het boek leer je vooral de basis van COBOL. De 4 eerste hoofdstukken zijn daarbij essentiëel als je deze taal onder de knie wilt krijgen. Het vijfde hoofdstuk kun je links laten liggen, zeker wanneer je nog maar net de taal leert. Later in dit boek wordt er echter wel zaken gebruikt die in het vijfde hoofdstuk worden besproken.

## De inhoud van dit deel

* Inleiding (Oef ): Hier leer je de basis om in COBOL programma's te maken. Er wordt geleerd hoe je gegevens invoert en uitvoert. En hoe je variabelen, in dit programmeertaal velden genoemd, aanmaakt.
* Berekeningen (Oef )
* IF en lussen (Oef )
* Deelprogramma's (Oef )
* Werken met tekst (Oef )
1. Inleiding
Dit is de inleiding van Programmeren in COBOL. COBOL is niet hoofdlettergevoelig dus een "a" betekent hetzelfde als een "A". Voor de overzichtelijkheid wordt aangeraden om bepaalde regels te volgen, sleutelwoorden(syntax) worden in hoofdletters geschreven en velden(variabelen) met kleine letters. Natuurlijk is de inhoud van een veld wel hoofdlettergevoelig.

## Indeling van een programma

Een programma in COBOL wordt ingedeeld in 4 delen of divisies.
COBOL-code: Indeling
Met de volgende betekenis:
IDENTIFICATION DIVISION geeft informatie over het programma. Bijvoorbeeld wat de naam is van het programma of wie het gemaakt heeft.
De ENVIRONMENT DIVISION is voornamelijk voor het gebruiken van bestanden door het programma.
In de DATA DIVISION komen al de verschillende soorten velden(variabelen) die het programma gebruikt.
In de PROCEDURE DIVISION staat de werkelijke programmacode.
Let op: de divisies moeten worden geschreven vanaf de 8ste positie. M.a.w. als je dit zou typen in een editor moet je voor je bijvoorbeeld IDENTIFICATION DIVISION typt, 7 spaties laten. Dit gebruik stamt nog uit de tijd toen COBOL op papier werd geschreven. Achter deze divisies moet een punt komen. Wat ook belangrijk is om te weten, is dat alleen IDENTIFICATION DIVISION en PROCEDURE DIVISION verplicht zijn in een programmacode. De andere twee moet je alleen schrijven als je het werkelijk gebruikt.
COBOL-code: Positie

## Hello World! (DISPLAY)

    Zie ook DISPLAY voor meer informatie.
Laten we ons eerste programma schrijven en het traditionele "Hello World!" op het scherm tonen.
COBOL-code: Hello World
Zoals eerder werd gezegd geeft IDENTIFICATION DIVISION informatie over het programma zelf. PROGRAM-ID. (let op de punt) is een onderdeel van deze divisie, die geeft aan hoe het programma heet. Na een naam te hebben gegeven, moet ook een punt komen.
Programma's kunnen worden ingedeeld in deelprogramma's (zie hoofdstuk deelprogramma's). "Hoofd." kun je in dit geval vergelijken met "main" in bijvoorbeeld java. Dit geeft gewoon aan dat dit het belangrijkste stukje code is van het programma. Je kunt "hoofd." echter vervangen door een andere naam.
De werkelijke programmacode wordt pas geschreven vanaf de 12de positie.
DISPLAY laat iets zien op het scherm. Wil je zoals in dit programma gewoon tekst tonen, dan moet je de tekst tussen aanhalingstekens plaatsen ("").
STOP RUN. (let op de punt) geeft aan dat je aan het einde van het programma zit.

## Commentaar

Het zou natuurlijk handig zijn als je commentaar kon plaatsen in een programma. Daarmee kun je later zien wat bijvoorbeeld bepaalde delen van een programma doen.
COBOL-code: Commentaar
Om commentaar te vermelden, moet je gebruik maken van een asterisk (*) op de 7de positie (dus voor de asterisk moet je 6 spaties laten). De hele regel wordt dan gezien als commentaar.

## Velden(variabelen)

Variabelen worden in COBOL velden genoemd en gedeclareerd in de DATA DIVISION. Meer bepaald bij WORKING-STORAGE SECTION.

### Numerieke velden

COBOL-code: Numerieke velden
Dit is een voorbeeld van een numeriek veld. Een veld begint op de 8ste positie. Het begint met het getal 77. 77 is het zogenaamde niveaunummer. Nu uitleggen wat het is zou zinloos zijn, aangezien dit nog maar de basis is. Naast 77 zou je ook 01 kunnen gebruiken. Het niveaunummer wordt gevolgd door de naam die je wilt geven aan het veld. Vaak wordt de naam van het veld vanaf de 12$^{de}$ positie geschreven. Daarna wordt het gevolgd door PIC(of PICTURE) dat bepaalt welk soort veld het is. De "9" staat voor een numeriek veld. Het aantal negens bepaalt hoeveel cijfers het veld maximum mag bevatten, 10 keer een 9 schrijven betekent dus een numeriek veld van 10 tekens lang. Als je een waarde aan een veld wilt toevoegen, kun je VALUE gebruiken, maar dit is niet verplicht. Vergeet opnieuw de punt op het einde niet.
COBOL-code: Numerieke velden
In plaats van bijvoorbeeld "77 getal PIC 9999999999." om de lengte te bepalen, kan je evengoed gewoon "PIC 9(10)" schrijven om aan te geven dat het getal uit 10 cijfers zal bestaan. Beide hebben hetzelfde effect.
Als je bijvoorbeeld het getal 7 in een variabele zet met PIC 999 dan krijg je op het scherm "007" te zien. Dus waar geen getal komt wordt 0 geplaatst. Later zullen we zien hoe je dit kunt wegwerken(zie hoofdstuk editing).

### Alfanumerieke velden

Dit is natuurlijk te vergelijken met een String in de programmeertaal Java. Je kunt zo'n veld declareren met PIC X. De X geeft opnieuw het soort variabele en zijn maximale lengte aan.
COBOL-code: Alfanumeriek velden
Ook hier kan VALUE worden gebruikt, alleen moet de inhoud nu tussen aanhalingstekens komen ("string" of 'string').
COBOL-code: Alfanumeriek velden

## Een simpel programma

COBOL-code: Getal
Je kunt dus makkelijk 2 velden in dezelfde DISPLAY tonen. Dit zorgt er wel voor dat de twee velden naast elkaar komen te staan. Om een spatie tussen de twee velden te hebben, kun je gewoon " " doen. Wil je dat ze onder elkaar komen dan zet je ze gewoon in 2 DISPLAY’s.
COBOL-code: DISPLAY

## ACCEPT

    Zie ook ACCEPT voor meer informatie.
Het zou natuurlijk leuk zijn moest de gebruiker input kunnen geven. Dit gebeurt via ACCEPT, na ACCEPT moet je het veld geven waarin de gebruiker iets voor moet ingeven.
COBOL-code: ACCEPT
Het vreemde aan ACCEPT is dat wanneer de gebruiker iets ingegeven heeft, de computer een biep-geluid geeft. Om dit te vermijden kan je NO BEEP gebruiken.
COBOL-code: NO BEEP

## MOVE

Met behulp van MOVE kun je makkelijk data overbrengen van het ene veld naar een andere. Maar je kunt ook gewoon een getal of tekst via MOVE naar een veld overbrengen.
COBOL-code: MOVE

## Decimale getallen

Het stukje over numerieke velden ging alleen over gehele getallen en dus geen decimale. In COBOL moet je als je een decimaal getal wilt gebruiken dat ook zo declaren.
COBOL-code: Decimale getallen
De V na PIC geeft aan waar je de decimale punt wilt hebben. Als je een decimaal getal wilt ingeven, moet je een punt(.) gebruiken en geen komma(,). Dit is omdat COBOL ontwikkeld is in Amerika, waar een decimaal getal wordt aangegeven met een punt. Als je het getal echter toont op het scherm, komt er geen punt te staan. De V is alleen voor het inlezen van een getal en om er mee te rekenen. Wil je toch een punt hebben, dan moet je een extra variabele declareren (zie hoofdstuk editing).
COBOL-code: Decimale getallen
Het veld "uitvoer" zal gebruikt worden om het op het scherm te laten zien. Het verschil is dat de V vervangen werd door een punt. Bij dit veld moet je de inhoud kopiëren vanuit het veld "getal" door middel van MOVE.

## Negatieve getallen

Er geldt ook iets gelijkaardigs voor negatieve getallen, alleen is het hier erger. Als je negatieve getallen wilt gebruiken, moet je die ook eerst declareren.
COBOL-code: Negatieve getallen
Als je dus een negatief getal wilt, moet je na PIC S999 zetten. S betekent sign (teken) en geeft aan dat het een negatief getal mag zijn. Dit geeft echter een probleem, zoals hieronder te zien is in de schermtekst als je het programma uitvoert.
88Q is dus niet het getal dat we hebben ingegeven. Hier kun je echter perfect mee rekenen, maar zoals bij een decimaal getal moet je er iets speciaal mee doen. Je hebt weer een extra veld nodig.
COBOL-code: Negatieve getallen
De "-" geeft aan waar je het teken wilt (zie hoofdstuk Editing). Opgelet, dit betekent niet dat er altijd een - zal staan; bij een positief getal zal er geen teken staan. Gebruik je daarentegen PIC +999 dan staat er altijd een teken, hetzij +, hetzij -, afhankelijk van de inhoud. Gebruik opnieuw MOVE om de inhoud van getal naar uitvoer te kopiëren.
2. Berekeningen
Dit is een hoofdstuk waar je kunt leren hoe je iets moet berekenen in COBOL.

## COMPUTE

    Zie ook COMPUTE voor meer informatie.
COMPUTE is de makkelijkste manier waarmee je iets kunt berekenen in COBOL. De volgende delen van deze pagina zijn hierdoor eigenlijk onnodig, maar het kan best leuk zijn om te weten dat je het ook anders kunt doen. Rekenen wordt gedaan met +, -, *, /, **(machten). Om die tekens te gebruiken, moet je ze tussen 2 spaties zetten. Nooit bijvoorbeeld "1+1" maar altijd 1 + 1.
COBOL-code: COMPUTE
De variabelen waar de uitkomst moet komen te staan aan de linkerkant van de "=" de berekening staat altijd aan de rechterkant. "=" lees je dus best als "wordt" (en niet "is"). Het is mogelijk om af te ronden in COBOL dankzij ROUNDED: Een 1, 2, 3 en 4 worden naar beneden afgerond; 5, 6, 7, 8 en 9 worden naar boven afgerond: Stel dat de uitkomst 4.5 is, maar het komt terecht in een variabele met PIC 9 die alleen 4 opslaat. Een wetenschappelijke/wiskundige afronding naar boven kan je uitvoeren met ROUNDED.
COBOL-code: COMPUTE
Ook kun je de uitkomst in meerdere variabelen zetten en kun je de ene niet laten afronden en de andere dan weer wel.
COBOL-code: COMPUTE
Wanneer er een complexe berekening wordt gedaan, hebben bepaalde tekens voorrang op andere, net zoals in de wiskunde. Haakjes hebben altijd voorrang. Daarna komt **, gevolgd door * en / (evenwaardig) en tenslotte + en -. Gelijk(waardig)e tekens worden van links naar rechts uitgevoerd.

### Wortel

Hoewel er geen teken bestaat om een wortel te doen met COMPUTE, is er toch een simpele manier om het te doen. Er bestaat namelijk een alternatieve notatie voor een wortel.
${\sqrt {a}}=a^{\frac {1}{2}}$
Links staat een gewone vierkantswortel en rechts staat 2 tot de 1/2 macht. Die zijn namelijk gelijk. De algemene notatie is:
${\sqrt[{n}]{a}}=a^{\frac {1}{n}}$
Dit maakt dat je een wortel kan berekenen door het volgende te doen.
COBOL-code: COMPUTE

## ADD

    Zie ook ADD voor meer informatie.
Naast COMPUTE zijn er nog ander manieren om te rekenen. Het enige voordeel dat deze manier heeft is dat het zeer logisch kan overkomen.
COBOL-code: ADD
Hier wordt dan de inhoud van verkoop toegevoegd aan de inhoud van omzet. Het is mogelijk om met meerdere variabelen bij ADD te gebruiken.
COBOL-code: ADD
Getal1 en getal2 worden zowel bij getal3 als bij getal4 opgeteld. Net zoals COMPUTE kun je gebruik maken van ROUNDED. Het woord GIVING zorgt dat het resultaat in een andere variabele gezet wordt.
COBOL-code: ADD

## SUBTRACT

    Zie ook SUBTRACT voor meer informatie.
COBOL-code: SUBTRACT
SUBTRACT verschilt niet erg van ADD: alleen wordt hier FROM gebruikt in de plaats van TO. Ook hier kan je GIVING en ROUNDED gebruiken.
COBOL-code: SUBTRACT
Waar je wel voor moet opletten is de declaratie van de variabelen. Als je SUBTRACT doet, kun je een negatief getal krijgen. Daarom is het best dat je S gebruikt bij de variabelen, bijvoorbeeld PIC S999. (data editing).

## MULTIPLY

    Zie ook MULTIPLY voor meer informatie.
COBOL-code: MULTIPLY
Hier worden getal2 en getal3 vermenigvuldigd met getal1. Ook hier kun je ROUNDED en GIVING gebruiken.
COBOL-code: MULTIPLY

## DIVIDE

    Zie ook DIVIDE voor meer informatie.
COBOL-code: DIVIDE
Opgelet, hier worden getal2 en getal3 gedeeld door getal1 (niet omgekeerd). Hier kun je ook ROUNDED en GIVING gebruiken.
COBOL-code: DIVIDE
Naast DIVIDE ... INTO kun je ook DIVIDE ... BY gebruiken.
COBOL-code: DIVIDE
Dit zorgt ervoor dat de berekening wordt omgedraaid. getal 1 zal worden gedeeld door getal2 in de plaats van getal2 door getal1. Je kunt bij DIVIDE ook de rest opslaan via REMAINDER.
COBOL-code: DIVIDE
Hier zal de rest worden opgeslagen in getal4.

## Speciale gevallen

Hoewel de notatie ingewikkeld is, kan met bovenstaande operaties bondiger programmacode geschreven worden. Onderstaande codelijnen zijn equivalent aan elkaar:
COBOL-code: Speciale gevallen
Foutmeldingen kunnen opgevangen worden met ON SIZE ERROR. Als er de uitkomst niet in de PIC (PICTURE) past, kan een subroutine opgeroepen worden.
COBOL-code: Speciale gevallen

## Conclusie

COMPUTE is de eenvoudigste manier om berekeningen uit te voeren. Het gaat veel sneller en je kunt snel complexe berekeningen uitvoeren zonder al teveel programmeerwerk. Wil je toch ADD, SUBTRACT, MULTIPLY en DIVIDE gebruiken dan is het aangeraden om goed te oefenen.
3. IF en lussen
In dit hoofdstuk leer je over conditionele expressies (IF) en herhalingen (PERFORM n TIMES, PERFORM UNTIL ...).

## Condities
### Relatiecondities

Via een relatieconditie vergelijk je een veld, constante of een rekenkundige uitdrukking met een andere: Groter, kleiner of gelijk. Dit kan met de operatoren >, <, =, >= en <=.

### Tekencondities

Dit zijn POSITIVE, NEGATIVE en ZERO. Hiermee vergelijk je een veld, constante of een rekenkundige uitdrukking om respectievelijk te zien of ze positief, negatief of nul zijn.

### OR en AND

Hiermee kun je meerdere condities gebruiken. Bij OR moet één van de relatie condities waar zijn bij AND moeten beide waar zijn.

## IF-statement

    Zie ook IF voor meer informatie.
In programmeren kun je 2 of meer dingen met elkaar vergelijken en op basis daarvan iets al of niet uitvoeren. Dit kan met IF ... END-IF. In onderstaand programma kan de gebruiker een getal raden. Als het getal juist is, dan krijgt hij "goed gegokt" op het scherm.
COBOL-code: IF-statement
IF zal de inhoud van de variabele vergelijken met 5. Als het overeenkomt, zal wat er tussen IF en END-IF staat, uitgevoerd worden. Met ELSE kan je ook iets doen in het andere geval. (THEN hoeft niet geschreven te worden, maar komt de leesbaarheid wel ten goede.)
COBOL-code: IF-statement
THEN geeft aan wat er gebeurt als het goed is en ELSE als het fout is. Natuurlijk kun je ook 2 variabelen met elkaar vergelijken zoals hier de IF getal vergelijkt met gezochtgetal.
Een IF moet altijd worden afgesloten met END-IF, anders leest de compiler tot bij het volgende punt. Moderne COBOL-conventies raden het gebruik van END-IF aan.

## EVALUATE

    Zie ook EVALUATE voor meer informatie.

## Lussen

    Zie ook PERFORM voor meer informatie.
Er zijn twee manieren om lussen te gebruiken: door middel van TIMES of UNTIL. TIMES laat een lus een aantal keren uitvoeren. Bij UNTIL moet er aan een bepaalde voorwaarde voldaan worden voordat de lus stopt. In beide gevallen moet er wel eerst PERFORM worden gebruikt.

### TIMES

COBOL-code: Lus met times
Met dit programma wordt "times" 60 keer getoond op het scherm. Er kan natuurlijk ook gebruik gemaakt worden van een variabele die bepaalt hoe vaak de lus moet worden uitgevoerd.

### UNTIL

COBOL-code: Lus met UNTIL
Hoewel dit voorbeeld sterk overeenkomt met het vorige, is het toch fundamenteel verschillend: als je de - vervangt door een +, dan zal de lus nooit eindigen!(Mainframes stoppen gelukkig vanzelf na een seconde (dure) rekentijd.) Om aan deze lus een einde te brengen moet er voldaan worden aan een bepaalde voorwaarde hier is dat wanneer het getal 0 bevat. Er kunnen ook meerdere condities bij UNTIL worden gebruikt.
COBOL-code: Meerdere condities.

#### VARYING

Deze lus kan vergeleken worden met de for-lus in andere talen. Maar moet echter gecombineerd worden met UNTIL.
COBOL-code: Lus met VARYING
Deze lus begint ook met PERFORM gevolgd door VARYING. i is de teller in deze lus en wordt gevolgd door FROM. FROM bepaalt de start positie van de teller i in de plaats van een cijfer kan er ook een veld staan. Dan komt BY en betekent hoeveel er wordt opgeteld of afgetrokken(je kan dus ook een negatief getal gebruiken) van de teller per keer dat de lus wordt uitgevoerd. Dan komt UNTIL die werkt net zoals bij de gewone UNTIL als er aan een bepaalde voorwaarde wordt voldaan eindigt de lus.
4. Deelprogramma's
Dit is een hoofdstuk waar je kunt leren hoe je deelprogramma's kunt maken in COBOL.

## Gebruik van deelprogramma's

Deelprogramma’s zijn deeltjes code die apart worden gezet en gebruikt worden door het hoofdprogramma. Dit wordt gedaan zodat de programmacode overzichtelijker wordt en stukjes code opnieuw kan worden gebruikt. Een deelprogramma voert slechts één taak uit. Daardoor is het belangrijk om een goede naam te geven aan het deelprogramma dat zegt, liefst in één woord, wat het doet.

## De simpele manier

COBOL-code: Deelprogramma
Dit is een simpel voorbeeld van een deelprogramma. Een deelprogramma wordt opgeroepen door middel van PERFORM, dus hetzelfde als bij een lus. Na PERFORM komt de naam van het deelprogramma in dit geval toon. Een deelprogramma wordt na de STOP RUN. van het hoofdprogramma geschreven. De naam van het deelprogramma wordt geschreven vanaf de 8ste positie, gevolgd door een punt. De code van het deelprogramma wordt, net zoals bij het hoofdprogramma, geschreven vanaf de 12de positie. Het is belangrijk om te onthouden dat na de code van het deelprogramma een punt komt dat aangeeft dat er een einde is gekomen aan het deelprogramma. Na een deelprogramma kunnen eventueel nog andere worden geschreven. Ook kan er van één deelprogramma worden verwezen naar een ander.

## Deelprogramma met times

COBOL-code: Deelprogramma met TIMES
Zoals bij lussen, kan er ook gebruik gemaakt worden van TIMES. PERFORM wordt gevolgd door de naam van het deelprogramma (tel) en ... TIMES, het aantal keer dat het uitgevoerd moet worden. Dit is ook een voorbeeld van een verwijzing vanuit een deelprogramma naar een ander.

## Deelprogramma met UNTIL

COBOL-code: Deelprogramma met UNTIL
Dit programma doet eigenlijk hetzelfde als het vorige maar hier wordt gebruik gemaakt van UNTIL. Dit is grotendeels hetzelfde. PERFORM wordt gevolgd door de naam van het deelprogramma en vervolgens UNTIL met de voorwaarde waaraan moet voldaan worden om te stoppen.
5. Werken met tekst
In dit hoofdstuk worden de verschillende manieren uitgelegd om te werken met tekst.

## ALPHABETIC

Via ALPHABETIC kun je controleren of de inhoud van een veld alleen maar hoofdletters, kleine letters en spaties bevat. Je kunt dit in een programma als beveiliging inbouwen, zodat de gebruiker geen verkeerde informatie geeft. Als je bijvoorbeeld een naam vraagt, kun je controleren dat het geen getal is of rare tekens bevat.
COBOL-code: ALPHABETIC
Naast ALPHABETIC bestaat er ook nog ALPHABETIC-LOWER en ALPHABETIC-UPPER. ALPHABETIC-LOWER controleert of alles in kleine letters staat en UPPER controleert of alles in hoofdletters staat.

## Tekens vervangen

Tekens vervangen gaat via het INSPECT-statement maar er zijn twee manieren om dat statement te gebruiken. Via REPLACING en CONVERTING, zowel bij numerieke als bij alfanumerieke velden.

### REPLACING

REPLACING maakt het mogelijk om in een veld een teken te veranderen door een ander teken of een stukje tekst door een ander stukje tekst.
COBOL-code: Tekst vervangen
ALL betekent in dit geval dat alle p’s worden vervangen door m’s. Naast ALL, kan je ook FIRST en LEADING gebruiken. FIRST betekent dat alleen de eerste vervangen wordt, en LEADING vervangt alleen als het helemaal vooraan staat. Je kunt slechts één veld tegelijkertijd gebruiken. Wat je vervangt en waarmee je het vervangt, moeten een gelijke tekenlengte hebben. 2 tekens moeten altijd vervangen worden door 2 tekens. Ook is het mogelijk om andere velden en constanten te gebruiken, zoals REPLACING ALL tekst BY andertekst of REPLACING ALL ZERO BY quote.

### CONVERTING

Een stuk tekst omzetten naar allemaal hoofdletters, kan met op verschillende manieren. Het kan omslachtig met REPLACING: REPLACING ALL "a" by "A", REPLACING ALL "b" by "B" enzovoort. Efficiënter gaat het met het INSPECT-statement in combinatie met CONVERTING.
COBOL-code: Tekst vervangen
Wanneer je CONVERTING gebruikt, kijkt COBOL eerst naar het veld dat je wilt omzetten. Hij kijkt naar het eerst teken, in dit geval de letter t, en zoekt die vervolgens in het veld kleineletters. Als COBOL de letter heeft gevonden, onthoudt die de positie van die letter, in dit geval positie 20. Dan kijkt het naar hoofdletters en zoekt wat er op positie 20 staat, dus hoofdletter T. Dit proces wordt herhaald tot alle letters vervangen werden. Voor de rest gelden dezelfde regels als bij REPLACING.
Dit algoritme kan gebruikt worden om een tekst op eenvoudige manier te versleutelen met een geheime code.
COBOL-code: Caesarcijfer-rotatie3

## Tekst opslitsen met UNSTRING

    Zie ook UNSTRING voor meer informatie.
Via UNSTRING kun je een alfanumeriek veld met tekst opsplitsen in kleinere velden.
COBOL-code: UNSTRING
Dit programma leest een datum in volgens ddmmjjjj, wat betekent dat een datum als 21 april 2007 moet worden geschreven als 21042007. Uiteindelijk wordt de datum verdeeld over de velden dag, maand en jaar. Na UNSTRING moet het veld komen dat je wilt opsplitsen. Na INTO moeten dan de velden komen waar de opgesplitste tekst moet komen. Het aantal velden mag minder of meer zijn dan het aantal stukjes tekst dat ontstaat door de UNSTRING.
Mensen schrijven hun datums niet zoals 21042007 maar eerder als 21-04-2007. UNSTRING maakt het mogelijk om een tekst op te splitsen op basis van een bepaald teken in dit geval moet dat "-" zijn. Dit gebeurd als volgt.
COBOL-code: UNSTRING
DELIMITED geeft dus aan op basis van welk teken de tekst moet worden opgesplitst.