我对AS400和RPG的了解非常有限。但我们有一个要求,需要从 Java 类调用 RPG 程序。所以我发现我们可以通过JTOpen来实现。但我坚持声明 ProgramParameter 列表。我有以下关于RPG程序的信息
程序名称:ZM30000R
参数:
分支 7,0(数字)
账户类型2(01-支票,02储蓄)
账号20(字符)
错误代码7(字符)
DR/CR 指示灯 1(字符 D、C)
但不知道输入和输出是什么。如何声明ProgramParameter?我已经做了如下。我也无法测试,因为我没有连接到这些系统。
// Create AS400 Text objects for the different lengths
// of parameters you are sending in.
AS400Text branchTxt = new AS400Text(7);
AS400Text accntTypeTxt = new AS400Text(2);
AS400Text accntNumberTxt = new AS400Text(20);
AS400Text errorCodeTxt = new AS400Text(7);
AS400Text DCIndicatorTxt = new AS400Text(1);
// declare and instantiate your parameter list.
ProgramParameter[] parmList = new ProgramParameter[5];
// assign values to your parameters using the AS400Text class to convert to bytes
// the second parameter is an integer which sets the length of your parameter output
parmList[0] = new ProgramParameter( branchTxt.toBytes(branch),7);
parmList[1] = new ProgramParameter( accntTypeTxt.toBytes(accntTypeTxt),2);
parmList[2] = new ProgramParameter( accntNumberTxt.toBytes(accntNumberTxt),20);
parmList[3] = new ProgramParameter( errorCodeTxt.toBytes(""),7);
parmList[4] = new ProgramParameter( DCIndicatorTxt.toBytes(indicator),5);
嗯,仅通过参数的描述我就知道了。分行、账户类型和账号均为IN。您需要该信息来进行财务预订或交易。错误代码显然是 OUT。根据我对金融系统的经验,API 返回预订金额的方式是合理正常的。通常人们会使用该符号,但在金融系统中,(D)ebit 或 (C)redit 是更好的方式。
该 API 很可能是金融系统的 API。如果这是真的,那么我就错过了这笔钱。您确定有完整的描述吗?
请注意,第一个参数是数字。你不走运。 iSeries 和 RPG 对于数字类型不是很宽容。可以从位、分区、打包、十进制、整数、浮点等中进行选择。如果 RPG 确实是 RPG 而不是 ILE RPG,那么您可以将其归结为分区、打包和字节。
我假设您可以访问 iSeries。然后就可以观看程序调用、调试信息和转储信息。如果您必须进行“反复试验”,这将对您有所帮助。如果没有通行证,路就会很艰难。如果程序调用不成功,您将在 java 类中收到错误。但如果没有来自 iSeries 的信息,您将很难确定真正的错误。因此,确实需要访问。
您的样本大部分都在正确的轨道上。但你的分支参数是数字。所以你应该使用 AS400ZonedDecimal 而不是 AS400Text:
AS400ZonedDecimal branchNbr = new AS400ZonedDecimal(7,0)
RPG 程序可能会被打包而不是分区。没什么大不了的,只需使用 AS400PackedDecimal 即可。
当您构造 ProgramParameter 对象时,您的构造函数要求会有所不同,具体取决于它们是程序的输入参数还是输出参数。对于输入参数,只需传递 toBytes() 结果即可。无需包含长度。对于仅输出参数,只需传递长度即可。
我同意罗伯特的回答,即缺少一些信息,但他对错误代码输出的假设似乎是有效的。但是,我猜测输入了 DCIndicator 参数,因为您的示例传递了一个值。对于错误代码参数,在程序调用之后,您需要提取该值并对其执行某些操作。根据您已经掌握的内容,程序调用的工作方式如下。请注意,我指定了库名称“MyLibrary”。这是出于示例目的。您必须确定您的程序对象位于哪个库中。
ProgramCall pgm = new ProgramCall(as400, QSYSObjectPathName.toPath("MyLibrary","ZM30000R","PGM"), parmList);
if (pgm.run() == true) {
String sErrorCode = (String) errorCodeTxt.toObject(parmList[3].getOutputData());
//Do something with your output data.
}
else {
AS400Message[] messageList = pgm.getMessageList();
for (int i=0; i<messageList.length; i++) {
String sMessageID = messageList[i].getID();
String sMessageText = messageList[i].getText();
//Do something with the error messages
}
}
还需要考虑的是库列表。 RPG 程序是否期望某些库出现在库列表中?如果是这样,您应该在调用程序之前发出 CommandCalls 将库添加到库列表中。
FWIW:使用 PCML 调用 IBM i 主机程序和服务程序比
ProgramCall
更容易。
编译器甚至会为您生成 PCML 文档。
有关详细信息,请参阅 http://javadoc.midrange.com/jtopen/com/ibm/as400/data/ProgramCallDocument.html。
如果您没有连接,那么您确实无法执行要求的操作。你如何测试它?参数是数字还是字符?