As a cleaner coded alternate to a nested If statement, the Case statement provides for conditional processing based on the value that is passed into the Case statement. This value has to be an integer, or an enumerated type.

This passed in value is tested against the different options provided for in the code, and if it matches that statement, then the code is executed.

The structure of the Case statement is multi-line and illustrated as follows -

case <Selector> of

<Option1> : <Statement1>;

<Option2> : <Statement2>;

else

<StatementForEverythingElse>;

end;

Each option requires a response or statement to be defined. It is assumed that the range of results that are passed in to the Case statement will vary over time, thereby qualifying the use of this statement, as it can easily be extended with additional options and response statements added to the code as required.

A Case statement can appear anywhere within the script code within a statement sequence.

Each option offered within the Case statement can result in the execution of multiple statements by grouping them within a Begin...End block.

Executing One Statement Per Option

In this example, the variable called Value is tested to see if the number that it contains equals 2, 4, or 5.

procedure ScriptEvent (var Value : variant);
begin
case Value of
2: LogInfo('The value is equal to 2');
4: LogInfo('The value is equal to 4');
5: LogInfo('The value is equal to 5');
end;
end;

You can add as many different options as required.

Once one option is met as it has a True result because the variable called Value equals one of those options, then the response statement following the option is executed. Once the response statement has been executed, then all processing stops, and the other options further down the Case statement list are not checked.

Executing Multiple Statements Per Option

Only one statement may be processed when an option is met, so if multiple response statements are required, then each option must have its own Begin…End statement block to allow more than one statement to be executed.

In this example, the variable called Value is tested to see if the number that it contains equals 2, 4, or 5.

procedure ScriptEvent (var Value : variant);
begin
case Value of
2: begin
LogInfo('The value is equal to 2');
LogInfo('Second statement to execute if Value = 2');
end;
4: begin
LogInfo('The value is equal to 4');
LogInfo('Second statement to execute if Value = 4');
end;
5: begin
LogInfo('The value is equal to 5');
LogInfo('Second statement to execute if Value = 5');
end;
end;
end;

You can add as many different options as are required.

If the variable called Value equals one of those options, then the response statements within the Begin….End block following the option are all executed. Then all processing stops, and the other options further down the Case statement list are not checked.

Executing A Default Statement If All Other Options Fail

Allowing for the possibility that none of the coded options will be met, a catchall can be included to ensure that other values are recognised by using else.

In this example, the variable called Value is tested to see if the number that it contains equals 2, 4, or 5.

procedure ScriptEvent (var Value : variant);
begin
case Value of
2: LogInfo('The value is equal to 2');
4: LogInfo('The value is equal to 4');
5: LogInfo('The value is equal to 5');
else
LogInfo('The value is something else');
end;
end;

You can add as many different options as required.

If none of the options that have response values are met as True, then the processing drops out and executes the response statement following else as a catchall. Then all processing stops.

Executing A Case Statement Using A Range

It is possible to cover more option values by including a range within your option selection. This is particularly useful if there are multiple options that would all have the same response statement.

A range is indicated by the two values in the range separated with two . . (dots or full-stops) with no additional space between.

In the following example, we are checking for a range of ages and responding with a general age description. Along with several range options, there is also a comment and a default catchall should no option be met as True.

procedure ScriptEvent (var Value : variant);
var
AgeInYears:Integer;
AgeBand:String;
begin
// AgeInYears := 52;
// The above line sets the age manually for testing purposes
case AgeInYears of
0..12: AgeBand := 'Child';
13..19: AgeBand := 'Teenager';
20..64: AgeBand := 'Adult';
else
AgeBand := 'Pensioner';
end;
LogInfo('Age '+IntToStr(AgeInYears)+' is a '+AgeBand);
end;

As always, additional options can be added as required.

Here we have a range of ages, and if the value passed in to the Case statement through the variable AgeInYears falls within one of the ranges, then the appropriate response statement will be executed.

If the value held in AgeInYears for example is 37 then the response will be Adult,

If the value held in AgeInYears is 8 then the response will be Child,

But of the value held in AgeInYears is 82 which is outside the ranges 0 to 12, 13 to 19, 20 to 64, then the response will be Pensioner,

The effect of executing this code is shown in the following Log entry.

A Case Statement Compared To A Nested If Statement

To illustrate the point that a nested If statement allows for greater flexibility, although it is considerably messier and more difficult to follow the code, the following example illustrate both types of statement to accomplish the same ultimate result outcome.

The following code uses the Case statement.

procedure ScriptEvent (var Value : variant);
var
AgeInYears:Integer;
AgeBand:String;
begin
case AgeInYears of
0..12: AgeBand := 'Child';
13..19: AgeBand := 'Teenager';
20..64: AgeBand := 'Adult';
else
AgeBand := 'Pensioner';
end;
LogInfo('Age '+IntToStr(AgeInYears)+' is a '+AgeBand);
end;

This code following uses a nested If statement to achieve the same result.

procedure ScriptEvent (var Value : variant);
var
AgeInYears:Integer;
AgeBand:String;
begin
if ((AgeInYears >= 0) and (AgeInYears <= 12)) then
AgeBand := 'Child'
else
if ((AgeInYears >= 13) and (AgeInYears <= 19)) then
AgeBand := 'Teenager'
else
if ((AgeInYears >= 20) and (AgeInYears <= 64)) then
AgeBand := 'Adult'
else
AgeBand := 'Pensioner';
LogInfo('Age '+IntToStr(AgeInYears)+' is a '+AgeBand);
end;

From the above examples you will see how much easier to read and cleaner the code becomes when a Case statement is used in place of a nested If statement.