我需要得到上个月的最后一天。所以这个CL可以在新月的第3天运行。 我可以在CL中做一个Select语句(我们在7.1中)
或者如果不是,在小表中编码和保存此日期所需的步骤是什么。
答案 0 :(得分:1)
以下是使用CL计算上个月最后一天的简单示例。
PGM
DCL VAR(&CYMD) TYPE(*CHAR) LEN(7)
DCL VAR(&JUL) TYPE(*CHAR) LEN(5)
DCL VAR(&JUL#) TYPE(*DEC) LEN(5)
RTVJOBA CYMDDATE(&CYMD)
CHGVAR VAR(%SST(&CYMD 6 2)) VALUE('01')
CVTDAT DATE(&CYMD) TOVAR(&JUL) FROMFMT(*CYMD) TOFMT(*JUL) TOSEP(*NONE)
CHGVAR VAR(&JUL#) VALUE(&JUL)
CHGVAR VAR(&JUL#) VALUE(&JUL# - 1)
CHGVAR VAR(&JUL) VALUE(&JUL#)
CVTDAT DATE(&JUL) TOVAR(&CYMD) FROMFMT(*JUL) TOFMT(*CYMD) TOSEP(*NONE)
ENDPGM
答案 1 :(得分:0)
CL实际上并不支持日期数据类型。因此它不支持像SQL或RPGLE那样的日期算法。
如果您需要确保在本月3日运行作业,为什么不使用作业调度程序?基本作业调度程序包含在操作系统中,或者您可能具有高级作业调度程序(AJS)。
对于基本作业调度程序:
ADDJOBSCDE JOB(MTH3RDDAY) CMD(CALL PGM(MYPGM)) FRQ(*MONTHLY)
SCDDATE(110315) SCDTIME('08:00')
FRQ(*MONTHLY) SCDDATE(110315)
是每个月3日重复工作的关键。
如果你选择继续让CL确定它是否应该运行;我建议一个RPGLE程序只返回一个月中的某一天。这样返回值就是一个简单的整数,你的CL不必尝试解析日期的字符或数字表示。
如果您需要有关该计划的帮助,请发布一个新问题并将其标记为RPGLE。
答案 2 :(得分:0)
从技术上讲,可能在CL中进行SELECT;但它需要编写SQL CLI API才能执行此操作。不适合缺乏经验但不值得努力的人。但是,CL可以运行INSERT或UPDATE语句,然后使用RCVF来检索插入的值。调用用RPG,COBOL或C编写的模块来执行SQL要容易得多。如果这些语言似乎遥不可及,那么REXX可以轻松地执行SQL并将值传递给CL。
没有SQL,日期数学看起来最好。如果你想要"最后一天"通过CL的当月,它可能最容易设置为下个月的第1天并减去1天#39。以下显示使用一对CEE* Date and TIME APIs:
的示例pgm
dcl &fromDate1 *char 6
dcl &fromDate2 *char 8
dcl &resultDate *char 8
dcl &qyear *char 2
dcl &qmonth *char 2
dcl &rtnVal1 *int
dcl &rtnVal2 *int
dcl &picStr1 *char 6 value( 'YYMMDD' )
dcl &picStr2 *char 8 value( 'YYYYMMDD' )
rtvsysval sysval( QYEAR ) rtnvar( &qyear )
rtvsysval sysval( QMONTH ) rtnvar( &qmonth )
/* Set to a day near month-end... */
chgvar &fromDate1 ( &qyear *cat &qmonth *cat '28' )
callprc CEEDAYS ( +
&fromDate1 +
&picStr1 +
&rtnVal1 +
*omit +
)
/* Add enough days to guarantee in "next month"... */
chgvar &rtnVal2 ( &rtnVal1 + 4 )
callprc CEEDATE ( +
&rtnVal2 +
&picStr2 +
&fromDate2 +
*omit +
)
/* Set to 1st day of next month... */
chgvar %sst( &fromDate2 7 2 ) '01'
callprc CEEDAYS ( +
&fromDate2 +
&picStr2 +
&rtnVal1 +
*omit +
)
/* Subtract 1 day to get to "last day"... */
chgvar &rtnVal2 ( &rtnVal1 - 1 )
callprc CEEDATE ( +
&rtnVal2 +
&picStr2 +
&resultDate +
*omit +
)
/* Dump to show &resultDate is last-day of this month... */
dmpclpgm
return
endpgm
首先设定当月28日的日期,然后再增加4天。使用这些值可确保第一个计算日期始终位于"下个月"内。然后它将该日期设置为' 01'。从那以后,它减去了1天的时间。
这两个API使用称为" Lilian day"的表示。这只是1582年10月14日以来天数的整数值。日期可以转换为Lilian日数,然后简单的整数数学可以加或减,但需要很多天。生成的整数可以转换回Date值。
您可以指定一个'图片字符串'描述输入和输出日期的日期格式。我使用6-char格式作为初始输入,但使用8-char格式输出。您可以根据需要修改格式。最后,它只是运行DMPCLPGM来显示结果。您可以设置PARM()变量以将结果返回到任何调用它。
示例代码中的结果是针对当月的LastDay。稍微改变一下,可以很容易地简化为下个月的第3天。
我考虑过创建表达LAST_DAY()的SYSIBM.SYSDUMMY1的VIEW;但是当VIEW在SELECT语句中运行良好时,它在i 6.1中崩溃了RUNQRY。尝试使其适用于CL的RCVF似乎并不值得。
我还测试了添加一个在月末运行的虚拟作业调度程序条目。然后我使用适当的API从条目中检索NextSubmissionDate。这种方法运作得很好,但是太过晦涩难以成为一个好的解决方案。当然,如果整个目的是安排一个工作,那么简单地为它添加一个调度程序条目可能就是应该做的。检索NextSubmissionDate只是将LastDayOfMonth引入任何CL程序的一种方法。
但如果这是目的,那么只需要一个计算最后一天的CL模块就是最直接的方式。