Retrieve Last Spooled file ID with API QSPRILSP
擷取 Job 最後產生的報表資訊 API QSPRILSP
pgm
dcl &SplfNbr1 *int 4
dcl &SplfNbr2 *int 4
dcl &RcvVar *char 70
dcl &BytesAvail *int 4 stg(*defined) defvar(&RcvVar 1)
dcl &BytesRtn *int 4 stg(*defined) defvar(&RcvVar 5)
dcl &SplfName *char 10 stg(*defined) defvar(&RcvVar 9)
dcl &JobName *char 10 stg(*defined) defvar(&RcvVar 19)
dcl &UserName *char 10 stg(*defined) defvar(&RcvVar 29)
dcl &JobNbr *char 6 stg(*defined) defvar(&RcvVar 39)
dcl &SplfNbr *int 4 stg(*defined) defvar(&RcvVar 45)
dcl &SysName *char 8 stg(*defined) defvar(&RcvVar 49)
dcl &SplfCrtDat *char 7 stg(*defined) defvar(&RcvVar 57)
dcl &SplfCrtTim *char 6 stg(*defined) defvar(&RcvVar 65)
dcl &RcvVarLen *int 4 value(70)
dcl &FmtName *char 10
dcl &ErrorCode *char 8
dcl &Stat *lgl
dcl &SplfExists *lgl
callsubr subr(RtvSplfNbr) rtnval(&SplfNbr1)
call pgm1
callsubr subr(RtvSplfNbr) rtnval(&SplfNbr2)
/* If pgm1 created a report, continue with other tasks. */
if (&SplfNbr2 *ne &SplfNbr1) do
call pgm2
call pgm3
call pgm4
enddo
return
subr subr(RtvSplfNbr)
chgvar &BytesAvail 70
chgvar &FmtName 'SPRL0100'
chgvar &ErrorCode x'0000000000000000'
chgvar &SplfExists '1'
call QSPRILSP (&RcvVar &RcvVarLen &FmtName &ErrorCode)
monmsg cpf333a exec(chgvar &SplfExists '0')
if (&SplfExists) then
else do
chgvar &SplfNbr 0
enddo
endsubr rtnval(&SplfNbr)
endpgm
Copy from https://www.itjungle.com/2006/02/08/fhg020806-story01/
A blog about IBM i (AS/400), MQ and other things developers or Admins need to know.
星期一, 11月 13, 2023
2023-11-13 Retrieve Current job last spooled file ID with API QSPRILSP
星期四, 11月 09, 2023
2014-05-12 如何於 java 環境中透過 QTEMP library 取得執行指令所輸出的報表內容?(AS400CommandOutput.java)
2014-05-12 如何於 java 環境中透過 QTEMP library 取得執行指令所輸出的報表內容?
AS400CommandOutput.java -- AS400 command output spooled file to TEXT file within QTEMP
Many CLP to get command spooled output to QTEMP outfile in CLP, but when the CLP call by Java command server,
could not get the QTEMP file.
The AS400CommandOutput will run your command output to spooled and use CPYSPLF command to copy spooled to
QTEMP outfile and read all record to TEXT file within QTEMP use AS400File.runCommand() method.
AS400CommandOutput.java
package com.free400.vengoal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Exception;
import com.ibm.as400.access.AS400File;
import com.ibm.as400.access.AS400FileRecordDescription;
import com.ibm.as400.access.AS400Message;
import com.ibm.as400.access.CommandCall;
import com.ibm.as400.access.Job;
import com.ibm.as400.access.QSYSObjectPathName;
import com.ibm.as400.access.Record;
import com.ibm.as400.access.RecordFormat;
import com.ibm.as400.access.SequentialFile;
import com.ibm.as400.access.SpooledFile;
import com.ibm.as400.access.SpooledFileList;
public class AS400CommandOutput {
private static final String FILE_SEPARATOR_PROP = "file.separator";
public static java.text.SimpleDateFormat datetimeFmt = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private AS400 as400;
private CommandCall commandCall;
private SequentialFile seqfile;
private String lastSplfName=null, lastSplfJob=null, lastSplfUsr=null, lastSplfJobNbr=null;
private int lastSplfNbr=0;
private String file;
private String commandJobNbr;
private String ddmJobNbr;
private File toFile = null;
private PrintWriter writer_;
private FileOutputStream os;
private boolean fileOpened = false;
public AS400CommandOutput(AS400 as400){
this.as400 = as400;
this.commandCall = new CommandCall(this.as400);
}
public AS400CommandOutput(AS400 as400, File toFile){
this.as400 = as400;
this.toFile = toFile;
this.commandCall = new CommandCall(this.as400);
}
public AS400 getSystem(){
return as400;
}
public String getCommandJobNbr(){
String cmdJobNbr = null;
try {
as400.connectService(AS400.COMMAND);
Job[] as400Jobs = as400.getJobs(AS400.COMMAND);
for(int i=0; i < as400Jobs.length; i++){
cmdJobNbr = as400Jobs[i].getNumber();
System.out.println("Linking to AS400 job: " + as400Jobs[i].getNumber() + "/" + as400Jobs[i].getUser() + "/" + as400Jobs[i].getName());
}
} catch (Exception e) {
e.printStackTrace();
}
return cmdJobNbr;
}
public String getDDMJobNbr(){
String ddmJobNbr = null;
try {
as400.connectService(AS400.RECORDACCESS);
Job[] as400Jobs = as400.getJobs(AS400.RECORDACCESS);
for(int i=0; i < as400Jobs.length; i++){
ddmJobNbr = as400Jobs[i].getNumber();
System.out.println("Linking to AS400 job: " + as400Jobs[i].getNumber() + "/" + as400Jobs[i].getUser() + "/" + as400Jobs[i].getName());
}
} catch (Exception e) {
e.printStackTrace();
}
return ddmJobNbr;
}
public void getLastSplfInfo(String selectSplfName, boolean deleteSplf) throws Exception{
String splfName, splfJob, splfUsr, splfJobNbr, splfDate,splfTime;
int splfNbr;
String lastSplfDateTime=" ";
String splfDateTime;
SpooledFileList splfList = new SpooledFileList( as400 );
// set filters, all users, on all queues
splfList.setUserFilter(as400.getUserId());
splfList.setQueueFilter("/QSYS.LIB/%ALL%.LIB/%ALL%.OUTQ");
// open list, openSynchronously() returns when the list is completed.
splfList.openSynchronously();
Enumeration enumer = splfList.getObjects();
while( enumer.hasMoreElements() )
{
SpooledFile splf = (SpooledFile)enumer.nextElement();
if ( splf != null )
{
// output this spooled file's name
splfName = splf.getStringAttribute(SpooledFile.ATTR_SPOOLFILE);
splfJob = splf.getStringAttribute(SpooledFile.ATTR_JOBNAME);
splfUsr = splf.getStringAttribute(SpooledFile.ATTR_JOBUSER);
splfJobNbr = splf.getStringAttribute(SpooledFile.ATTR_JOBNUMBER);
splfDate = splf.getStringAttribute(SpooledFile.ATTR_DATE);
splfTime = splf.getStringAttribute(SpooledFile.ATTR_TIME);
splfNbr = splf.getIntegerAttribute(SpooledFile.ATTR_SPLFNUM);
splfDateTime = splfDate + splfTime;
//System.out.println("splfDate:" + splfDate + " splfTime:" + splfTime + " job:" + splfJobNbr + "/"+ splfUsr + "/" + splfJob + " spooled file = " + splfName + " splfNbr=" + splfNbr);
if(splfName.equalsIgnoreCase(selectSplfName) && splfJob.equalsIgnoreCase("QPRTJOB")){
if (deleteSplf){
splf.delete();
} else if (splfDateTime.compareTo(lastSplfDateTime) > 0){
lastSplfDateTime = splfDateTime;
lastSplfName = splfName;
lastSplfJob = splfJob;
lastSplfUsr = splfUsr;
lastSplfJobNbr=splfJobNbr;
lastSplfNbr = splfNbr;
}
}
}
//System.out.println("last SPLFInfo: job " + lastSplfJobNbr + "/"+ lastSplfUsr + "/" + lastSplfJob + " lastSplfName:" + lastSplfName + " lastSplfNbr:" + lastSplfNbr);
}
// clean up after we are done with the list
splfList.close();
}
public void cpysplfWithQtemp(String splfName, boolean deleteTempFile) throws Exception{
if(seqfile == null){
seqfile = new SequentialFile();
seqfile.setSystem(as400);
seqfile.setPath("/QSYS.LIB/QGPL.LIB/QDDSSRC.FILE"); // for run following command use;
}
if(ddmJobNbr == null)
ddmJobNbr = getDDMJobNbr();
file = splfName.substring(0, 4) + ddmJobNbr;
getLastSplfInfo(splfName, false);
CPYSPLF(seqfile, lastSplfName, lastSplfJob, lastSplfUsr, lastSplfJobNbr, lastSplfNbr, true, "QTEMP", file, "M000000000", 201);
seqfile.setPath(new QSYSObjectPathName("QTEMP", file, "M000000000", "MBR").getPath());
setRecordFormat();
if(toFile == null)
readAll();
else
readAll(toFile);
getLastSplfInfo(splfName, true);
}
public void readAll(){
readAll(null);
}
public void readAll(File toFile){
try {
seqfile.open(AS400File.READ_ONLY, 100, AS400File.COMMIT_LOCK_LEVEL_NONE);
Record dataRcd = seqfile.readNext();
while (dataRcd != null) {
if(toFile == null)
onRecord(dataRcd);
else
onRecord(toFile, dataRcd);
dataRcd = seqfile.readNext();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
seqfile.close();
if(fileOpened){
writer_.close();
os.close();
fileOpened = false;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void onRecord(Record record) {
System.out.println(getClass() + ":" + record);
}
public void onRecord(File file, Record record) throws IOException{
if(!fileOpened){
os = new FileOutputStream(file, file.exists());
writer_ = new PrintWriter(os, true);
fileOpened = true;
}
writer_.println(record);
writer_.flush();
}
public void setRecordFormat() throws Exception{
AS400FileRecordDescription recordDescription = new AS400FileRecordDescription(as400, seqfile.getPath());
RecordFormat[] formats = recordDescription.retrieveRecordFormat();
RecordFormat recordFormat = formats[0];
seqfile.setRecordFormat(recordFormat);
}
public void CPYSPLF(SequentialFile seqFile, String splfName, String splfJob, String splfUsr, String splfJobNbr, int splfNbr , boolean includeIGCData, String toLibrary, String toFile, String toMbr, int toFileRecordLength){
String cmdCRTPF = "CRTPF FILE("
+ toLibrary.toUpperCase().trim()
+ "/"
+ toFile.toUpperCase().trim()
+ ") RCDLEN("
+ toFileRecordLength
+ ") MBR("
+ toMbr.toUpperCase().trim()
+ ") MAXMBRS(*NOMAX) SIZE(*NOMAX)";
String cmdCPYSPLF = "CPYSPLF FILE("
+ splfName
+ ") TOFILE("
+ toLibrary.toUpperCase().trim()
+ "/"
+ toFile.toUpperCase().trim()
+ ") JOB("
+ splfJobNbr
+ "/"
+ splfUsr
+ "/"
+ splfJob
+ ") SPLNBR("
+ splfNbr
+ ") MBROPT(*REPLACE)";
try {
if(!chkObjExist(seqFile, toLibrary, toFile, "*FILE"))
seqFile.runCommand(cmdCRTPF);
AS400Message[] messagelist = seqFile.runCommand(cmdCPYSPLF);
for (int i = 0; i < messagelist.length; i++) {
if (messagelist[i].getID() != null){
if(messagelist[i].getID().equalsIgnoreCase("CPF3485")){
System.out.println(cmdCPYSPLF +" Command successful");
} else
System.out.println(messagelist[i].getID() + " " + messagelist[i].getText());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean chkObjExist(SequentialFile seqFile, String objLib, String objName, String objType) throws Exception {
boolean objectExist = true;
String cmdChkObj;
cmdChkObj = "CHKOBJ OBJ(" + objLib + "/" + objName + ") OBJTYPE(" + objType + ")";
AS400Message[] messagelist = seqFile.runCommand(cmdChkObj);
for (int i = 0; i < messagelist.length; i++) {
if (messagelist[i].getID() != null){
System.out.println(messagelist[i].getID() + " " + messagelist[i].getText());
if (messagelist[i].getID().equalsIgnoreCase("CPF9801")){
objectExist = false;
}
}
}
return objectExist;
}
public boolean runCmd(String commandString) {
boolean success = false;
try {
// Run the command.
if (success = commandCall.run(commandString)){
//System.out.println(commandString + " Command successful");
}else{
System.out.println(commandString + " Command failed");
throw new AS400Exception(commandCall.getMessageList());
}
} catch (Exception e) {
System.out.println("Command " + commandCall.getCommand() + " did not run");
e.printStackTrace();
}
return success;
}
public static void main(String[] args) {
try {
AS400 as400 = new AS400("as400ip", "user", "userpass");
AS400CommandOutput get400ACTJOB = new AS400CommandOutput(as400, new File("d:\\temp\\WRKACTJOB.TXT"));
get400ACTJOB.runCmd("WRKACTJOB OUTPUT(*PRINT) RESET(*YES) SEQ(*CPUPCT)");
Thread.sleep(5000);
get400ACTJOB.runCmd("WRKACTJOB OUTPUT(*PRINT) SEQ(*CPUPCT)");
get400ACTJOB.cpysplfWithQtemp("QPDSPAJB", true);
get400ACTJOB.runCmd("WRKSYSSTS OUTPUT(*PRINT)");
get400ACTJOB.cpysplfWithQtemp("QPDSPSTS", true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
2013-07-03 如何將 outq 中所有報表搬移至另一個 outq ?(Command MOVOUTQ with List Spooled Files (QUSLSPL) API)
如何將 outq 中所有報表搬移至另一個 outq ?(Command MOVOUTQ with List Spooled Files (QUSLSPL) API)
File : QCLSRC
Member: MOVOUTQ
Type : CLP
Usage : CRTCLPGM MOVOUTQ TGTRLS(V5R4M0)
OS : V5R4 later
/* =============================================================== */
/* = Command MovOutQ CPP = */
/* = MovOutQ CLP = */
/* = Paramater notes: = */
/* = FromOutq: from outq = */
/* = ToOutq : to outq = */
/* = = */
/* = Only spooled file status RDY, SAV, HLD selected to move = */
/* =============================================================== */
/* = Date : 2013/07/02 = */
/* = Author: Vengoal Chang = */
/* =============================================================== */
Pgm (&qfromoutq &qtooutq)
Dcl &qfromoutq *CHAR 20
Dcl &qtooutq *CHAR 20
Dcl &FROMLIB *CHAR 10
Dcl &FROMOUTQ *CHAR 10
Dcl &FROMQUAL *CHAR 20
Dcl &TOLIB *CHAR 10
Dcl &TOOUTQ *CHAR 10
Dcl &PDATA *PTR
Dcl &PGENERIC *PTR
Dcl &PUSRSPC *PTR
Dcl &SFJNAME *CHAR 10
Dcl &SFJUSER *CHAR 10
Dcl &SFJNBR *CHAR 6
Dcl &SFNAME *CHAR 10
Dcl &SFNBR *CHAR 4
Dcl &SFSTS *UINT 4
Dcl &USGENERIC *CHAR STG(*BASED) +
LEN(256) BASPTR(&PGENERIC)
Dcl &USDTAOFF *UINT 4
Dcl &USDTACNT *UINT 4
Dcl &USDTASIZ *UINT 4
Dcl &USDTAENT *CHAR STG(*BASED) +
LEN(256) BASPTR(&PDATA)
Dcl &CH4 *CHAR 4
Dcl &CH4A *CHAR 4
Dcl &CH4B *CHAR 4
Dcl &OFFSET *UINT 4
Dcl &OFFSET2 *UINT 4
Dcl &USRSPC *CHAR 20
Dcl &USRSPCL *CHAR 10 'QTEMP '
Dcl &USRSPCS *CHAR 10
Dcl &X *UINT 4 0
MonMsg CPF0000 *N GoTo Error
/* First ensure that variables are extracted correctly */
ChgVar &FromOutQ %SST(&qfromoutq 1 10)
ChgVar &FromLib %SST(&qfromoutq 11 10)
ChgVar &ToOutQ %SST(&qtooutq 1 10)
ChgVar &ToLib %SST(&qtooutq 11 10)
/* Resolve special values */
If (&ToOutQ *EQ '*FROMOUTQ') +
ChgVar &ToOutQ &FromOutQ
RtvObjD Obj(&FromLib/&FromOutQ) ObjType(*OUTQ) +
RtnLib(&FromLib)
RtvObjD Obj(&ToLib/&ToOutQ) ObjType(*OUTQ) +
RtnLib(&ToLib)
/* If both from and to are the same then issue an error */
If ((&FromLib *EQ &ToLib) *AND +
(&FRomOutQ *EQ &ToOutQ)) DO
SndPgmMsg MsgID(CPF9898) MsgF(QCPFMSG) +
MsgDta('FromOutQ could not same as +
ToOutQ') MsgType(*ESCAPE)
Return
EndDO
SndPgmMsg MsgID(CPF9898) MsgF(QCPFMSG) +
MsgDta('Retrieving output queue entries') +
ToPgmQ(*EXT) MsgType(*STATUS)
ChgVar &USRSPCS 'MOVOUTQSPC'
ChgVar &USRSPC (&USRSPCS *CAT &USRSPCL)
ChgVar &FROMQUAL (&FROMOUTQ *CAT &FROMLIB)
DltUsrSpc UsrSpc(&USRSPCL/&USRSPCS)
MonMsg CPF0000
Call QUSCRTUS (&USRSPC 'MOVOUTQ ' +
X'00000100' x'00' '*ALL ' 'User space +
for MOVOUTQ ')
Call QUSLSPL (&USRSPC 'SPLF0300' +
'*ALL ' &FROMQUAL '*ALL ' +
'*ALL ')
/* Get header information pointer */
Call QUSPTRUS (&USRSPC &PUSRSPC)
/* Generic Header is at offset x'6C'-decimal 108 */
ChgVar &PGENERIC &PUSRSPC
ChgVar &OFFSET %OFFSET(&PGENERIC)
ChgVar &OFFSET2 (&OFFSET + 108)
ChgVar %OFFSET(&PGENERIC) &OFFSET2
/* Get user data offset */
ChgVar &CH4 %SST(&USGENERIC 17 4)
ChgVar &USDTAOFF %BIN(&CH4)
/* Get user data size */
ChgVar &CH4 %SST(&USGENERIC 29 4)
ChgVar &USDTASIZ %BIN(&CH4)
/* Get number of entries for status message */
ChgVar &CH4 %SST(&USGENERIC 25 4)
ChgVar &USDTACNT %BIN(&CH4)
/* If no entries, then bypass processing */
If (&USDTACNT *EQ 0) +
Goto END
/* link to first data entry */
ChgVar &PDATA &PUSRSPC
ChgVar &OFFSET %OFFSET(&PDATA)
ChgVar &OFFSET2 (&OFFSET + &USDTAOFF)
ChgVar %OFFSET(&PDATA) &OFFSET2
ChgVar &X 1
ChgVar %BIN(&CH4A) &X
ChgVar %BIN(&CH4B) &USDTACNT
/* Process the list of entries on the usrspc */
LOOP:
ChgVar &SFJNAME %SST(&USDTAENT 1 10)
ChgVar &SFJUSER %SST(&USDTAENT 11 10)
ChgVar &SFJNBR %SST(&USDTAENT 21 6)
ChgVar &SFNAME %SST(&USDTAENT 27 10)
ChgVar &CH4 %SST(&USDTAENT 37 4)
ChgVar &SFNBR %BIN(&CH4)
ChgVar &CH4 %SST(&USDTAENT 41 4)
ChgVar &SFSTS %BIN(&CH4)
If (&SFSTS *EQ 1 *OR +
&SFSTS *EQ 4 *OR +
&SFSTS *EQ 6 ) Do
ChgSplFa File(&SFNAME) +
Job(&SFJNBR/&SFJUSER/&SFJNAME) +
SplNbr(&SFNBR) OutQ(&TOLIB/&TOOUTQ)
EndDo
Else Do
SndPgmMsg MsgID(CPF9898) MsgF(QCPFMSG) +
MsgDta('Spooled file' *BCAT +
&SFNAME *Bcat 'in job' *BCAT +
&SFJNBR *CAT '/' *CAT +
&SFJUSER *TCAT '/' *CAT +
&SFJNAME *BCAT 'in' *BCAT +
&FROMLIB *TCAT '/' *CAT +
&FROMOUTQ *BCAT +
'is not moved.') +
ToPgmQ(*EXT) MsgType(*STATUS)
EndDo
IF (&X *LT &USDTACNT) DO
ChgVar &OFFSET %OFFSET(&PDATA)
ChgVar &OFFSET2 (&OFFSET + &USDTASIZ)
ChgVar %OFFSET(&PDATA) &OFFSET2
ChgVar &X (&X + 1)
ChgVar %BIN(&CH4A) &X
Goto LOOP
EndDo
END:
DltUsrSpc UsrSpc(&USRSPCL/&USRSPCS)
Return:
Return
/*-- Error handling: -----------------------------------------------*/
Error:
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
EndPgm:
EndPgm
File : QCMDSRC
Member: MOVOUTQ
Type : CMD
Usage : CRTCMD CMD(MOVOUTQ) PGM(MOVOUTQ)
/* =============================================================== */
/* = Command....... MovOutQ = */
/* = CPP........... MovOutQ CLP = */
/* = Description... Move output queue spooled files to another = */
/* = output queue = */
/* = = */
/* = CrtCmd Cmd( MovOutQ ) = */
/* = Pgm( MovOutQ ) = */
/* = SrcFile( YourSourceFile ) = */
/* =============================================================== */
/* = Date : 2013/07/02 = */
/* = Author: Vengoal Chang = */
/* =============================================================== */
CMD PROMPT('Move Output Queue')
PARM KWD(FROMOUTQ) TYPE(FROM) PROMPT('From output +
queue')
PARM KWD(TOOUTQ) TYPE(TO) PROMPT('To output queue')
FROM: QUAL TYPE(*NAME) LEN(10) MIN(1)
QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) +
SPCVAL((*LIBL)) PROMPT('Library')
TO: QUAL TYPE(*NAME) LEN(10) DFT(*FROMOUTQ) +
SPCVAL((*FROMOUTQ))
QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) +
SPCVAL((*LIBL)) PROMPT('Library')
參考資訊:
List Spooled Files (QUSLSPL) API
星期三, 11月 08, 2023
2012-01-04 使用 QSPRILSP API 取得 current job 的最後一份報表的 ID 資訊(Command RTVLSTSPLI)
使用 QSPRILSP API 取得 current job 的最後一份報表的 ID 資訊(Command RTVLSTSPLI)
從 V5R2 後系統提供新 API QSPRILSP 來取得 current job 的最後一份報表的 ID 資訊。
File : QCLSRC
Member: RTVLSTSPLI
Type : CLP
Usage : CRTCLPGM yourlib/RTVLSTSPLI
OS : V5R2
/*-------------------------------------------------------------------*/
/* Program . . : RTVLSTSPLI */
/* Description : Retrieve Last Spooled Id under current job */
/* Author . . : Vengoal Chang */
/* Published . : AS400ePaper */
/* Date . . . : January 4, 2012 */
/* */
/* Program function: Retrieve Last Spooled Id under current job */
/* */
/* */
/* Compile options: */
/* CrtClPgm Pgm( RTVLSTSPLI ) */
/* SrcFile( QCLSRC ) */
/* SrcMbr( *PGM ) */
/* */
/*-------------------------------------------------------------------*/
/* In V5R2 new API */
/* RETRIEVE IDENTITY OF LAST SPOOLED FILE CREATED (QSPRILSP) API */
/*-------------------------------------------------------------------*/
Pgm ( &Splf +
&Job +
&User +
&Nbr +
&SplfNbrC +
)
Dcl &RcvVar *Char 70
Dcl &RcvVarLen *Char 4
Dcl &ApiErrCode *Char 8
/* FIELDS FROM FORMAT SPRL0100 */
Dcl &BytesRtn *Dec (10 0)
Dcl &BytesAvl *Dec (10 0)
Dcl &Splf *Char 10
Dcl &Job *Char 10
Dcl &User *Char 10
Dcl &Nbr *Char 6
Dcl &SplfNbr *Dec (6 0)
Dcl &SplfNbrC *Char 6
Dcl &SystemName *Char 8
Dcl &CreateDate *Char 7
Dcl &CreateTime *Char 6
/*-- Global error monitoring: --------------------------------------*/
MonMsg CPF0000 *N GoTo Error
ChgVar (%bin(&ApiErrCode 1 4)) 0
ChgVar (%bin(&RcvVarLen 1 4)) 70
Call QSPRILSP ( &RcvVar +
&RcvVarLen +
'SPRL0100' +
&ApiErrCode )
ChgVar &BytesRtn %bin(&RcvVar 1 4)
ChgVar &BytesAvl %bin(&RcvVar 5 4)
ChgVar &Splf %sst(&RcvVar 9 10)
ChgVar &Job %sst(&RcvVar 19 10)
MonMsg Mch3601
ChgVar &User %sst(&RcvVar 29 10)
MonMsg Mch3601
ChgVar &Nbr %sst(&RcvVar 39 6)
MonMsg Mch3601
ChgVar &SplfNbr %bin(&RcvVar 45 4)
ChgVar &SplfNbrC &SplfNbr
ChgVar &SystemName %sst(&RcvVar 49 8)
ChgVar &CreateDate %sst(&RcvVar 57 7)
ChgVar &CreateTime %sst(&RcvVar 65 6)
Return:
Return
/*-- Error handling: -----------------------------------------------*/
Error:
Call QMHMOVPM ( ' ' +
'*DIAG' +
x'00000001' +
'*PGMBDY' +
x'00000001' +
x'0000000800000000' +
)
Call QMHRSNEM ( ' ' +
x'0000000800000000' +
)
EndPgm:
EndPgm
File : QCMDSRC
Member: RTVLSTSPLI
Type : CMD
Usage : CRTCMD Cmd(yourlib/RTVLSTSPLI) Pgm(RTVLSTSPLI) Allow( *Ipgm *Bpgm )
OS : V5R2
/* =============================================================== */
/* = Command....... RtvLstSplI = */
/* = CPP........... RtvLstSplI = */
/* = Description... Retrieve Last Spooled Id under current job = */
/* = = */
/* = = */
/* = CrtCmd Cmd( RtvLstSplI ) = */
/* = Pgm( RtvLstSplI ) = */
/* = SrcFile( YourSourceFile ) = */
/* = Allow( *Ipgm *Bpgm ) = */
/* =============================================================== */
/* = Date : 2012/01/04 = */
/* = Author: Vengoal Chang = */
/* =============================================================== */
CMD PROMPT('Retrieve Last Spooled File Id')
PARM KWD(SPLF ) TYPE(*CHAR) LEN(10) +
RTNVAL(*YES) MIN(1) +
PROMPT('CL var for SPLF (10)')
PARM KWD(JOB ) TYPE(*CHAR) LEN(10) +
RTNVAL(*YES) +
PROMPT('CL var for JOB (10)')
PARM KWD(USER ) TYPE(*CHAR) LEN(10) +
RTNVAL(*YES) +
PROMPT('CL var for USER (10)')
PARM KWD(NBR ) TYPE(*CHAR) LEN( 6) +
RTNVAL(*YES) +
PROMPT('CL var for NBR (6)')
PARM KWD(SPLNBR ) TYPE(*CHAR) LEN( 6) +
RTNVAL(*YES) MIN(1) +
PROMPT('CL var for SPLNBR (6)')
File : QCLSRC
Member: RTVLSTSPLT
Type : CMD
Usage : CRTCLPGM pgm(yourlib/RTVLSTSPLT)
CALL RTVLSTSPLT
PGM
Dcl &Splf *Char 10
Dcl &Job *Char 10
Dcl &User *Char 10
Dcl &Nbr *Char 6
Dcl &SplNbrC *Char 6
RTVLSTSPLI SPLF(&SPLF) JOB(&JOB) USER(&USER) NBR(&NBR) +
SPLNBR(&SPLNBRC)
MONMSG CPF333A /* No spooled file created under the current job */
DMPCLPGM
DSPSPLF FILE(QPPGMDMP) SPLNBR(*LAST)
ENDPGM
詳細資訊參照:Retrieve Identity of Last Spooled File Created (QSPRILSP) API
2011-08-18 如何取得使用者於系統中有幾份報表存在 ?(Retrieve Spool Information QSPSPLI API )
如何取得使用者於系統中有幾份報表存在 ?(Retrieve Spool Information QSPSPLI API )
File : QRPGLESRC
Member: RTVSPLINFO
Type : RPGLE
Usage : CRTBNDRPG RTVSPLINFO
OS : V6R1
* From V6R1 new Retrieve Spool Information (QSPSPLI) API
* http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/apis/qspspli.htm
*
* PTF SI44375 for 6.1 and SI44376 for 7.1
* Supersedes
* PTF SI33959 for 6.1 and SI34013 for 7.1
H DEBUG OPTION(*SRCSTMT:*NODEBUGIO) DFTACTGRP(*NO) ACTGRP(*CALLER)
DRtvSplInfo pr extpgm('QSPSPLI')
D RcvVar 65535 options(*varsize)
D RcvVarLen 10I 0 const
D Format 8 const
D ASP 10 const
D UsrName 10 const
D ErrCde likeds(ErrorCode)
D SPLI0100 ds
D bytesRtn 10I 0
D bytesAvl 10I 0
D nbrOfSplFile 10I 0
D aspGrpName 10A
D userName 10A
D ErrorCode ds
D BytesProv 10I 0 inz(%Size(ErrorCode))
D BytesAvail 10I 0 inz(0)
D ExpMsgId 7
D Reserved 1
D ExptionData 256
/free
RtvSplInfo(SPLI0100 :
%size(SPLI0100) :
'SPLI0100' :
'*SYSBAS' :
'*CURRENT' :
ErrorCode);
dsply ('For ' + %trimr(aspGrpName) + ':');
dsply (%trimr(userName) + ' has ' +
%char(nbrOfSplFile) + ' spool files');
RtvSplInfo(SPLI0100 :
%size(SPLI0100) :
'SPLI0100' :
'*SYSBAS' :
'*ALL' :
ErrorCode);
dsply ('All users have ' + %char(nbrOfSplFile) +
' spool files');
*inlr = *on;
return;
/end-free
Retrieve Spool Information (QSPSPLI) API
2007-11-05 如何將報表轉為 Text 或 Html 格式 ? (Command:CVTSPLSTMF)
如何將報表轉為 Text 或 Html 格式 ? (Command:CVTSPLSTMF)
此指令是將報表轉換為 Text 或 Html 格式,並可以轉換中文而且可將報表對齊,不過報表
中文控制碼(0E0F)要前後配對完整才可以,並將之存放在 IFS 目錄中,所以使用前須先建立
一個目錄,例如使用指令 MD '/spool' 建立一 spool 的目錄,使用 WRKLNK '/spool' ,並
選用 5 ,即可檢視該目錄內容:
===============================================================================
Work with Object Links
Directory . . . . : /
Type options, press Enter.
2=Edit 3=Copy 4=Remove 5=Display 7=Rename 8=Display attributes
11=Change current directory ...
Opt Object link
5 spool
Bottom
Parameters or command
===>
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel F17=Position to
F22=Display entire field F23=More options
===============================================================================
Work with Object Links
Directory . . . . : /spool
Type options, press Enter.
2=Edit 3=Copy 4=Remove 5=Display 7=Rename 8=Display attributes
11=Change current directory ...
Opt Object link
Bottom
Parameters or command
===>
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel F17=Position to
F22=Display entire field F23=More options
===============================================================================
使用CVTSPLSTMF 指令範例:
利用 AS/400 列印螢幕功能(HOST print),列印一份報表 QSYSPRT,在使用下列指令將
QSYSPRT 報表複製至目錄 /spool 中:
Convert Spool to Stream File (CVTSPLSTMF)
Type choices, press Enter.
From spooled file name . . . . . > QSYSPRT Name
To stream file name . . . . . . > QSYSPRT.TXT
To directory . . . . . . . . . . > '/spool'
Job name . . . . . . . . . . . . * Name, *
User . . . . . . . . . . . . . Name
Number . . . . . . . . . . . . 000000-999999
Spooled file number . . . . . . > *LAST 1-9999, *LAST, *ONLY
Stream file format . . . . . . . *TEXT *TEXT, *HTML
Stream file option . . . . . . . > *REPLACE *NONE, *REPLACE, *ADD
Bottom
F3=Exit F4=Prompt F5=Refresh F10=Additional parameters F12=Cancel
F13=How to use this display F24=More keys
==============================================================================
此時使用 WRKLNK '/spool' ,按執行鍵,並使用選項 5,會得到下列畫面,使用選項 5,
可以檢視報表資料:
Work with Object Links
Directory . . . . : /spool
Type options, press Enter.
2=Edit 3=Copy 4=Remove 5=Display 7=Rename 8=Display attributes
11=Change current directory ...
Opt Object link
QSYSPRT.TXT
Bottom
Parameters or command
===>
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel F17=Position to
F22=Display entire field F23=More options
==============================================================================
當轉換為一般文字檔後,可以使用 FTP 方式或 AS/400 NetServer 方式將目錄分享出來,
PC 端即可取得報表資料了。
有關 As/400(iSeries) NetServer 詳細資料請參照
http://www-1.ibm.com/servers/eserver/iseries/netserver/
File : QRPGLESRC
Member: CVTSPLSTMR
Type : RPGLE
Usage : CRTBNDRPG CVTSPLSTMR
******************************************************************
* *
* PROGRAM NAME: CVTSPLSTMR called by CVTSPLSTMC *
* *
* AUTHOR : Vengoal Chang *
* *
* DATE WRITTEN: March 2006 *
* *
* DESCRIPTION : Converts spooled file data in work file *
* CvtSplWrk2 to HTML or TEXT format to work file *
* CvtSplWrk1. *
* *
* FUNCTIONS : Adds basic HTML headings and footings and a *
* title. *
* *
* Copyright 2006 (c) Vengoal Chang. *
* All rights reserved. *
* *
******************************************************************
H DFTACTGRP(*NO) Debug
FCvtSplWrk2IF F 382 DISK
FCvtSplWrk1UF A F 378 DISK
* Standard HTML header lines
D aaHeader S 80A DIM(2) CTDATA PERRCD(1)
* Standard HTML footer line
D aaFooter S 80A DIM(1) CTDATA PERRCD(1)
* Input spooled file data including control characters
D InputData DS
D saSkipLine 3A
D ssSkipLine 3S 0 OVERLAY(saSkipLine:1)
D saSpceLine 1A
D ssSpceLine 1S 0 OVERLAY(saSpceLine:1)
D saInput 378A
* Output HTML-format data
D OutputData DS
D saOutput 378A
* Program parameters - title and page length in lines
D paToFmt S 5A
D paTitle S 50A
D piPageLen S 10I 0
* Line counter variable
D wiLine S 10I 0
* Procedure prototypes
D HTMLHeader PR
D HTMLFooter PR
D Convert PR
D Merge PR LIKE(saOutput)
D iaOutput LIKE(saOutput)
D iaInput LIKE(saInput)
D SpceLines PR
D isSpceLine LIKE(ssSpceLine)
D SkipLines PR
D isSkipLine LIKE(ssSkipLine)
D ParseInput PR
**********************************************************************
* Program parameters
C *ENTRY PLIST
C PARM paToFmt
C PARM paTitle
C PARM piPageLen
* Output HTML header lines
C If paToFmt = '*HTML'
C CALLP HTMLHeader
C EndIf
* Convert spool file lines to HTML or Text
C EVAL wiLine = 1
C READ CvtSplWrk2 InputData LR
C DOW *INLR = *OFF
C CALLP ParseInput
C CALLP Convert
C READ CvtSplWrk2 InputData LR
C ENDDO
* Output HTML footer lines
C If paToFmt = '*HTML'
C CALLP HTMLFooter
C EndIf
C RETURN
**********************************************************************
* Procedure to create HTML header lines *
**********************************************************************
P HTMLHeader B
D HTMLHeader PI
C EVAL saOutput = aaHeader(1)
C WRITE CvtSplWrk1 OutputData
C IF paTitle <> '*NONE'
C EVAL saOutput = '< TITLE>'
C + %trim(paTitle)
C + ''
C WRITE CvtSplWrk1 OutputData
C ENDIF
C EVAL saOutput = aaHeader(2)
C WRITE CvtSplWrk1 OutputData
P HTMLHeader E
**********************************************************************
* Procedure to create HTML footer line *
**********************************************************************
P HTMLFooter B
D HTMLFooter PI
C EVAL saOutput = aaFooter(1)
C WRITE CvtSplWrk1 OutputData
P HTMLFooter E
**********************************************************************
* Procedure to convert spooled file data to HTML text *
**********************************************************************
P Convert B
D Convert PI
* If 'space' position is zero, 'overprint' previous line
C IF saSpceLine = '0'
C *HIVAL SETGT CvtSplWrk1
C READP CvtSplWrk1 OutputData 99
C EVAL saOutput = Merge(saOutput:saInput)
C UPDATE CvtSplWrk1 OutputData
C ELSE
* Skip to a line if specified
C IF saSkipLine <> *BLANKS
C CALLP SkipLines(ssSkipLine)
C ENDIF
* Space a number of lines if specified
C IF saSpceLine <> *BLANKS
C CALLP SpceLines(ssSpceLine)
C ENDIF
* 'Print' line
C EVAL saOutput = saInput
C WRITE CvtSplWrk1 OutputData
C EVAL wiLine = wiLine + 1
C ENDIF
C RETURN
P Convert E
**********************************************************************
* Procedure to merge two overlaid lines of text *
**********************************************************************
P Merge B
D Merge PI LIKE(saOutput)
D iaOutput LIKE(saOutput)
D iaInput LIKE(saInput)
D laOutput S LIKE(saOutput)
D i S 5I 0
C EVAL i = 1
C DOW i <= %size(iaInput )
C and i <= %size(iaOutput)
C and i <= %size(laOutput)
C IF %subst(iaInput:i:1) = *BLANK
C EVAL %subst(laOutput:i:1) = %subst(iaOutput:i:1)
C ELSE
C EVAL %subst(laOutput:i:1) = %subst(iaInput :i:1)
C ENDIF
C EVAL i = i + 1
C ENDDO
C RETURN laOutput
P Merge E
**********************************************************************
* Procedure to skip to a given line number *
**********************************************************************
P SkipLines B
D SkipLines PI
D isSkipLine LIKE(ssSkipLine)
C EVAL saOutput = *BLANKS
C IF wiLine > isSkipLine
C DOW wiLine <= piPageLen
C WRITE CvtSplWrk1 OutputData
C EVAL wiLine = wiLine + 1
C ENDDO
C If paToFmt = '*HTML'
C EVAL saOutput = '< hr>'
C WRITE CvtSplWrk1 OutputData
C EndIf
C EVAL saOutput = *BLANKS
C EVAL wiLine = 1
C EndIf
C DOW wiLine < isSkipLine
C WRITE CvtSplWrk1 OutputData
C EVAL wiLine = wiLine + 1
C ENDDO
C RETURN
P SkipLines E
**********************************************************************
* Procedure to space a number of lines *
**********************************************************************
P SpceLines B
D SpceLines PI
D isSpceLine LIKE(ssSpceLine)
D liCount S 5I 0
C* EVAL wiLine = wiLine + 1
C EVAL saOutput = *BLANKS
C DOW liCount < isSpceLine - 1
C WRITE CvtSplWrk1 OutputData
C EVAL wiLine = wiLine + 1
C EVAL liCount = liCount + 1
C ENDDO
C RETURN
P SpceLines E
**********************************************************************
P ParseInput B
D ParseInput PI
D Input S 2048
D InpLen S 5I 0
D DATA S 2048
D X0E C X'0E'
D X0F C X'0F'
C z-add 1 i 5 0
C z-add 1 J 5 0
C Clear Data
C Eval Input = InputData
C Eval InpLen= %len(%trimr(InputData))
C 1 Do InpLen
C If %SUBST(Input : i : 1) = X0E
C Eval %SubSt(Data : j : 1) = ' '
C Eval J = J + 1
C Eval %SubSt(Data : j : 1)
C = %SubSt(Input : i : 1)
C Else
C If %SUBST(Input : i : 1) = X0F
C Eval %SubSt(Data : j : 1)
C = %SubSt(Input : i : 1)
C Eval J = J + 1
C Eval %SubSt(Data : j : 1) = ' '
C Else
C Eval %SubSt(Data : j : 1)
C = %SubSt(Input : i : 1)
C EndIf
C EndIf
C Eval i = i + 1
C Eval j = j + 1
C If i > InpLen
C Leave
C EndIf
C EndDo
C Eval InputData = Data
C Eval InpLen = j -1
C
C RETURN
P ParseInput E
**
< html>< head>
< body>< pre>
**
< hr>