END-IF is the terminator that closes an IF statement. In Easytrieve, an IF opens a block of conditional logic, and END-IF marks exactly where that block ends. The rule is short and absolute: every IF must be followed by exactly one END-IF, and that single END-IF closes not only the IF but also any ELSE-IF and ELSE branches that belong to it. Once control passes END-IF, the program continues with the next statement regardless of which branch ran - or whether any branch ran at all. Although END-IF looks trivial, it is one of the most important keywords to master, because a misplaced or missing END-IF is the single most common structural error beginners hit. The compiler cannot guess where you meant an IF to stop, so it keeps swallowing statements into the conditional until it either finds the END-IF or runs out of program - which is why a forgotten END-IF often produces an error message pointing at a line nowhere near the real mistake. This tutorial explains the format of END-IF, the one-per-IF pairing rule, why ELSE-IF and ELSE never take their own terminator, how END-IF behaves in nested IF statements (it closes from the inside out), and the indentation habits that make correct pairing effortless. Worked examples progress from a single guarded statement to a nested decision, and a troubleshooting section shows how to read the confusing errors a missing END-IF produces so you can fix them quickly.
1END-IF
END-IF takes no operands. It is a keyword on a line by itself, placed after the last statement of the IF block it closes. Its only job is to mark the boundary. Simplicity here is a feature: because END-IF carries no options, the only thing you can get wrong is where you put it.
The core rule is that each IF is paired with exactly one END-IF. This holds no matter how many branches the IF has. An IF with three ELSE-IF branches and one ELSE still needs just one END-IF at the very bottom. This is different from languages that require a terminator per branch, and it is what keeps banded Easytrieve decisions compact.
123IF EMP# GT 10000 TOTAL-EMP# = TOTAL-EMP# + 1 END-IF
The simplest use guards a single statement. When EMP# is greater than 10000 the counter is bumped; otherwise the block is skipped. The END-IF closes the block so the next statement runs unconditionally.
When an IF has ELSE-IF or ELSE branches, the same single END-IF closes all of them. You do not - and must not - put an END-IF after each ELSE-IF. The compiler treats the ELSE-IF and ELSE as part of the one IF structure, and the terminator applies to the whole thing.
1234567IF SEX EQ 'M' TOTAL-MALE = TOTAL-MALE + 1 ELSE-IF SEX EQ 'F' TOTAL-FEMALE = TOTAL-FEMALE + 1 ELSE TOTAL-UNKNOWN = TOTAL-UNKNOWN + 1 END-IF
| Branch | Needs its own terminator? |
|---|---|
| IF | The structure needs one END-IF total |
| ELSE-IF (each) | No - shares the single END-IF |
| ELSE | No - shares the single END-IF |
| END-IF | Exactly one, at the bottom |
IF statements can be nested - one IF inside another. Each nested IF needs its own END-IF, and the terminators pair from the inside out: an END-IF always closes the nearest IF that is still open above it. Reading the code from the bottom up, the first END-IF you meet closes the innermost IF, the next closes the IF around it, and so on. This is exactly why consistent indentation matters so much - the visual nesting mirrors the logical nesting.
123456789IF ACCOUNT-TYPE = 'S' IF BALANCE < 0 PERFORM OVERDRAWN-SAVINGS ELSE PERFORM NORMAL-SAVINGS END-IF ELSE PERFORM PROCESS-CHECKING END-IF
The inner END-IF closes the balance test; the outer END-IF closes the account-type test. If you deleted the inner END-IF, the outer ELSE would attach to the inner IF and the whole meaning would change - or the program would fail to compile. Aligning each END-IF under its IF makes this impossible to get wrong.
Because Easytrieve keeps reading statements into an unterminated IF, a missing END-IF rarely errors on the line where you forgot it. Instead the compiler complains later - often at the next activity, the end of the program, or an ELSE that now seems to have no IF. When you see a structural error that does not make sense on the line reported, count your IF and END-IF keywords and check the pairing before anything else.
END-IF closes only IF statements. It is not interchangeable with the other Easytrieve terminators: END-DO closes a DO loop, END-PROC closes a procedure, and END-CASE closes a CASE. Using the wrong terminator - for example closing a loop with END-IF - is a compile error because each block type expects its own partner. If you are unsure which terminator a block needs, see the scope terminators overview linked below.
| Block | Correct terminator |
|---|---|
| IF / ELSE-IF / ELSE | END-IF |
| DO WHILE / DO UNTIL | END-DO |
| PROC procedure | END-PROC |
| CASE selection | END-CASE |
When you start a sentence with "if...", everyone waits to hear the rest before they know what to do. END-IF is like the full stop at the end of that sentence - it tells the computer "the if-part is finished now, carry on". Each "if" gets exactly one full stop. If you have a little if inside a big if, like a small box inside a big box, each box needs its own lid, and you close the little box before you close the big one. Forget a lid and the computer gets confused about where each box ends.
1. What does END-IF do in Easytrieve?
2. How many END-IF statements does one IF need?
3. Do you code an END-IF for each ELSE-IF branch?
4. In nested IFs, which IF does an END-IF close?
5. What happens if you omit a required END-IF?