I realized that using ASIS as an intermediate format without further precautions is not safe.
The data might contain control characters, which might get stripped out when the data is being written out to the intermediate file.
Then I realized that by contrast a human-readable date would be safe, and that the CARLa date input parser is fairly lenient.
So a better circumvention would be to write out the original query, which generates dates, albeit with leading blanks instead of leading zeroes.
And then read those back in, converting them into date values again, and writing them out again using DATE.
In other words, use the following DEFINE CONVERT:
Note that this uses the whole 10 characters as input, not just the first 8 positions, and that the test for missing is now on the second position, as the first one might be blank in a valid date.
IBM - Software Development and Level 3 Support Manager IBM Security zSecure Suite
Original Message:
Sent: Tue May 09, 2023 08:48 AM
From: Jeroen Tiggelman
Subject: Date Format on Summary Command
Hi again,
Although you cannot generally DEFINE in terms of another DEFINE, we also have a separate MAX modifier that you can use on the SUMMARY instead of using a variable defined via DEFINE MAX. As it turns out, this can also be used on a variable with a CONVERT.
So I think this query should do what you want:
n type=racf_access select raclist_merge=no class<>group proftype<>GLOBAL define count_suc(7,"Allowed",udec$abbr,bw,noprop) sum(access_count_suc) define lastuse(10,"LastUse",noprop) as CONVERT(access_lastuse,TOD,DATE) summary id class(nd) profile(nd) lastuse(key,"Last-Used" 10 MAX), access_intent_max_suc("Access-Used",12,max) access("Access-Allowed",14),count_suc(key,14) class(pas,key) profile(key,60),
I also tried to make this work with a two-pass approach as I described. It turned out you need to write the original field as ASIS and not as HEX.
You then get something clunky like this:
Pass 1
alloc type=output dd=interim dsn=CRMBINT.C2R2295.REPORT n type=racf_access dd=interim select raclist_merge=no class<>group proftype<>GLOBAL define count_suc(7,"Allowed",udec$abbr,bw,noprop) sum(access_count_suc) define lastuse(10,"LastUse",noprop) as access_lastuse summary id class(nd) profile(nd) lastuse(key,"Last-Used" 10 ASIS), access_intent_max_suc("Access-Used",12,max) access("Access-Allowed",14),count_suc(key,14) class(pas,key) profile(key,60),
Pass 2
deftype type=$ alloc type=$ dsn=CRMBINT.C2R2295.REPORT n type=$ name=TITLE nopage def test(8) as substring(record,74,8) def before(10) as substring(record,1,10) def at(10) as substring(record,11,10) def at_date(10) as convert(substring(record,11,8),tod,date), where substring(record,11,1)<>' ' def after(0) as substring(record,21) s test=' ' list record(0) n type=$ name=HEADER nopage s test='Profile 'c list before | at | after n type=$ name=DATA nopage x likelist=TITLE x likelist=HEADER list before | at_date | after
Where my REPORT file is VBA. If you use VB, you need most substring offsets one lower.
For the data lines, I am just copying the parts before and after the value we want to convert.
The conversion itself is probably clear. The WHERE clause is there to not generate dates from converted missing values.
The extra two newlists are there to not modify the title and column header lines but always just copy those..
I use LIST as opposed to SORTLIST so that the lines remain in the order in which they are read.
(LIST writes immediately when reading a line, whereas SORTLIST reads into memory, sorts, and then produces output--in the order of the newlist statements.)
I am sure the direct method makes a lot more sense, but thought I would include the "how to" on the circumvention idea anyway. ;-)
Edits: corrected some of the substring lengths.
Regards,
------------------------------
Jeroen Tiggelman
IBM - Software Development and Level 3 Support Manager IBM Security zSecure Suite
Delft
Original Message:
Sent: Tue May 09, 2023 02:42 AM
From: Jeroen Tiggelman
Subject: Date Format on Summary Command
Hi Linnea,
SUMMARY is a "LIST family command", so you should expect the output to be similar to LIST.
However, you base the LASTUSE defined variable on the ACCESS_LASTUSE field in TYPE=RACF_ACCESS.
The ACCESS_LASTUSE field in is a TOD field, and its output differs from the sample output shown for the DATE format.
You can see this with
n type=field s newlist_type=racf_access field=access_lastuse sortlist format B U I L T I N F I E L D S 8 May 2023 23:25 Format TOD
[Or with the FIELD primary command under ISPF you could navigate to the newlist type and field and see all the characteristics.]
I did not look for RACF_ACCESS input for my test this morning, so I built a sample of how to convert the date format with a different TOD field:
n type=racf s exists(certend) def ce_date as convert(certend,tod,date) summary ce_date(9)
So, you can convert the TOD field to a DATE field using the CONVERT function of the DEFINE command. After that, you would expect it to work like a DATE field.
Unfortunately, there are limitations to defining fields in terms of other defined fields. I believe it is currently not possible to take the MAX of a CONVERT result in a single pass.
I guess you could write out the results as you do now overriding the output format on the field to ASIS, and read the output back in as input using DEFTYPE, and CONVERTing TOD to DATE on this part of the data (while just echoing the other parts of the line).
If you don't like that approach, it might be time to request an enhancement.
Edit: Changed HEX to ASIS
------------------------------
Jeroen Tiggelman
IBM - Software Development and Level 3 Support Manager IBM Security zSecure Suite
Delft
Original Message:
Sent: Mon May 08, 2023 03:36 PM
From: Linnea Sullivan
Subject: Date Format on Summary Command
I opened a case TS012958771 and they could not find a resolution. Suggest I ask the question here.
Using NEWLIST TYPE RACF_ACCESS trying to the SUMMARY Command to print a date in the following format DDMMMYYYY. This works when the days are 2 digits, but not on days that are a single digit. I saw in the manuals a figure for the LIST command that showed the options for DATE output. It indicated a date with the length of 9 or 10 should produce the correct output. I tried this on the SUMMARY command and it does not see to work, and I do not see a similar chart for SUMMARY as I did for LIST.
In the example carla below (Created from AM.3) I am trying to get the field LASTUSE to print as a 2 digit day, Month, and year (ddmmmyyyy). But so far I can only get a one digit day on calendar days the 1st - 9th.
Suggestions?
n type=RACF_ACCESS name=CTBYPRFL nodetailinherit required
st="Permit and UACC usage, Access monitor records for any
/* Generated by CKRP3AM4 */
define count_suc(7,"Allowed",udec$abbr,bw,noprop)
sum(access_count_suc)
define count_vio(5,"Deny",udec$abbr,bw,noprop)
sum(access_count_vio)
define count_unk(5,"Unexp",udec$abbr,bw,noprop)
sum(access_count_unk)
define lastuse(10,"LastUse",noprop) max(access_lastuse)
define firstuse(9,"Firstuse",noprop) min(access_lastuse)
define prof#(5,"Prof",dec,bw,noprop) sumcount
define auth#(5,"Auth",dec,bw,noprop) count
define Miss#(7,"Missing",dec,noprop) count where
(proftype="missing"C)
define Pres#(8,"Permits",dec,noprop) count where
(proftype<>"missing"C)
define Perm#(8,"Permits and UACC",dec,noprop) count
select raclist_merge=no class<>group proftype<>GLOBAL
summary,
id,
class(nd),
profile(nd),
lastuse(key,"Last-Used",10),
access_intent_max_suc("Access-Used",12,max),
access("Access-Allowed",14),
count_suc(key,14),
class(pas,key),
profile(key,60),
------------------------------
Linnea Sullivan
------------------------------