02
Sat, Nov
2 New Articles

The Stuff Legends Are Made Of

APIs
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

As the old saying goes, “with flexibility comes complexity.” Actually, we just made that saying up, but it’s true, nevertheless. In most cases, the more options you give a particular report, the more flexible (and thus useful) it becomes to the user. But adding more options also makes the report more complex to code. It also makes it more difficult for the user to interpret the data on the report. After all, a report that prints accounts receivable totals for an entire organization will show far different totals than one that prints only two of 10 locations. On the outset, this seems obvious, but it may not always be apparent to users that they are looking at a report that only includes locations one and two. For the sake of clarity, your reports need to have a legend that documents the selection criteria used in preparing the report.

Coding a legend to print at the end of a report is not exactly rocket science. It is boring, repetitive work. Anytime we think of “boring, repetitive work,” human nature takes over and we immediately think, “Let somebody else do it!” But when left with a situation where we needed to make changes to the legends of hundreds of reports, we had another thought: What if we could write a single program that could be called at the end of any of our reports and would print the selection criteria used to generate the report? Implementation of such a program would mean that adding to or changing selection parameters on a report would not require that we change the report legend. Such an enhancement would also ensure that the selection criteria always matched all of the options selected.

Implementation of such a procedure would mean that our programmers would not be bored and burdened with this “boring, repetitive work.” We felt that we owed it to our fellow programmers. (And it sure beats writing a couple of hundred subroutines.) Along the way, we could become heroes. Maybe even legends among our peers! How could we resist such a challenge?

Legendary Reasoning

For our purposes, the concept was reasonably simple. To get the selection criteria for any of our reports, we needed only to list the input fields from the display file used to generate the report. The Retrieve Display File API, QDFRTVFD, provided us with this information, but, as we soon found out, you have to do a lot of digging to extract it. Figure 1 illustrates

all of the various data structures we had to go through in order to get to the list of field names. We’ll get to the highlights of the code we used to do this in this article.

The next step in the process was to get the actual data that was keyed into the selection fields. Because all of our reports use the local data area (LDA) to pass the selection criteria from the prompt program to the printing program, this was not much of a problem. Furthermore, because we use a physical file to describe the LDA externally, we could use the text description of each field from that external definition as a label for each selection field used. The List File Fields API, QUSLFLD, provided us with this information. The QUSLFLD API was also able to return the starting buffer position of each field. With this information, we could extract what the user keyed from the LDA by using the offset position in conjunction with the field lengths. Figure 2 shows an example of the final page of a report that was produced using this tool. As you can see, the legend lists a text description for each entry specified and the value keyed into each one. As an added bonus, if any programmer comes along later and adds more operator selections, the new selections will automatically be included in the legend!

To print the legend from one of our reports, we simply insert a call to the PRTLEGEND program at the end of the report program. There were a couple of considerations made when doing this, however. First of all, to get the legend to print in the same spool file as the report, you need to make sure that the printer file QSYSPRT has a shared access path. You can do this by specifying SHARE(*YES) on an Override Printer File (OVRPRTF) command. Second, you must make sure that the printer file is still open when you call the PRTLEGEND program. Failure to consider these factors would result in the legend printing in its own spool file.

The Making of a Legend

The complete code for the PRTLEGEND program, along with a demonstration program, can be downloaded from the Midrange Computing Web site (www.midrangecomputing.com/mc). While PRTLEGEND has 935 source statements, over 450 of the statements are comments describing the data structures used with the Retrieve Display File API, QDFRTVFD. We didn’t have to enter the definition specifications for these structures. They can be found on your system in QSYSINC/QRPGLESRC member name QDFRTVFD. This library has many source files that contain the data structures for many, many APIs. It comes with every AS/400, but you have to install it. If you are going to work with APIs, you owe it to yourself to get acquainted with this library. It will become your principal source of API reference material. Figure 3 shows a portion of the mainline code for the program. The program accepts three parameters: the format name, file name, and library name of the display file used to generate the request for the report. Our program passes these fields to the GetDspFF procedure, which loads array ArryInfo with the names (and length) of each field in the format. Next, it calls the GetFTxt procedure, which loads array AryTxt with the name, description (taken from the TEXT keyword), and buffer position of each field in the REPTDS file. The REPTDS file is the aforementioned external data structure that we use to describe parameters passed to our report programs via LDA. Our program then walks through the AryInfo array, and, for each element, it looks through the AryTxt array to see if the display file field names match names in our REPTDS external data structure. Keep in mind that an external data structure is really nothing more than a physical file. If our program finds a display file field name that matches a name from our external data structure, the program extracts the data from the LDA into a generic print field and prints a legend line.

Figure 4 shows the GetFTxt procedure. This procedure first calls another procedure that returns a pointer to a user space. It then calls the List Database Field API, QUSLFLD, to generate a list of field names for the REPTDS data structure into the newly created user space, using the offsets in each data structure to point to the next structure until it gets to the

list of fields structure using pointer ListPoint. This structure repeats itself for each field in the file. So we process all of the list field structures loading each field name and buffer position into the array AryTxt.

Figure 5 shows some of the code in the GetDspFF procedure. This procedure uses the Retrieve Display File API, QDFRTVDF, to get the names of all the fields in a format in the display file. While this API normally returns its information into one long field, we have directed its output into a user space instead. We did this because a user space can hold much more data than a single field. The way we redirected the output was to base the receiver variable on the same pointer that points to the user space. The rest of the code in this procedure walks through the various data structures (shown in Figure 1) to extract the field names and load them into the array. You’ll have to download the code if you want to see more details on how this all works, but you get the general idea.

Legends in Our Own Minds...

The PRTLEGEND program saved uncounted hours of tedious programming time and tons of money for our company. The programmers hoisted us on their shoulders shouting,
“Hip-Hip-Hooray!” And modest programmers that we are, we simply went about our business looking for other dragons to slay.

OK, we made most of that up. But the PRTLEGEND program does save a lot of hours of mind-numbing programming. If you can use this code (with minor modifications), it might save your programmers a lot of time too. Can’t you hear the cheering?

Doug Pence is the founder and Ron Hawkins is the research and development manager of CPU Medical Management Systems in San Diego, California. Doug can be reached by email at This email address is being protected from spambots. You need JavaScript enabled to view it.. Ron can be reached by email at This email address is being protected from spambots. You need JavaScript enabled to view it.
.

QDFFBASE

Base File Section

QDFFINFO File Header

Section

QDFFINOF

QDFFWUOF QDFFINOF

QDFWFLEI

Where Used File Level

QDFAROF

QDFWNTBO QDFWXLEN

QDFFNTBL

Field Name Table for Entire File

QDFWRCDI Where Used Record Info

QDFWFLDI

Where Used Field Info

QDFARFTE

Record Format Table

QDFFRINF

Record Header Section

QDFFRDPD

Record Level Device Dependant Section

QDFFXRDP

Device Dependant Extension

Section

QDFFRAOF

QDFWRLEN

QDFFXRDO

Figure 1: PRTLEGEND is possible thanks to many APIs.

Report selections:

From Date......................................... 050100

To Date........................................... 053100

Report format..................................... 2

Number of copies.................................. 01

Hold report?...................................... N C *ENTRY PLIST
C PARM InFormat
C PARM InLibrary
C PARM InFile
c If NOT %open(qsysprt)
c Open qsysprt
c endif
c *dtaara define *lda Lda

Figure 2: The output of PRTLEGEND describes record selection criteria.

c in lda
c except Heding

* Get array of field information
c CallP GetDspFF(InFormat:
c InLibrary: InFile) * Get array of text/buffer postion from parameter file
c callp GetFTxt
c Do 1000 x
c eval DsAryInfo = AryInfo(x)
c If Name = *blanks
c leave
c else
c do NbrFlds xx
c move AryTxt(xx) ReturnFmt
c if SfName = Name
c move Length SfLength
c eval PrtField = %subst(Lda:SfBufPos:SfLength)
c eval SfDesc = %trim(sfdesc) + AllPeriods
c except PrtDetail
c leave
c endif
c enddo
c endif
c enddo
c eval *inlr = *on
oqsysprt e Heding1 2 1
o or of
oqsysprt e Heding 12
o or of
o 33 ‘Report selections:’
o ef PrtDetail 1
o SfDesc 65
o PrtField 91 P GetFTxt B export
d GetFTxt PI

d ListFormat S 8
D FileFmt S 10 inz('PARM ')
d FileLib S 20 inz('REPTDS *LIBL')
d I S 4 0 inz
d OverRide S 1
d SpacePtr S *
D UserSpace S 20 inz('RTVTXTSPC QTEMP')

D GenDs DS 140 Based(GenDsPoint)
D OffsetHdr 117 120B 0
D OffsetList 125 128B 0
D NbrInList 133 136B 0
D SizeEntry 137 140B 0
D HeaderDs DS 44 Based(HeadPoint)
D OutFileNam 1 10
D OutLibName 11 20
D OutType 21 25
D OutFormat 31 40
D RecordLen 41 44B 0
D ListDs DS 82 Based(ListPoint)
D SfFld 1 10
D SfType 11 11
D BufferOut 13 16B 0
D FieldLen 21 24B 0
D Digits 25 28B 0
D Decimals 29 32B 0
D FieldDesc 33 82
D ErrorDs DS 116 INZ
D BytesPrv 1 4B 0 inz(116)
D BytesAvl 5 8B 0
D MessageId 9 15
D ERR### 16 16
D MessageDta 17 116

* Create user space for retrieve file description
C Eval SpacePtr = CrtUsrSpc(UserSpace)

*

* List fields to user space
C Call 'QUSLFLD'
C Parm UserSpace
C Parm 'FLDL0100' ListFormat
C Parm FileLIb
C Parm FileFmt
C PARM '1' OverRide
C Parm ErrorDs

Figure 3: The mainline code of PRTLEGEND shows how easy this utility is in concept.

c Eval GenDsPoint = SpacePtr
c Eval HeadPoint = GenDsPoint + OffsetHdr
c Eval NbrFlds = NbrInList
c Eval ListPoint = GenDsPoint + OffsetList * Search list of fields to get size, description, and buffer

* position of each field in file
C Do NbrInList I
C MoveL SfFld SfName
C Move FieldDesc SfDesc
C z-add BufferOut SfBufPos
C Move ReturnFmt AryTxt(i)
c Eval ListPoint = ListPoint + SizeEntry
C EndDo

c eval Nbrflds = i - 1
c return

P GetFTxt E DQDFFBASE DS Based(SpacePtr)
D* Base File Section (QDFFBASE)
D* Base file structure. This is
D* the first structure and is
D* located at offset zero of the
D* returned data.
D QDFFINOF 9 10B 0
D* Displacement to file header
D* section (see structure
D* QDFFINFO)
D QDFFFRCS 11 12B 0
D* Number of record formats
D* specified. This number
D* includes internally generated
D* record formats.
D* Display attribute bits.
D QDFFFSCR 14 15B 0
D* Number of valid file screen
D* sizes (see structure
D* QDFFSCRA,).
D*QDFFSCRS 20 20
D*
D* Screen size table. This area
D* defines the screen sizes
D* valid for externally defined
D* files. This is specified by
D* the DSPSIZ keyword. When not
D* specified, a default
D* DSPSIZ(*DS3) is generated.
D* Structure QDFFSCRA defines
D* the entries. The elements
D* are in the sequence that the
D* DSPSIZ keywords are
D* specified.

* Retrieve display informtion into user space (looking for

* format and field names)
C CALL 'QDFRTVFD'
C PARM QDFFBASE
C PARM 16776704 ReceiveLen
C PARM 'DSPF0100' FileFmt
C PARM SFileLib
C PARM ErrorDs

Figure 4: The GetFTxt procedure extracts information about data in the LDA.

Figure 5: The GetDspFF procedure determines which fields are in the prompting display file.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: