DCL-S in RPGLE - Serving Up Variables with Pizza

What is DCL-S in RPGLE?

DCL-S declares standalone variables in free-format RPGLE—think of them as the toppings, sauce, and cheese you mix and match to build your program. The syntax is as versatile as a pizza menu:

DCL-S variable-name data-type [attributes];

You can define all sorts of variables, from numbers to strings to pointers, and customize them with attributes like length, precision, or arrays. It’s like picking the perfect pizza size and toppings for every order.

The Code Breakdown

This program handles a pizza order at CodeSlice Pizzeria, showcasing every DCL-S variation.

// Lesson: Using DCL-S in IBM i RPGLE Programming
// Purpose: Teach standalone variable declarations with a pizza-ordering twist
// Author: Nick Litten (the RPGLE pizza maestro)

// Declare constants - because pizza constants are forever
DCL-C PIZZA_PRICE 12.99; // Cost of a large pizza
DCL-C MAX_TOPPINGS 5; // Max toppings before pizza rebellion
DCL-C SHOP_NAME 'CodeSlice Pizzeria'; // Our pizza joint’s name

// Declare standalone variables with DCL-S - all the pizza variables!
DCL-S PizzaQty PACKED(3:0); // Number of pizzas (packed decimal)
DCL-S ToppingCount INT(5); // Number of toppings (integer)
DCL-S TotalCost ZONED(7:2); // Total order cost (zoned decimal)
DCL-S CustomerName CHAR(30); // Customer’s name (fixed-length character)
DCL-S DeliveryNotes VARCHAR(50); // Delivery instructions (variable-length)
DCL-S IsRushOrder IND; // Rush order flag (indicator)
DCL-S OrderDate DATE(*ISO); // Order date (ISO format: YYYY-MM-DD)
DCL-S OrderTime TIME(*HMS); // Order time (HH:MM:SS)
DCL-S DiscountAmt DECIMAL(5:2); // Discount amount (decimal)
DCL-S PizzaSize GRAPHIC(10 CCSID(1200)); // Pizza size in Unicode
DCL-S OrderMsg UCS2(100 CCSID(13488)); // Message in UCS-2 for fancy displays
DCL-S TipAmt FLOAT(8); // Tip for delivery driver (floating-point)
DCL-S OrderId UNS(10); // Unique order ID (unsigned integer)
DCL-S TempPtr POINTER; // Pointer for advanced pizza magic
DCL-S PizzaStatus DTAARA('PIZZASTAT'); // Data area for pizza status
DCL-S OrderQueue LIKE(PizzaQty); // Variable like PizzaQty for queue count
DCL-S ToppingList DIM(5) CHAR(20); // Array for topping names

// Main procedure - let’s cook up some variable-packed code!

// Initialize variables with sample data
PizzaQty = 3; // Three pizzas, because more is better
ToppingCount = 4; // Four toppings for flavor explosion
TotalCost = (PizzaQty * PIZZA_PRICE) + (ToppingCount * 1.50); // Base cost
CustomerName = 'CodeNinja Sam'; // Our pizza-loving coder
DeliveryNotes = 'Leave at the server room door'; // Delivery instructions
IsRushOrder = *ON; // Gotta get that pizza fast
OrderDate = %DATE('2025-09-24': *ISO); // Today’s date
OrderTime = %TIME('18:17:00': *HMS); // Current time
DiscountAmt = 5.00; // Generous discount
PizzaSize = 'Large'; // Unicode pizza size
OrderMsg = 'Order for ' + %TRIM(CustomerName); // UCS-2 message start
TipAmt = 2.50; // Tip for the driver
OrderId = 1234567890; // Unique order ID
TempPtr = *NULL; // No pointer magic today
PizzaStatus = 'INPGM'; // Pizza status in data area
OrderQueue = 2; // Two orders in queue
ToppingList(1) = 'Pepperoni'; // First topping
ToppingList(2) = 'Mushrooms'; // Second topping

// Apply discount and check topping limit
IF IsRushOrder;
   TotalCost += 2.00; // Rush order fee
ENDIF;

TotalCost -= DiscountAmt; // Apply discount

// Build order summary
IF ToppingCount > MAX_TOPPINGS;
   OrderMsg = %UCS2('Whoa, ' + %TRIM(CustomerName) + '! ' +
   %CHAR(ToppingCount) + ' toppings? Pizza might collapse!');
ELSE;
   OrderMsg = %UCS2(SHOP_NAME + ': ' + %CHAR(PizzaQty) + ' ' +
   %TRIM(PizzaSize) + ' pizzas, ' + %CHAR(ToppingCount) +
   ' toppings (' + %TRIM(ToppingList(1)) + ', etc.), Total: $' +
   %CHAR(TotalCost) + ', Tip: $' + %CHAR(TipAmt));
ENDIF;

// Display the order summary
DSPLY OrderMsg;

// Shut down the pizza oven and debug the next slice
*INLR = *ON;
RETURN;

Constants

  •  PIZZA_PRICE: $12.99 for a large pizza.
  • MAX_TOPPINGS: 5, to keep the pizza structurally sound.
  • SHOP_NAME: Our pizzeria’s name, CodeSlice Pizzeria.

Variables (DCL-S Variations)

  •  PizzaQty PACKED(3:0): Packed decimal for number of pizzas (3 digits, 0 decimals).
  • ToppingCount INT(5): Integer for topping count (up to 5 digits).
  • TotalCost ZONED(7:2): Zoned decimal for total cost (7 digits, 2 decimals).
  • CustomerName CHAR(30): Fixed-length character for customer name.
  • DeliveryNotes VARCHAR(50): Variable-length character for delivery instructions.
  • IsRushOrder IND: Indicator for rush order status (*ON/*OFF).
  • OrderDate DATE(*ISO): Date in ISO format (YYYY-MM-DD).
  • OrderTime TIME(*HMS): Time in HH:MM:SS format.
  • DiscountAmt DECIMAL(5:2): Decimal for discount amount.
  • PizzaSize GRAPHIC(10 CCSID(1200)): Unicode graphic string for pizza size.
  • OrderMsg UCS2(100 CCSID(13488)): UCS-2 string for fancy output.
  • TipAmt FLOAT(8): Floating-point for delivery tip.
  • OrderId UNS(10): Unsigned integer for unique order ID.
  • TempPtr POINTER: Pointer for advanced memory magic (not used here).
  • PizzaStatus DTAARA('PIZZASTAT'): Data area variable for pizza status.
  • OrderQueue LIKE(PizzaQty): Variable inheriting PizzaQty’s definition.
  • ToppingList DIM(5) CHAR(20): Array for up to 5 topping names.

RPG Logic

  •  Initializes variables with sample data (e.g., 3 pizzas, 4 toppings, customer CodeNinja Sam).
  • Calculates total cost: (PizzaQty * PIZZA_PRICE) + (ToppingCount * 1.50) + (rush fee if IsRushOrder) - DiscountAmt.
  • Checks if ToppingCount exceeds MAX_TOPPINGS. If so, warns about pizza collapse; otherwise, builds a detailed order summary using OrderMsg (in UCS-2 for flair).
  • Uses DSPLY to show the order, because console output is the coder’s pizza delivery.

DCL-S Variations Explained

Here’s a quick rundown of DCL-S variations shown in the code:

Numeric Types

  • PACKED(n:d): Packed decimal (e.g., PizzaQty) for precise calculations.
  • ZONED(n:d): Zoned decimal (e.g., TotalCost) for legacy compatibility.
  • INT(n): Integer (e.g., ToppingCount) for whole numbers.
  • DECIMAL(n:d): Decimal (e.g., DiscountAmt) for modern decimal handling.
  • FLOAT(n): Floating-point (e.g., TipAmt) for scientific or imprecise numbers.
  • UNS(n): Unsigned integer (e.g., OrderId) for non-negative whole numbers.

Character Types

  •  CHAR(n): Fixed-length character (e.g., CustomerName) for consistent strings.
  • VARCHAR(n): Variable-length character (e.g., DeliveryNotes) for flexible strings.
  • GRAPHIC(n CCSID(n)): Unicode graphic string (e.g., PizzaSize) for multilingual support.
  • UCS2(n CCSID(n)): UCS-2 string (e.g., OrderMsg) for advanced character encoding.

Other Types

  •  IND: Indicator (e.g., IsRushOrder) for boolean flags.
  • DATE(format): Date (e.g., OrderDate) for date handling.
  • TIME(format): Time (e.g., OrderTime) for time tracking.
  • POINTER: Pointer (e.g., TempPtr) for memory addressing.
  • DTAARA(name): Data area (e.g., PizzaStatus) for system data storage.
  • LIKE(ref): Inherits another variable’s definition (e.g., OrderQueue like PizzaQty).
  • DIM(n): Array (e.g., ToppingList) for lists of values.

Why DCL-S Rocks

DCL-S is like choosing the perfect pizza toppings: it gives you flexibility to define variables exactly how you need them. Whether it’s a precise decimal for costs or a fancy Unicode string for international customers, DCL-S has you covered. Plus, it keeps your code clear and maintainable, so you’re not untangling variable definitions like a messy pizza order.

Remember to name your variables like you’re naming a pizza: descriptive and clear, like PizzaQty instead of PQ. Vague names are like ordering “something with stuff”—good luck debugging that at midnight!

So, fire up your IBM i, toss this code into the oven, and savor the flexibility of DCL-S in RPGLE. May your variables be as well-defined as a perfectly baked pizza!

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
>