23
Mon, Dec
1 New Articles

What Is the Difference Between *OMIT and *NOPASS?

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

Do you know the best way to use optional parameters with procedures?

 

When you're using procedures, you have to ability to support optional parameters by using the special keywords *NOPASS and *OMIT. This article discusses the difference between the two and the appropriate times to use them.

*NOPASS

Let's begin with the *NOPASS option. The *NOPASS keyword specifies that the parameter is an optional parameter and does not need to be passed.

 

When you specify a parameter as being optional with the *NOPASS keyword, any subsequent parameters must also be specified as *NOPASS. This makes sense because, if you were allowed to skip parameters, how would the procedure being called be able to figure out which parameters you intend to send?

Determining How Many Parameters Were Passed

Once you specify parameters as being optional, you need to be able to support them within your procedure. Because the variables are not initialized, if you try to access them within the procedure, your program will crash or it will throw an exception if you are monitoring for it. To see how many parameters were passed, you can use the %parms built-in function (BIF) inside of your procedure. The %parms BIF will return the number of parameters that were passed into the procedure.

Creating a Procedure to Use *NOPASS

To illustrate the use of the *NOPASS special keyword, let's create a procedure that uses this functionality. For our example, we will create a procedure that uses the CPYTOIMPF command to export files to the IFS. This will allow us to easily export physical files with a simple line of code in our RPG programs.

 

For our programs, we will use the QCMDEXC API to execute our command. Here's the prototype for that:

 

     D* Prototype for QCMDEXC API

     D ExecuteCommand...

     D                 PR                  extPgm('QCMDEXC')

     D  argInCommand              65535A   const options(*varsize)

     D  argInLength                  15P 5 const

 

To illustrate the use of the *NOPASS keyword, we will create a procedure that calls the CPYTOIMPF command called exportFile. Here's the prototype for that:

 

     D* Prototype for CPYIMPF procedure

     D exportFile...

     D                 PR             1N

     D   argFromFile                 10A   const

     D   argFromLib                  10A   const options(*NOPASS)

     D   argFromMbr                  10A   const options(*NOPASS)

     D   argToFile                  512A   const options(*NOPASS)

 

The first parameter is the physical file that we are exporting from. Because we are exporting a file, this parameter is required, so I did not use the *NOPASS option on this one. But all the rest can be defaulted to another value, so these have been assigned to be optional using the *NOPASS keyword.

 

And here is our exportFile procedure using the *NOPASS keyword on three of the four parameters:

 

     P exportFile...

     P                 B                   EXPORT

     D exportFile...

     D                 PI             1N

     D   argFromFile                 10A   const

     D   argFromLib                  10A   const options(*NOPASS)

     D   argFromMbr                  10A   const options(*NOPASS)

     D   argToFile                  512A   const options(*NOPASS)

     D* Local Variables

     D   svReturn      S              1N

     D   svToFile      S            512A

     D   svCmdString   S           2000A

      /free

        svReturn = *OFF;

        //---------------------------------------------------------

        // Initialize the Defaults.

        //---------------------------------------------------------

        svToFile = %trim(argFromFile) + '.txt';

        if %parms > 3;

          svToFile = %trim(argToFile);

        endif;

        //-------------------------------------------------------------

        // CPYTOIMPF

        //-------------------------------------------------------------

        svCmdString = 'CPYTOIMPF FROMFILE(';

        // Library (Optional)

        if %parms > 1;

          svCmdString = %trim(svCmdString) + %trim(argFromLib) + '/';

        endif;

        // File (Mandatory)

        svCmdString = %trim(svCmdString) + %trim(argFromFile);

        // Member (Optional)

        if %parms > 2;

          svCmdString = %trim(svCmdString) + ' ' + %trim(argFromMbr);

        endif;

        svCmdString = %trim(svCmdString) + ') '

               + 'TOSTMF(''' + %trim(svToFile) + ''') MBROPT(*REPLACE) '

               + 'STMFCCSID(*PCASCII) RCDDLM(*CRLF) DTAFMT(*FIXED)';

        monitor;

          ExecuteCommand(%trim(svCmdString):%len(%trim(svCmdString)));

        on-error;

          // Exception

          svReturn = *ON;

        endmon;

        return svReturn;

      /end-free

     P                 E

 

For the library and the physical file member, we have dynamically built the CPYTOIMPF command to include them into the command to be executed if they were passed into the procedure. The target stream file to be created on the IFS will be defaulted to match the name of the physical file with a .txt extension if one was not specified.

 

To test out our procedure, we'll try a different permutation of each option available from the main procedure:

 

      /free

       if (exportFile('EMPHIST'));

         dsply 'Error on Export!';

       endif;

       if (exportFile('EMPHIST':'MYLIB'));

         dsply 'Error on Export!';

       endif;

       if (exportFile('EMPHIST':'MYLIB':'EMPHIST'));

         dsply 'Error on Export!';

       endif;

       if (exportFile('EMPHIST':'MYLIB':'EMPHIST':

                      '/Public/EmployeeHistory.txt'));

         dsply 'Error on Export!';

       endif;

       *inlr = *ON;

      /end-free

 

For our code sample, we allow the library and the member to be optional parameters and we set default values if they are not passed.

 

What if we want to use the default for the library but want to pass the member? Or what if we want to use the defaults for the library and member but specify the output file name? This is where the *OMIT keyword comes into play.

*OMIT

The *OMIT keyword indicates that the parameter is optional, but it will use the *OMIT special value as a placeholder to indicate that it is not being passed. Then we could have additional parameters after the omitted parameter. And with *OMIT, we do not have to specify the rest of the parameters as being omitted. This is because the optional parameter is being identified.

 

The *OMIT does identify the parameter as being valid, so you can't use the %parms keyword to determine if a parameter was omitted or not. And even if you could, if you had multiple omitted parameters, you wouldn't be able to determine which one was omitted—unless all of them were. So we could use the %ADDR to identify whether the parameter was omitted because the address will be null if it was omitted.

 

Here is our new version of the prototype that uses both *NOPASS and *OMIT:

 

     D* Prototype for CPYIMPF procedure

     D exportFile...

     D                 PR             1N

     D   argFromFile                 10A   const

     D   argFromLib                  10A   const

     D                                     options(*NOPASS: *OMIT)

     D   argFromMbr                  10A   const

     D                                     options(*NOPASS: *OMIT)

     D   argToFile                  512A   const

     D                                     options(*NOPASS: *OMIT)

 

And here is our new exportFile procedure using the *OMIT keyword:

 

     P exportFile...

     P                 B                   EXPORT

     D exportFile...

     D                 PI             1N

     D   argFromFile                 10A   const

     D   argFromLib                  10A   const

     D                                     options(*NOPASS: *OMIT)

     D   argFromMbr                  10A   const

     D                                     options(*NOPASS: *OMIT)

     D   argToFile                  512A   const

     D                                     options(*NOPASS: *OMIT)

     D* Local Variables

     D   svReturn      S              1N

     D   svToFile      S            512A

     D   svCmdString   S           2000A

      /free

        svReturn = *OFF;

        //---------------------------------------------------------

        // Initialize the Defaults.

        //---------------------------------------------------------

        svToFile = %trim(argFromFile) + '.txt';

        if %parms > 3;

          if %addr(argToFile) <> *NULL;

            svToFile = %trim(argToFile);

          endif;

        endif;

        //-------------------------------------------------------------

        // CPYTOIMPF

        //-------------------------------------------------------------

        svCmdString = 'CPYTOIMPF FROMFILE(';

        // Library (Optional)

        if %parms > 1;

          if %addr(argFromLib) <> *NULL;

            svCmdString = %trim(svCmdString) + %trim(argFromLib) + '/';

          endif;

        endif;

        // File (Mandatory)

        svCmdString = %trim(svCmdString) + %trim(argFromFile);

        // Member (Optional)

        if %parms > 2;

          if %addr(argFromMbr) <> *NULL;

            svCmdString = %trim(svCmdString) + ' ' + %trim(argFromMbr);

          endif;

        endif;

        svCmdString = %trim(svCmdString) + ') '

               + 'TOSTMF(''' + %trim(svToFile) + ''') MBROPT(*REPLACE) '

               + 'STMFCCSID(*PCASCII) RCDDLM(*CRLF) DTAFMT(*FIXED)';

        monitor;

          ExecuteCommand(%trim(svCmdString):%len(%trim(svCmdString)));

        on-error;

          // Exception

          svReturn = *ON;

        endmon;

        return svReturn;

      /end-free

     P                 E

 

It's not necessary to use *NOPASS with *OMIT. We could just specify *OMIT, which would require us to always pass the parameter and specify the *OMIT keyword if we want it to be omitted. I use a combination of both here for the most flexibility.

 

The main procedure will test out the modified exportFile procedure with the *OMIT keyword specified on the arguments. All of the tests in the previous main procedure will work because we still have *NOPASS specified, but now we can select which parameters will be passed and which ones will not.

 

      /free

       // Specify: File and Output File Name

       if (exportFile('EMPHIST':*OMIT:*OMIT:

                      '/Public/EmployeeHistory1.txt'));

         dsply 'Error on Export!';

       endif;

       // Specify: File, Library and Output File Name

       if (exportFile('EMPHIST':'MYLIB':*OMIT:

                      '/Public/EmployeeHistory2.txt'));

         dsply 'Error on Export!';

       endif;

       // Specify: File, Member and Output File Name

       if (exportFile('EMPHIST':*OMIT:'EMPHIST':

                      '/Public/EmployeeHistory3.txt'));

         dsply 'Error on Export!';

       endif;

       // Specify: Everything

       if (exportFile('EMPHIST':'MYLIB':'EMPHIST':

                      '/Public/EmployeeHistory4.txt'));

         dsply 'Error on Export!';

       endif;

       // Specify: Everything but Output File Name (Using *OMIT)

       if (exportFile('EMPHIST':'MYLIB':'MCPRESS':*OMIT));

         dsply 'Error on Export!';

       endif;

       // Specify: Everything but Output File Name (Using *NOPASS)

       if (exportFile('EMPHIST':*OMIT:'MCPRESS'));

         dsply 'Error on Export!';

       endif;

       *inlr = *ON;

      /end-free

 

On review of this main procedure, you can see that you could selectively pass whichever values you want to use to override the default values, or you could not pass them at all.

CPYTOIMPF (STMFCODPAG Changed to STMFCCSID)

Notice that I am using the STMFCCSID parameter with the CPYTOIMPF command because I'm using V6R1. The V5R4 box used STMFCODPAG, which is still supported but is not listed when you prompt the command and is intended to be removed in a later release.

 

If you use this procedure to perform your exports, you only need to change the syntax in one procedure, and all of your programs using this functionality will be updated.

Using *OMIT on the Last Parameter

You don't need to specify *OMIT on the last parameter; you don't really need a placeholder here because there is nothing after it. But, when I'm building reusable procedures that I intend to use in the future, I like to code them in such a way that I have to do minimal thinking when using them. So, if I were to assume I could use *OMIT for all optional parameters, then my procedure will support it because my procedure is programmed to handle it. That way, if I were to pass in *OMIT in the last parameter, it will not see it as a valid file name and will behave as expected. And who knows, you may add additional parameters later on.

The Output

If you view the output using Qshell, you can see the files that were created. You can enter Qshell by typing STRQSH on the command line.

 

121510Snyder_fig01

Figure 1: Use Qshell to see the files created on the IFS. (Click images to enlarge.)

 

For the files that were exported without a specified name, the default name was assigned to match the name of the physical file with a .txt extension. All the rest were placed into the Public folder, as specified within the program.

Download the Code

You can download the code used in this article by clicking here.

 

121510Snyder_fig02

as/400, os/400, iseries, system i, i5/os, ibm i, power systems, 6.1, 7.1, V7,

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: