Более сложный способ сделать это - создать параметр типа * X . Затем вы можете передать любую переменную в вашу программу RPGLE и обработать ее. Вы можете принять * CHAR, * DEC, * INT, что угодно. Вот пример оператора PARM для определения команды:
PARM KWD(RTNVAR) TYPE(*X) LEN(1 10 0) +
RTNVAL(*YES) MIN(1) VARY(*YES *INT2) +
PASSATR(*YES) Prompt('Return Field')
Если вы введете это и нажмете на справку, это может объяснить, как TYPE (* X) работает с атрибутом LEN и как работают атрибуты VARY и PASSATR. Для этого примера я поставил значение по умолчанию 10,0 для десятичных чисел, но это не должно быть.
Затем в вашей программе RPGLE возьмите этот параметр ввода и разбейте его на структуру данных следующим образом:
D#EntryVariable DS
D parmAttr1 1 1i 0
D parmNumDec 2 2i 0
D parmDecLength 3 3i 0
D parmSize 2 3i 0
D EntryValue 4 19
Вы должны установить это значение EntryValue на любую длину, которая, по вашему мнению, будет максимальной, учитывая, что десятичные переменные в CL хранятся в запакованном формате в памяти, поэтому 15-байтовое десятичное поле будет иметь длину 8 байт (7,5 байт +. 5-байтный знак). Структура данных по полям выглядит следующим образом:
- parmAttr1 сообщает вам, какой тип переменной был передан. Вот некоторые значения:
- * DEC = 0x03
- * INT = 0x00
- * CHAR = 0x04
- parmNumDec действителен только для переменных * DEC. Это количество десятичных знаков.
- parmDecLength действителен только для переменных * DEC. Это общее количество цифр для поля * DEC
- parmSize действителен только для переменных, отличных от * DEC. Это длина переданной переменной.
- EntryValue - это значение, которое должно быть возвращено вызывающей программе. Он будет содержать любое значение, которое было там до вызова вашей команды. Оставьте достаточно места, чтобы вместить любую переменную, которую вы ожидаете.
Затем вы обрабатываете свой код, чтобы получить значение и поместить его в часть EntryValue структуры данных. Будьте очень осторожны при обновлении EntryValue. Любые данные, превышающие заданную длину, не принадлежат вашей программе, и если вы их измените, вы можете сломать что-то еще в работе. Опять же, помните, что десятичные переменные CL хранятся в памяти в упакованном десятичном формате.
Чтобы ввести десятичное значение в упакованное поле неизвестного размера, вы можете сделать это одним из двух способов. Простой, но утомительный способ сделать это - создать 15 различных упакованных десятичных переменных и определить их в структуре данных параметров ввода, используя SELECT и WHEN для заполнения. Другой способ - использовать указатели и циклы. Я покажу вам, как. Для начала вам понадобятся некоторые указатели и определенные рабочие поля:
*Working field to hold the value to be returned.
*Decimal places are implied, but not necessary.
DworkDec S 15P 0
*Pointer to the value part of the entry parameter.
DptrParmValue S *
*Pointer to the working decimal field.
DptrWorkDec S *
*A single byte of the parm value. This will move along the
*parm value field as ptrParmValue changes.
DparmChar S 1 Based(ptrParmValue)
*A single byte of the workDec field. This will move along
*the field as ptrWorkDec changes.
DworkChar S 1 Based(ptrWorkDec)
*A counter for positioning the ptrParmValue pointer.
DparmPos S 5i 0
*A counter for positioning the ptrWorkDec pointer.
DworkPos S 5i 0
*The actual length, in bytes, of the return parm value
DparmRealLen S 5i 0
Что вы будете делать, это переместить значение результата в поле workDec. Я предлагаю создать временное целочисленное поле (5i 0) и умножить результат на 10 до степени количества десятичных позиций в результате, чтобы получить целое число с подразумеваемым десятичным числом, а затем СДЕЛАТЬ временное целочисленное поле в workDec. workDec определяется как 15,0, так как это все больше, чем может быть десятичное поле CL - имея в виду, что мы игнорируем десятичные дроби в этой точке. Итак, мы знаем, что workDec всегда будет больше или равным переданному параметру.
После установки workDec вы начинаете задом наперед с самой правой части как workDec, так и parmValue, сбрасывая байты по ходу. Мы делаем это потому, что упакованные десятичные значения хранятся в памяти по правому краю.
/free
workPos = (%Size(workDec)+.5)/2 + .99 - 1;
parmRealLen = (parmDecLength_.5)/2 + .99;
For parmPos = parmRealLen-1 downTo 0;
ptrParmValue = %Addr(parmValue)+parmPos;
ptrWorkDec = %Addr(workDec)+workPos;
parmChar = workChar;
workPos = workPos-1;
EndFor;
/end-free