Simplifying RPG Assignments with EVAL-CORR: A Real-World Example
As RPG developers, we often find ourselves writing repetitive and verbose code to move data between data structures — especially when we fetch records from a database and need to populate another structure with the same fields.
Fortunately, the EVAL-CORR operation (available in RPG Free Format as a simple EVAL assignment when structures share field names) allows us to replace multiple lines of manual assignments with one clean and elegant statement.
In this post, I’ll show you how EVAL-CORR works using a practical example that fetches customer data from a physical file (CLANA00F) and copies selected fields into another data structure.
The Problem: Manual Field Mapping
Suppose you have a data structure UserData filled via an SQL FETCH, and you want to copy its values into another structure CLANArec with a matching layout.
You might be tempted to do something like this:
CLANAREC.CLANN0 = WWANN0;
CLANAREC.CLCCL0 = WWCCL0;
CLANAREC.CLCIB0 = WWCIB0;
CLANAREC.CLNOM0 = WWNOM0;
While this works, it’s verbose, error-prone, and hard to maintain — especially when the number of fields grows or the structure changes.
The Solution: Use EVAL-CORR
If the field names in both data structures match exactly (same spelling and compatible types), you can replace all those assignments with just one line:
eval CLANArec = UserData;
This automatically copies all matching fields from UserData to CLANArec. Cleaner, easier, and safer.
Real Example: Full RPG Free Format Code
Below is a very simple full working RPGLE (Free Format) program that demonstrates this technique.
**free // ********************************************************************* // Reads data from file CLANA00F and copies fields with the same names * // from DS 'UserData' to DS 'CLANArec' using a simplified assignment. * // ********************************************************************* // // This highlights a more maintainable and readable // approach than copying each field manually. // ctl-opt dftactgrp(*no) actgrp(*caller) option(*xref); // Declares the physical file CLANA00F as input-only. This is your customer master file. dcl-f CLANA00F usage (*input); // Customers data // Declares a data structure (CLANArec) with the same layout as the file record format CLANA. // This structure will be filled with data to be used in the program. dcl-ds CLANArec likerec(CLANA); // Declares a manually defined data structure that matches only the selected columns from the file. // This DS is used as the host structure for the FETCH operation. dcl-ds UserData; WWANN0 char(01); WWCCL0 zoned(7); WWCIB0 char(03); WWNOM0 char(50); end-ds; // preapre the data recordset // Declares cursor C1 to select all columns from the file, read-only mode. exec sql declare C1 cursor for select * from CLANA00F for read only; // Ensures cursor is closed before opening — best practice to prevent locks or redefinition issues. exec sql close C1; // Opens the declared cursor. exec sql open C1; // Read recordset // Loop continues as long as there’s no SQL error (SQLCODE = 0). dow Sqlcode = 0; // Fetches a row from the result set into the UserData structure. exec sql fetch C1 into :UserData; // If a record was fetched successfully... if sqlcode = 0; // Instead of this verbose field-by-field assignment: // CLANAREC.CLANN0 = WWANN0; // CLANAREC.CLCCL0 = WWCCL0; // CLANAREC.CLCIB0 = WWCIB0; // CLANAREC.CLNOM0 = WWNOM0; // Use this cleaner, more maintainable form: // This statement automatically assigns values from UserData to CLANArec // for all fields with matching names (case-insensitive and compatible types). // It reduces code verbosity, improves readability, and eases maintenance. eval CLANArec = UserData; endif; enddo; // Closes the SQL cursor after processing to release any associated resources. exec sql close C1; // Marks the last record indicator to end the program and allow the system to reclaim resources. *inlr = *on; |
How It Works
When you write eval CLANArec = UserData;, the compiler uses the EVAL-CORR behavior under the hood:
It looks for fields that exist in both structures (case-insensitive).
It assigns the value from UserData to the corresponding field in CLANArec.
Fields that don’t match are ignored — no errors, no warnings.
The types must be compatible (e.g., char to char, zoned to zoned, etc.).
This technique is ideal when:
You’re working with temporary or fetch-based structures.
You want to simplify and future-proof your code.
You value readability and maintainability.
Conclusion
Using EVAL-CORR is one of those small tricks that can make your RPG code dramatically cleaner and easier to maintain.
Next time you're mapping fields between structures, consider whether a simple eval might do the job. You'll write less code, and your future self (or your colleagues) will thank you.
Have You Used EVAL-CORR Before?
Let me know in the comments if you've already adopted this technique — or if you still prefer manual assignments and why.
And if you found this post helpful, share it with your RPG community!
Comments
Post a Comment