Showing posts with label cl. Show all posts
Showing posts with label cl. Show all posts

Wednesday, August 27, 2025

CVTDAT can use 1970 rule

This almost slipped past me, the information in the IBM i 7.6 documentation that says that the Convert Date command, CVTDAT can use the '1970 rule'.

Whether CVTDAT uses the '1940 rule' or the '1970 rule' depends upon the presence of the QIBM_QBASEYEAR Environment variable. If its value is '1970' that rule is used, if it is not present then the '1940 rule' is used.

How can I tell if I have that Environment variable? There are two ways. I can use the Work with Environment Variables command, WRKENVVAR:

01  WRKENVVAR

Wednesday, November 20, 2024

Using expression in CL call parameters

Starting in IBM i 7.4 it is possible to use CL Built in Functions, BiF, in the parameters of CL's Call command. This becomes even easier when I use the additional parameters in the Parameter parameters of the CALL command.

Those of you who have seen example of my RPG code have seen examples where I have used BiFs in its Call operation code parameters. When I learned that there was now similar functionality in CL I became very curious what could I do with it.

I chosen a number of scenarios to write examples for, as these are things I have done many times with RPG's Call operation code.

Wednesday, October 23, 2024

Retrieving the library that contains the currently running program

The idea for this post came from a question. The questioner had a situation where, due to a mixed-up library list, someone had run the wrong version of a program from another library. They already had the program's name on their display files, and they asked was it possible to retrieve the library the current executing program is in, and add that to the their display files.

After some discussion we decided that any change would be needed in both RPG and CL programs. Fortunately, this is simple in both languages.

Before I start explaining my RPG and CL code I need to have a display file within which are fields for the program and the program's library. I created a simple display file to do this, called TESTDSPF:

01 A                                      DSPSIZ(24 80 *DS3)
02 A          R SCREEN
03 A                                  3  2'Program name  . :'
04 A            PGMNAME       10   O  3 20
05 A                                  4  2'Program library :'
06 A            PGMLIB    R        O  4 20REFFLD(PGMNAME  *SRC)

Wednesday, September 25, 2024

Copy source members to the IFS

Someone asked me how I would write a program to copy all of the members in source files to separate files in the IFS, where they could then me imported into a GiT. I can see a program like this being more useful overtime as more people move from using source files to using a GiT repository.

In this example I will be copying all the source members from the source file DEVSRC in the library MYLIB to the IFS directory /home/MyFolder. The files in the IFS would all be named in the following way: source_member_name.source_member_type, for example: TESTRPG.RPGLE

My first attempt at creating a program to do this was to use RPG. I was going to use the CPYTOIMPF command within the QCMDEXC Scalar function. Alas, several hours of creating program I received the following message when running the RPG program for the first time:

Wednesday, June 26, 2024

Create an Excel spreadsheet from a CL program

It has been possible to create a Microsoft compatible Excel spreadsheet using SQL since the last Technology Refreshes. In my example I demonstrated how you could do this within a RPG program.

A few months have passed and I have been asked how to do the same within a CL program. With a minor change I will show it is possible.

Let me start by showing the code for this program:

Wednesday, December 27, 2023

Using QShell to search source members

The idea for this post comes from one I found upon the Seiden Group's website. I need to thank Alan Seiden for giving me permission to take the contents of his post and tweak it in a way I would use it.

The post gave an example of using QShell to grep, search files for a string of characters, to search source members in source files. As it is possible to use wild cards in a grep statement I can search many libraries and/or many different source files for the string I desire. For example if I want to search every RPG source file for the string "free". I would start QShell by using the following command:

  qsh

Wednesday, September 6, 2023

Reading from multiple members in a CL program

It has been a while since I wrote a post about CL. I have been given an opportunity to do so again when I received this question:

If my file has 5 members and I want to read only first record of each member in CL how can we do that ?

Yes, this is entirely possible using CL, with no help from RPG.

Before I start showing CL code I am going to need a file, which you will not be surprised I called TESTFILE, and it is in my library, MYLIB. The DDS code for this file is:

01  A          R TESTFILER
02  A            TEXT          45A

Wednesday, August 3, 2022

Copying multiple spool files into one PDF

The task came in: I needed to take many spool files from an output queue and convert them into just one PDF. I have written about converting individual spool files into PDF, but now there was the need for the to be only one PDF.

My solution would need to:

  1. Merge all of the spool files into one spool file
  2. Convert the one spool file into a PDF in the IFS

Both of these I have done separately on many occasions; this was the first time to do them together.

I cannot use the spool files I used for this task, but I have two spool files in my personal output queue:

Tuesday, June 21, 2022

Extra parameters added to Call command to prevent decimal data error

new parameters added to call command

Anyone who has programmed on IBM i has experienced this frustration. I want to call a CL program from a command line. I type:

CALL CL_PGM ('A' 12)

And I am presented with the following error:

MCH1202 received by procedure CL_PGM. (C D I R)

For the beginner this is cryptic. When I drill down into the job log I can see what really happened:

Thursday, October 21, 2021

Delaying a CL program by a fraction of a second with USLEEP

call usleep in a cl program

I have already written about how to delay a RPG program by less than a second by using the USLEEP procedure. Now I need to do the same in a CL program.

As we are in 2021 I hope that all of your CL source members are all the type CLLE. The program I am going to show must be compiled using the Create Bound CL program command, CRTBNDCL, not using the Create CL program command, CRTCLPGM, which is the default for type CLP.

USLEEP is a UNIX type API. This means that it is case sensitive. When I use it in a program I must use usleep, and not USLEEP or Usleep. I am just going to refer to it in the text of this post as USLEEP as it is easier for you to see its name amongst the rest of the text.

Wednesday, April 28, 2021

Handling variable length variables in CL

cl pogram coping with varchar data

More and more of us are using SQL to modernize our databases from DDS files to SQL tables, view, and indexes. When you rework your files into tables you quickly realize the benefit of converting that 50 alphanumeric field in the DDS file to a variable length character, VARCHAR, column in the SQL equivalent. This conversion saves disk space as the data in that column is only stored as the length it is, not the whole 50 characters.

RPG and SQL easily copes with this type of column. Alas, CL does not. If I try to declare file, DCLF, that contains variable length columns the program will not compile without using a special option in DCLF.

Before I start showing CL code I need to start with a SQL table, that contains a VARCHAR column:

Wednesday, January 27, 2021

For groups in CL

dofor allows for logic in cl program

This comes under the category of: I thought I had already written about this. The DOFOR command in CL allows me to construct a For group in CL, like I can in RPG when I use its FOR operation code. The same information has to be given to both:

RPG
===
for Count = 1 to 10 by 1 ;


CLLE
====
DOFOR VAR(&COUNT) FROM(1) TO(10) BY(1)
  1. What I call the count variable
  2. Starting value
  3. End value
  4. Increment value, this is optional as it is in RPG. If it is not given 1 is assumed

Wednesday, October 28, 2020

Getting the day of the week in a CL program using SQL

getting day of week in a cl program

The germ for this post came from a Facebook post I saw. The question was posed: Is it possible to retrieve the day of the week in a CL program? Multiple people suggested using a CEE API. Then came a reply that really interested me. This person said he had built a SQL View for this purpose.

It struck me as a creative approach to this scenario. SQL has a global variable CURRENT_DATE which contains, as the name suggests, the current date:

SELECT CURRENT_DATE
  FROM SYSIBM.SYSDUMMY1

00001
----------
2020-10-28

What kind of information would I want to know about today's date?

Wednesday, January 22, 2020

Copying source statements from IFS files into programs

copy and include source code from members and ifs files into another member

I am sure we are all familiar with using a copy compiler directive to copy source code from a "copy book" source member into another. As we can now edit and compile individual source files in the IFS, how can I insert code from those members into the source code of my source file members?

Below I am going to give examples in my three favorite IBM i programming languages:

I have three files in an IFS folder, MyFolder, that contain snippets of RPG, CL, and SQL that I want to copy into programs in a source file, DEVSRC, in my library, MYLIB. I also have code snippets in other source members I want to include too. How to do it?

Wednesday, August 28, 2019

Parms built in function added to CL

using bif parms to find number of parameters passed

With every new release I go through all the "What's new for this release" section of IBM's KnowledgeCenter. For IBM i 7.4 and the CL programming language there is only one addition this release: %PARMS built in function. It appears to be identical to the %PARMS built in function in RPG. It is the way to determine how many parameters have been passed to a program or procedure, and from that stop the program from erroring if too few parameters are passed.

In the past I wrote about coping with to few parameters being passed to a CL program, but the new BiF is a lot neater and easier for someone else to understand.

As I said above %PARMS is available in RPG:

Wednesday, August 21, 2019

Executing CL commands using RUNSQLSTM

adding cl commands to member used by runsqlstm

The Run SQL Statements command, RUNSQLSTM, runs all of the SQL statements that are in a particular source member. I use the command a lot as I put all of my SQL statements to create Tables, Views, Indexes, and the statements to Alter them into source members, and I update the member whenever I make a change to the object. I also put miscellaneous groups of SQL statements into source members, that I can then execute whenever I want.

I use RUNSQLSTM so much I have a PDM option defined so I don't have to type in the command and all the parameters I care about.

Opt  Command
 RS  RUNSQLSTM SRCFILE(&L/&F) SRCMBR(&N) COMMIT(*NONE) ERRLVL(20)

In the past if I ever wanted to run a CL command in one of these member I would use SQL's QCMDEXC procedure.

Wednesday, July 17, 2019

Easiest way to retrieve the program's name in a CL program

this is the easiest way to get the cl program name

It has always been a bit of a pain to get the name of the CL current program using the Receive Message command, RCVMSG. Therefore, I was excited when I received an example program showing a much simpler way of getting the same information by using a Machine Interface program.

The program I am going to show needs to be created as a CLLE member, and compiled using the Create Bound CL program , CRTBNDCL. As the call procedure command, CALLPRC, is not permitted in CLP source members.

My CLLE program will be calling the MI program _MATPGMNM, it is important to notice that the program name starts with an underscore ( _ ). I cannot use a CALL command, I must use the CALLPRC command instead.

My first example is the simplest program I could write to call this MI program, and have the current program name and library returned.

Wednesday, May 22, 2019

Using Check BiFs in CL

check and check bifs in cl

It has been several been several months since I last wrote a post about CL programming, therefore, I thought it would be a good excuse to share something I was using in a CL program I wrote a couple or so weeks ago. I am sure many have used the Check, %CHECK, and the Check reverse, %CHECKR build in functions, BiFs, in RPG to check a character string for the first place a certain character(s) is not. In the CL program I was writing I needed the same functionality.

IBM has been adding BiFs to CL that are similar to the ones to be found in RPG. Fortunately there are %CHECK and %CHECKR BiFs in CL too. The general format of them is similar to the RPG equivalent:

%CHECK(<test values> <variable> <starting position>)

%CHECKR(<test values> <variable> <starting position>)

I found I could use these BiFs in my CL in two ways:

Thursday, January 10, 2019

Re-enable disabled IFS user id

enable disabled netserver ifs user id or profile

When I am mapping an IFS folder to a Windows network drive I know that there are times where I will perform a typo on my password and the IBM i operating system will block me. This is where it gets interesting, I have disabled the user id I use trying to perform this connection, but I can still signon to the same IBM i.

When I create a user profile the command appears to create two:

  1. What I call the "IBM i" that I use to signon to a 5250 ("green screen") session.
  2. A NetServer user profile, that is used when I use the NetServer functions like mapping a Windows network drive to an IFS share.

Tuesday, January 8, 2019

Making copy a file to the IFS easier

automate copy of file to ifs

Often I find it easier to analyze the contents of a file using Microsoft's Excel than using the IBM i based tools. I take the file, or table, and copy it to my folder in the IFS, and then copy it from there to my PC. A colleague asked how did I do this so quickly, and having showed him how I do, he recommended that this would be a good subject for a post in this blog.

I am surprised how few developers I talk to build their own set of programs to automate tasks they perform every day. Too many times I see these people type in command names, prompt with F4, and fill in the same parameters time and again to do the same task. I admit I don't want to do that, if I need to perform the same task more than just a few times I will create a program containing all the commands I need. Then I can call the program with just a few parameters, and the program will do everything. If I want to copy a file to the IFS I just need the file and library, the rest will always be the same.