IBM DFSORT,11 3行,每行71、72或80个字符
OPTION COPY
OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X)
列式输出格式的两个答案经受了时间的考验。在某种程度上,这给了我一个“循环”,因为在OUTFIL REPEAT =上多次复制了当前记录。
另一种获取价值的方法似乎更长,但更短,因为我无法找出任何无条件的方法来处理第二年的第12条记录,并使其成为有条件的手段,包括IFTHEN=(WHEN=
,两次和其他一些东西。在回旋处获得收益(月初是最简单的方法),在回旋处损失严重(特殊语法要求)。
这使用一个内置函数(DFSORT中的所有函数都是内置函数)来查找每月的最后一天。然后添加一天(函数)到下个月的第一天,并使用PREVDSUN函数获得前一个星期日(与以前一样,它总是上个月的最后一个星期日)。
将年份(输入)转换为有效日期时,将使用两位数的序列号表示月份,并且也将复制该值的日期,因为起始点与有效期一样长,最初在该月的最后一天之后:5,2
比短C'01'
。
详细信息如下:
选项复制-将输入文件复制到输出
OUTFIL-允许具有不同选择和格式的多个输出文件生成格式化的报告。由于使用,优先于较短的优先INREC
使用REPEAT=
。
REPEAT = 12-每个记录产生12个副本。在此示例中,由于SEQNUM,只能有一个输入记录(与以前的版本不同)。
5:-从记录的第5列开始。
SEQNUM,2,ZD-序列号,默认以一位和两位数字开头,“带区号的十进制”(对于无符号,它们将与字符相同)。
1,8-将长度8的字节1复制到当前位置(9)。这是因为Y4T需要看到8,否则将使用其他日期格式。
Y4T-ccyymmdd格式的日期(由于紧靠其前面的8)。
LASTDAYM-月份的最后一天(也可以是星期,季度和年份)。
TOJUL =-输出日期函数的日期转换(TOJUL比TOGREG小1个字符)
9,7-现在是7长,Y4T将为CCYYDDD。
ADDDAYS-增加天数,如果进入下个月/年,则自动调整(也可以是ADDMONS和ADDYEARS)
PREVDSUN-朱利安日期到来,上一个星期日位于,TOGREG使用“-”分隔符获取正确的输出格式(可以是任何您喜欢的分隔符)
12倍-清除空白,使我们能够以如此短的方式进行处理
以上是2014年的输出:
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28
需要一些信息来告诉SORT该怎么做。没有默认值。OPTION COPY
是最短的,SORT FIELDS=COPY
等效但更长。
这次所做的工作本身OUTFIL
(允许使用REPEAT)。工作代码可以是160(2 * 80),144(2 * 72),140(72 + 69)或138(70 + 68)中的任何一个(不包括前导空格,强制连续空格和尾随空格)。
考虑到接收者必须知道他们在做什么,我想我可以说DFSORT代码列出了从1900年开始的任何一年的每个月的最后一个星期日(将从0001年开始,但是我避免这样做,因为可以)(最多9999)(尽管DFSORT支持高达9999的年份,但由于第12个日期进入下一年,所以以前的解决方案在9999年不起作用)。
如果有特别合适的内置函数,为什么代码那么长?
字段定义是短暂的。字段仅定义为数据(记录)中的特定位置,可以立即使用。换句话说,字段不是这样定义的,而是为每次使用而定义的,仅用于使用。日期函数需要知道使用哪种(许多)日期格式作为源,并且输出必须采用日期格式,因此必须指定日期格式。
现在我们有朱利安约会... TBC?
OPTION COPY
INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
(-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
(-),11:X,18,120,6X)
需要一些 JCL
//LASTSUNG EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
和一个输入文件(JCL的另一行和三个流内数据项):
//SORTIN DD *
2014
1900
2000
产生:
2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31
实际可以使用到9999年。
DFSORT是IBM的大型机排序产品。数据是可以操纵的,但是由于排序是关键,并且排序通常规模大且运行时间长,DFSORT控制卡没有循环结构,因此我们无法将SORT放入循环中。使诸如高尔夫之类的任务变得有些困难。
之所以发布答案,是因为DFSORT具有PREVDday
功能。因此,一个月内的最后一个星期日很容易。它是上个月的星期日(PREVDSUN)至下个月的第一天。
在一个“操作数”(覆盖)中执行该操作也很有趣,有点像在一个sprintf
或多个操作中进行。
这里是无高尔夫球的:
OPTION COPY
INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,
1,8,1,8,1,8,1,8,
1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,
14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
62:C'9',69:C'10',77:C'11',85:C'12',
127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
11:X,18,120,6X)
虽然不是很滥用,但尝试将所有这些都塞进一个OVERLAY并不常见,并且似乎需要一些不必要的东西才能将它们全部塞入一个OVERLAY。这里有打高尔夫球的空间,但是由于最多只能打掉一条线,所以我不会动心。
将为每条记录处理INREC。
OVERLAY允许更改现有记录的内容。如果记录在过程中超出其长度,则不存在问题。
1,4是即将到来的年份。它上面附加了一个字面0020,然后连续的1,8重复11次以得到96个字节的长卡盘,
扩展的当前记录的第12年添加了1,其月份设置为1(1月)。
剩余的10个月更改为3到11。
然后以相反的顺序(由于OVERLAY)出现了12种此类事物:
127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
n:是记录中的列号。X插入一个空格。89,8从该列/长度中获取数据,Y4T将其视为CCYYMMDD日期,PREVDSUM计算出前一个星期日,TOGREG = Y4T(-)将其输出为公历CCYY-MM-DD日期。
如果OVERLAY的特定部分的源和目标破坏性地重叠,则会使您感到垃圾,因此最终的11:X,18,120,6X)
重新排列和掩盖了一些混乱。
可以在以下位置找到手册和文件:http : //www-01.ibm.com/support/docview.wss?uid=isg3T7000080,其中包含900页以上的《 DFSORT应用程序编程指南》。
与所有IBM产品一样,所有手册都是免费提供的(极少量的非常昂贵的手册除外,全世界只有很少一部分人会假装理解)。
所有DFSORT控制卡都必须以空白开头。列72仅用于继续(任何非空白都可以,但是*是常规的)。列72后跟一个序列号区域,该序列号区域被忽略,使每个记录为80个字节。
也许还会有另外两种解决方案。