For decades, RPG programmers have relied on the tried-and-true combination of DSPATR(PC) and indicators to manage cursor placement on display files. While this method gets the job done, it can also introduce a host of challenges that hinder code maintainability and introduce potential errors. This blog post dives into a modern alternative – dynamic cursor positioning without indicators – that offers a cleaner and more efficient approach.
The Pervasiveness (and Peril) of Indicators
If you've spent any time working with RPGLE display files, you're likely familiar with the concept of indicators. These special fields within the display file allow you to control the cursor's location. While indicators seem straightforward at first, their widespread use can lead to several problems:
- Code Complexity: Managing numerous indicators throughout your code can quickly lead to spaghetti logic. Keeping track of which indicator points to which field can become a maintenance nightmare.
- Maintainability Woes: As programs evolve, indicator-based cursor control can make modifications cumbersome. Adding new fields or rearranging the display can require a ripple effect of indicator updates throughout the code.
- Error Prone: Incorrect indicator values can lead to unintended cursor placement, causing user confusion and data entry errors. Debugging such issues can be a time-consuming task.
A Modern Alternative: Enter CSRLOC
There's a better way! The RPG language provides a built-in functionality called CSRLOC that allows you to dynamically control the cursor position at runtime. This keyword resides within the display file itself and stores information about the cursor's location, specifically the row and column number. By leveraging CSRLOC, we can eliminate the need for separate indicator fields altogether.
The Power of CSRLOC in Action
Instead of pre-defining cursor positions with indicators, we can utilize the CSRLOC data dynamically. Here's how it works:
Add CSRLOC to the display file. If you have multiple screens, you will need to add it to every format where you need to position to a field.
A R SCR1
A CSRLOC(Z1LINE Z1COLUMN)
A Z1LINE 3S 0H
A Z1COLUMN 3S 0H
- Unleashing QCMDEXC: The
QCMDEXC
RPG built-in function allows us to execute iSeries commands dynamically. In this case, we'll use it to execute theDSPFFD
command, which retrieves information about the display file structure at runtime. This retrieved data includes the crucial CSRLOC values.// Get list of fields in display file // for cursor positioning cmdstr = 'DSPFFD FILE(SLVNDM01) ' + 'OUTPUT(*OUTFILE) OUTFILE(QTEMP/VNDMFLDS)'; qcmdexc(%trim(cmdstr): %len(%trim(cmdstr)));
- Building a Reusable Subprocedure: To avoid code duplication, we can create a subprocedure that takes the record format name and the target field name as input parameters. This subprocedure will:
- Use
QCMDEXC
to executeDSPFFD
and retrieve the CSRLOC data. - Parse the retrieved data to identify the row and column position of the target field based on its name within the record format.
- Utilize this information to dynamically calculate the desired cursor location.
dcl-proc setCursor; dcl-pi *N; @RecFormat VARCHAR(10) value; @FieldName VARCHAR(10) value; end-pi; dcl-s $$recFmt varchar(10); dcl-s $$fldNam varchar(10); $$recFmt = %upper( %trim(@RecFormat) ); $$fldNam = %upper( %trim(@FieldName) ); // Set the cursor based the field exec sql select whdrow, whdcol into :z1line, :z1column from vndmflds where trim(whname) = :$$recFmt and trim(whfldi) = :$$fldNam; return; end-proc;
- Use
By calling this subprocedure whenever you need to position the cursor on a specific field, you can eliminate the need for pre-defined indicators. The subprocedure takes care of calculating the correct row and column based on the current display file structure.
// turn off position indicators 60 thru 79
$recformat = 'SCR1';
%subarr(*in:60:20) = *off;
*in90 = *on; //assume prog
1b if vmname = *BLANKS;
snd-msg 'Vendor name required';
setCursor($recformat:'vmname');
LV leavesr;
1e endif;
Benefits and Considerations
This dynamic approach to cursor positioning offers several advantages:
- Reduced Code Complexity: Saying goodbye to indicators means cleaner and less cluttered code.
- Improved Maintainability: Changes to the display file layout no longer require extensive indicator updates, making your code more adaptable.
- Potential for Flexibility: Dynamic cursor positioning opens doors for more flexible cursor control logic within your program.
There are a couple of considerations to keep in mind:
- Display File Modification: This approach requires adding the CSRLOC keyword to your display file.
- Slight Processing Overhead: The use of
QCMDEXC
for retrieving CSRLOC data introduces a small overhead compared to using indicators. However, in most cases, the benefits of cleaner code outweigh this minor performance consideration.
Conclusion: A Brighter RPGLE Future
By embracing dynamic cursor positioning and ditching the indicator approach, you can write cleaner, more maintainable, and potentially more flexible RPGLE code. This technique is particularly valuable for programs that interact with complex display files or require frequent layout changes. Consider exploring this approach and see how it can transform your RPGLE development experience!
Have You Ditched Indicators Yet? Share Your Experiences!
Have you experimented with dynamic cursor positioning in your RPGLE programs? Share your experiences and insights in the comments below. Let's discuss the potential of this approach and explore its broader applications in the RPG world!
For more RPGLE tips and tricks, check out some of my other posts:
Replacing ERRMSGID with SND-MSG.