我正试图涉足RPG ILE的MVC池。所以我有两个模块VIEW和MODEL,它们绑定到我的主程序CNTRL。我通过调用MODEL模块验证在VIEW模块中输入的信息,然后传回View任何错误。当我尝试使用QHNSNDPM api时,我在作业日志中看到错误,然后是CALL STACK STTRY NOT FOUND。我试图在调用堆栈上找到theVIEW模块,但它不在那里。在DDS和ILE中不是超强,我不知道如何/如何处理这个错误。任何建议将不胜感激!
DCL-F DISPLAY WORKSTN;在VIEW模块中。
现在来自VIEW模块的一些代码......
fileQueue.enqueue('')
和DDS for DISPLAY ....
dcl-pr SendMsg Extpgm('QMHSNDPM');
MsgID char(7) const;
MsgF char(20) const;
MsgData char(30) const;
MsgDataLen int(10) const;
MsgType char(10) const;
CallStackEnt char(10) const;
CallStackCtr int(10) const;
MsgKey char(4) const;
Error like(ErrorDS);
end-pr;
*******************************************************************
dcl-proc VIEW_SetError EXPORT;
dcl-pi *n;
Msg int(3);
MSGQ char(10);
end-pi ;
// The MSGQ parameter is from the PSDS *PROC
// I tried having this defined in the view where the DDS file
// is defined, and I have tried with it defined in the main CNTRL program
Dcl-s MsgTxt char(30);
if Msg=1;
MsgTxt='Invalid Facility';
AT1FAC=setAttr(*omit:'RI');
elseif Msg=2;
MsgTxt='Status must be O, C, or A!';
AT1STAT=setAttr(*omit:'RI');
elseif Msg=3;
MsgTxt='Invalid Order Number';
AT1ITEM=setAttr(*omit:'RI');
elseif Msg=4;
MsgTxt='Invalid Vendor Number';
AT1VEND=setAttr(*omit:'RI');
elseif Msg=5;
MsgTxt='Invalid Pallet Number';
AT1PLT=setAttr(*omit:'RI');
endif;
callp SendMsg (*blanks: *blanks :
MsgTxt : %size(MsgTxt):
'*INFO': '*':
0: *blanks: ErrorDS);
// I have tried setting the CallStackEnt to * and C
// And the CallStackCtr to 0,1,2
write msgctl;
end-proc ;
这是启动进程的CL ....它非常基本,但我们在遗留代码中使用了很多覆盖,所以我认为从CL开始会有所帮助......
A DSPSIZ(24 80 *DS3)
A CHGINPDFT(UL FE)
A PRINT
A HELP
A ALTHELP(CA01)
A* ALTPAGEUP(CF07)
A* ALTPAGEDWN(CF08)
A CF03(03)
A CF04(04)
A CF06(06)
A CF12(12)
*------------------------------------------------------------------*
* Screen 1 - Filter Criteria
*------------------------------------------------------------------*
A R SCREEN1
A OVERLAY
A BLINK
A RTNCSRLOC(&REC1 &FLD1)
A CSRLOC(XROW1 XCOL1)
A XROW1 3S 0H
A XCOL1 3S 0H
A REC1 10A H
A FLD1 10A H
A 1 2'SCN200-01'
A COLOR(BLU)
A COMPANY 40A O 1 20DSPATR(HI)
A WSID 10A O 1 62
A 1 73DATE
A EDTCDE(Y)
A 2 2SYSNAME
A 2 23'Pallet Maintenance'
A COLOR(BLU)
A 2 62USER
A 2 73TIME
A 5 4'Enter Facility to Search'
A COLOR(BLU)
A 7 7'Facility:'
A DFAC1 2 B 7 21
A DSPATR(&AT1FAC)
A AT1FAC 1A P
A 7 24'+'
A 8 2'Pallet Status:'
A DSTAT 1 B 8 21
A DSPATR(&AT1STAT)
A AT1STAT 1A P
A 8 24'(O=Open, C=Closed, or A=All)'
A 10 4'Search by Item and/or Vendor:'
A COLOR(BLU)
A 11 11'Item:'
A DITM1 15A B 11 21
A DSPATR(&AT1ITEM)
A AT1ITEM 1A P
A 11 37'+ (Blank=All)'
A 12 9'Vendor:'
A DVND1 5S 0B 12 21
A DSPATR(&AT1VEND)
A AT1VEND 1A P
A 12 28'+ (Blank=All)'
A 15 7'Or By Pallet ID:'
A COLOR(BLU)
A 16 9'Pallet:'
A DPLT1 11A B 16 21
A DSPATR(&AT1PLT)
A AT1PLT 1A P
A 18 4'IF ALL SEARCH FIELDS LEFT BLANK, +
A ALL FACILITY RECORDS'
A COLOR(BLU)
A 19 6 'DISPLAYED IN PALLET ID ORDER.'
A COLOR(BLU)
A 23 2'F3=Exit'
A COLOR(BLU)
*------------------------------------------------------------------*
* Message Subfile
*------------------------------------------------------------------*
A R MSGRCD TEXT('MSG SFL RECORD')
A SFL SFLMSGRCD(24)
A MSGKEY SFLMSGKEY
A PGMSGQ SFLPGMQ
*------------------------------------------------------------------*
* Message Subfile Control
*------------------------------------------------------------------*
A R MSGCTL TEXT('MSG SFL CONTROL')
A OVERLAY SFLCTL(MSGRCD) SFLSIZ(10)
A SFLPAG(1) SFLDSPCTL SFLDSP SFLINZ
A N98 SFLEND
A PGMSGQ SFLPGMQ
顺便说一下,公司位是我测试的遗留物。我已从服务程序中添加了公司检索。
CNTRL RPGLE ......
PGM
DCL VAR(&COMPANY) TYPE(*CHAR) LEN(40) VALUE('BROWNFOX')
CALL PGM(CNTRL) PARM(&Company)
ENDPGM
我想如果我已经把它拿走了这么远,我不妨投入复制成员
模型复制
ctl-opt dftactgrp(*no) BNDDIR('MVC');
*------------------------------------------------------------------*
* Mainline processing
*------------------------------------------------------------------*
/define MODEL_PalletMaintenance
/copy TEMPLATE/QCPYSRC,MODEL
/undefine MODEL_PalletMaintenance
/define VIEW_GetParms
/copy TEMPLATE/QCPYSRC,VIEW
/undefine VIEW_GetParms
dcl-ds *N PSDS;
PGMSGQ *PROC;
WSID CHAR(10) Pos(244);
USER CHAR(10) Pos(254);
end-ds;
//dcl-s Exit ind;
//dcl-s ErrorField char(30);
dcl-s ErrorText char(30);
dcl-s ErrorID int(3);
//dcl-ds Screen1DS likeDS(Screen1);
dcl-s CurrentStep int(5);
dcl-c StepExit 0;
dcl-c StepPrep 1;
dcl-c StepShowScreen1 2;
dcl-c StepValidateScreen1 3;
//dcl-c StepShowScreen2 0;
dcl-pr cntrl EXTPGM ;
END-PR;
//dcl-PROC cntrl;
dcl-pi *n;
END-PI;
CurrentStep=StepPrep;
DoU CurrentStep=StepExit;
select;
When CurrentStep=StepPrep;
VIEW_Prep(Screen1DS);
MODEL_Prep(Screen1DS);
CurrentStep=StepShowScreen1;
When CurrentStep=StepShowScreen1;
if (VIEW_GetParms(Screen1DS));
CurrentStep=StepValidateScreen1;
else;
CurrentStep=StepExit;
ENDIF;
When CurrentStep=StepValidateScreen1;
ErrorID=MODEL_ValidateScreen1(Screen1DS);
if (ErrorID<>0);
VIEW_SetError(ErrorID:PGMSGQ);
CurrentStep=StepShowScreen1;
else;
CurrentStep=StepExit;
ENDIF;
ENDSL;
enddo;
*INLR=*on;
Return;
观看......
/if defined(MODEL_PalletMaintenance)
dcl-ds Screen1DS qualified;
Company char(40);
Facility char(2);
Status char(1);
Item char(35);
Vendor zoned(5:0);
Pallet char(11);
END-DS;
DCL-PR MODEL_Prep;
*n likeds(Screen1DS);
END-PR;
DCL-PR MODEL_ValidateScreen1 int(3);
*n likeds(Screen1DS);
END-PR;
/endif
答案 0 :(得分:2)
排除QMHSNDPM故障:在致电QMHRMVPM之前&#39;然后在调用QMHSNDPM之后查看交互式作业的消息(系统请求3然后是选项10,然后是f10,然后是f18),如果你没有看到你的消息发送消息的程序有问题。如果您确实看到该消息,请在光标上按f1,然后按F9查看消息的发送位置。
对于您的程序,可能需要2或3的msgCallStack,或者如果您希望在命令行返回消息,则需要4或5。
我输入oldschool格式来查看变量名称。
call 'QMHSNDPM'
parm msgIdIN
parm msgLoc
parm msgRplDta
parm msgRplDtaLen
parm msgType
parm msgQueue
parm 3 msgCallStack
parm msgKey
parm msgErr
这应该将消息从模型中的过程发送回视图。
对于rpg交互式中的MVC风格程序,您可以从视图开始,然后调用模型,该模型将消息拍摄回视图。也许你有一个调用视图的控制器。
答案 1 :(得分:1)
跟踪当前的堆栈级别可能很棘手。
请记住,当您在一个过程中时,堆栈级别增加1.因此,如果您当前的堆栈级别为1并且您调用了一个过程,则该过程内部的堆栈级别为2.
在我的应用程序中,我声明了一个初始化为1的全局变量。在进入过程时,我向该变量添加1,在退出时,我减去1.该变量被传递给QMHSNDPM API。
另外,对子程序的调用不会向堆栈添加1。
希望这有帮助。
答案 2 :(得分:1)
// MSGQ参数来自PSDS * PROC
//我尝试在DDS文件的视图中定义了这个 //已定义,我已尝试使用主CNTRL程序中定义的
因此在程序堆栈上,每个堆栈条目都有一个消息队列。您声明用于初始化消息子文件的消息队列来自PSDS *PROC
。因此,您需要将消息发送到相同的堆栈条目。我这样做的方法是使用相同的变量填充StackEntry和PGMMSGQ,并使堆栈计数器为0。
这是我向消息子文件发送消息的程序(我将其保存在服务程序中):
// ----------------------------------------
// SndDspfMsgText - sends an *INFO message to the
// message subfile in a display file.
//
// Parameters:
// StackEntry - The program call stack entry to which the message is sent.
// Usually the program name. This must be the same value that
// is placed in the SFLPGMQ variable in the message subfile
// control format.
// MsgText - Text of the messqage to be sent.
// MsgTextLen - The length of the message text provided above.
// ----------------------------------------
dcl-proc SndDspfMsgText Export;
dcl-pi *n;
StkEnt Char(10) Const;
MsgText Char(512) Const Options(*VarSize);
MsgTextLen Int(10) Const;
end-pi;
dcl-ds MsgFile LikeDs(QualName_t) Inz(*LikeDs);
dcl-ds ErrorCd LikeDs(ErrorCdType1_t) Inz(*LikeDs);
dcl-s pmMsgId Char(7) Inz('CPF9898');
dcl-s pmMsgText Char(512) Inz('');
dcl-s pmMsgTextLen Int(10) Inz(0);
dcl-s pmMsgTyp Char(10) Inz('*INFO');
dcl-s pmStkCnt Int(10) Inz(0);
dcl-s pmMsgKey Char(4) Inz('');
// if Message Data is provided,
if MsgTextLen > 0;
pmMsgTextLen = min(%size(MsgText): MsgTextLen);
pmMsgText = %subst(MsgText: 1: pmMsgTextLen);
endif;
MsgFile.Name = 'QCPFMSG';
qmhsndpm(pmMsgId: MsgFile: pmMsgText: pmMsgTextLen:
pmMsgTyp: StkEnt: pmStkCnt: pmMsgKey:
ErrorCd);
end-proc;
以下是一些您需要完全理解上述过程的模板:
// Standard Error Code Format
dcl-ds ErrorCdType1_t Qualified Template Inz;
BytesProv Int(10) Inz(%size(ErrorCdType1_t));
BytesAvail Int(10);
MsgId Char(7);
Data Char(1024) Pos(17);
end-ds;
// Qualified Name
dcl-s Name_t Char(10) Template Inz('');
dcl-ds QualName_t Qualified Template Inz;
Name Like(Name_t) Inz('');
Lib Like(Name_t) Inz('*LIBL');
end-ds;
// Call Stack Qualifier - used by message handling APIs
dcl-ds CallStackQual_t Qualified Template Inz;
Module Like(Name_t) Inz('*NONE');
Program Like(Name_t) Inz('*NONE');
end-ds;
// Send Program Message
dcl-pr qmhsndpm ExtPgm('QMHSNDPM');
MessageId Char(7) Const;
MessageFile LikeDs(QualName_t) Const;
MessageDta Char(512) Const Options(*Varsize);
MessageLen Int(10) Const;
MessageType Char(10) Const;
StackEntry Char(4102) Const Options(*Varsize);
StackCounter Int(10) Const;
MessageKey Char(4);
Error LikeDs(ErrorCdType1_t);
StackEntryLen Int(10) Const Options(*NoPass);
StackEntryQual LikeDs(CallStackQual_t)
Const Options(*NoPass);
ScreenWaitTime Int(10) Const Options(*NoPass);
StackEntryType Char(10) Const Options(*NoPass);
Ccsid Int(10) Const Options(*NoPass);
end-pr;