หลักการ
Array = มักใชักับชุดของตัวแปร แทนที่จะประกาศตัวแปรที่มีลักษณะเหมือนกันหลายๆตัว เช่น X1,X2,X3 โดยเพียงระบุ X(1), X(2), X(3) อ่านว่า X ลำดับ(element) ที่ 1, X ลำดับที่ 2, X
ลำดับที่ 3
Array ของ RPG/400
มีข้อจำกัดพอสมควรเมื่อเทียบกับภาษาสมัยใหม่อื่นๆ เช่น
ทำได้แค่ 1 มิติเท่านั้น
ตัวอย่างที่ใช้งานบ่อยๆ
- เดือน 1 มีชื่อย่อว่า JAN Mth(1) = JAN, Mth(2) = FEB
-
รวมค่าใช้จ่าย แยกตามเดือน Amt(1),Amt(2),…
เก็บค่าใช้จ่ายของเดือน 1,2,
…
- รวมยอดขาย แยกกลุ่มสินค้า Gam(1),Gam(2),…
เก็บยอดขายกลุ่มสินค้า 1,2,
…
- การค้นหา
“อักษร” ที่ต้องการ (วิธีใหม่
ใช้ Scan)
- การจัดการ String
เช่น ชื่อกลุ่มงาน ที่ 2
อักษร หลัง “-“ (MT-Z1001 -> Z1) ,
ตัดอักษรหลัง ตัวเลข (608ZZ
-> 608, R-1560HHMT -> R-1560)
รูปแบบการสร้าง ตัวแปร Array
I. Array ว่างๆ เป็นตัวแปรสำหรับใช้งาน
II. Array ที่กำหนดค่าให้เลย ด้วยตารางข้อมูลท้ายโปรแกรม
III. Array ที่อ่านจาก File โดยตรง
I. การประกาศค่า Array ว่างๆ
รูปแบบที่ใช้กันบ่อย
ในการสร้างรายงานข้อมูลการขายสินค้าทั้งเดือน (เรียงตาม Invoice No)
- แต่ต้องการให้ ให้ "สรุป" รวมค่าตามแต่ละรายการสินค้า ท้ายรายงาน
ปรกติ ที่ท้ายโปรแกรม จะเพิ่มเปิด Logical-file ที่เรียงตามงาน อ่านแล้วคำนวน
หลายคนไม่ใช้วิธีนี้ เนื่องจาก อาจจะพบบางกรณีที่รวมค่าแล้วไม่เท่ากับ รายการด้านบน! เพราะมีข้อจำกัดเฉพาะแทรกอยู่
ทางแก้ไข คือ ก่อนจะพิมพ์รายงาน (ด้านบน) ให้รวมค่าเก็บไว้ในตัวแปร
ประกาศตัวแปร Array
E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+
E AR21 50 15
AQ22 7 2
ได้ AR21[...] ขนาด 15 อักษร จองพื้นที่ไว้ 50 ตัว
AQ22[…]
ตัวเลข 7,2 (xx,xxx.xx
จองพื้นที่ไว้ 7 หลัก
2 หลักเป็นทศนิยม )
จองตัวแปรไว้ 50 ตัว
ลบค่าใน Array ทิ้ง มักจะประกาศไว้ครั้งแรก (อยู่ก่อนเข้า Loop
อ่านข้อมูล)
มักจะกำหนดตัวชี้ Element สุดท้ายใน
Array (เช่น M2)
C....Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments
C CLEARAR21
C CLEARAQ22
C Z-ADD0 M2
ตรวจค่าใน Array ด้วย LookUp
ถ้าพบ สะสมค่า, ถ้าไม่พบ ให้จัดเก็บค่าไว้ใน Array
รูปแบบที่ใช้กันบ่อย
C....Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments
C
Z-ADD1 I# 30
C ItemNo LOKUPAR21,I# 80
C *IN80
IFEQ ‘1’ Found
C ADD qty
AQ22,M2
C ELSE Not-Found
C ADD 1
M2
C MOVEItemNo AR21,M2
C Z-ADDqty AQ22,M2
C ENDIF
นำ ItemNo (ค่าจาก File) ค้นหาใน Array AR21 โดยเริ่มต้นลำดับที่ตามค่า I# (ควรเริ่มที่ 1)
ถ้าพบ *Indicator
จะ On (‘1’) ตัวแปร I# จะบอกลำดับที่พบ
ตย. ต้องการตัด “IN” ทิ้ง ใน ITEM เช่น เป็น “FISH IN OIL” กลายเป็น “FISH OIL”
ใช้ Array มาเก็บข้อมูล ด้านซ้าย และ ด้านขวา โดยตรวจจาก ตำแหน่ง
ค่าเริ่มต้น ค่าสุดท้าย
1...5....0. 1...5....0
FISH IN OIL FISH OIL
a.ค้นหาตำแหน่ง "IN" ใน ITEM
a.1 พบเริ่มต้น ตำแหน่งที่ 6 (จัดเก็บใน I#)
a.2 "IN" มีความยาว 2 อักษร ตำแหน่งถัดไป คือ 8 (6 + 2) (จัดเก็บใน J#)
b.นำอักษรถัดไป ถึงแม้ว่าจะเป็นช่องว่าง (X#5) มาแทนที่ ตำแหน่งเริ่มต้นที่พบ IN
เลือกใช้คำสั่งที่เหมาะสมได้ ดังนี้
E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+
E AR1 50 1
C*---
“IN“ SCAN ITEM,1 I# 80 a.
*IN80 IFEQ ‘1’ Found
I# ADD 2 J# a.2
MOVEAITEM AR,1
MOVEAAR,J# X#5
5 SUBSTITEM:J# X#5 Or
MOVEAX#5 AR,I# b.
END
ตย. อ่านข้อมูล ได้ “กลุ่มสินค้า” เก็บใน str และ “ยอดขาย” เก็บใน qty
ต้องการรวม “ยอดขาย” ตาม “กลุ่มสินค้า” การประกาศค่า โดย
AR21 ใช้เก็บ กลุ่มสินค้า
AQ22 ใช้เก็บ ยอดรวมจำนวน
E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+
E AR21 50 15 AQ22 7 2
C*…
C....Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments
C CLEARAR21
C CLEARAQ22
C Z-ADD0 M2
C*
C*---KEY1 SETLL file
C*---KEY1 READE file
C*---*IN80 DOWEQ '0'
C*
C Z-ADD1 I# 30
C str LOKUPAR21,I# 80
C *IN80 IFEQ ‘1’ Found
C ADD qty AQ22,M2
C ELSE
C ADD 1 M2
C MOVEstr AR21,M2
C Z-ADDqty AQ22,M2
C ENDIF
C*---
C*--- EXCPT DTL010
C*---KEY1 READE file
C*--- ENDDO
C*----
C*
C XFOOTAQ22 T#QTY
C DO M2 I#
C MOVELAR21,I# O#ITNO
C Z-ADDAQ22,I# O#QTY
C EXCPTTTL010
C ENDDO
Xfoot รวมค่าใน Array ทั้งหมด (อยู่หลัง Loop อ่านข้อมูล)
รูปแบบที่ใช้กันบ่อย
C....Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments
C XFOOTAQ22 T#QTY
Tip บางคนหลีกเลี่ยงคำสั่งดังกล่าวด้วยการเพิ่มคำสั่งลักษณะนี้ลงไป
(เข้าใจง่ายแต่
อาจทำให้โปรแกรมทำงานหนักขึ้น)
C....Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments
C ADD qty T#QTY
Sort การเรียงลำดับใน Array
รูปแบบที่ใช้กันบ่อย
C....Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments
C SORT AR1
ระวัง หลังการเรียง ข้อมูลกลุ่มที่เป็น Blank จะแสดงก่อน
ทางแก้ไข การนำไปใช้
ต้องเลือกรายการที่ไม่เป็น Blank
Array
ที่สร้างแบบเรียกใช้เป็นคู่ AR21, AQ22 การ SORT จะตัวเดียว
จะทำให้ลำดับคู่ใน AQ22 ผิด
ทางแก้ไข รวม AR21 กับ AQ22 ให้เป็น Array ตัวเดียวกัน (ทำหลัง Loop อ่าน Data) แล้วจึงเรียงลำดับ
C....Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments
C DO M2
I#
C MOVELAR21,I# AR1 LEFT
C MOVE AQ22,I# AR1 RIGHT
C
ENDDO
C*
C
SORT AR1
C*
C
DO M2 I#
C
MOVELAR1,I# O#ITNO
LEFT
C MOVE AR1,I# O#QTY RIGHT
C O#ITNO IFNE *BLANKS
C
EXCPTTTL010
C
ENDIF
C
ENDDO
ตย.
จากข้อมูลต่อไปนี้
(Logical File : Key = Order)
Order Item Qty
111 A 10
222 A 10
333 B 15
444 A 10
ใช้ Array รวมค่าและแสดงผลรวม
ท้ายรายงาน ลักษณะนี้
# Total = 45
A
30
B
15
E
AR21 50 15
AQ22 7 2
C*…
C CLEARAR21
C CLEARAQ22
C Z-ADD0 M2 30
C STP010
TAG
C* -------------
C
EXFMTDSP01
C KA GOTO
STP020
C*
C
EXCPTHED010
C KEY12 SETLLOrderL1
C READ
OrderL1 80
C*
-------------------------------
C *IN80 DOWEQ’0’
C*
C
Z-ADD1 I# 30
C ITEM LOKUPAR21,I# 80
C *IN80
IFEQ ‘1’
Found
C ADD qty
AQ22,M2
C ELSE
C
ADD 1 M2
C
MOVELITEM AR21,M2
C Z-ADD AQ22,M2
C ENDIF
C*
C OF
EXCPTHED010
C
EXCPTDTL010
C*
C READ
OrderL1 80
C ENDDO
C*
-------------------------------
C STP020 TAG
C* -------------
C
EXCPTHED010
C
XFOOTAQ22 G#QTY
C
EXCPTGRD010
C*
C
DO M2 I#
C
MOVELAR21,I# T#ITEM
C
Z-ADDAQ22,I# T#QTY
C EXCPTTTL010
C
ENDDO
C*
C SETON LR
C LR
RETRN
II. Array ที่กำหนดค่าให้เลย จากตารางข้อมูลท้ายโปรแกรม
ข้อสังเกต กำหนดค่าใน E-Spec มี 3 ชุดตัวเลข
โดยเพิ่มจำนวน Data ใน 1 แถวข้อมูล
ตารางข้อมูลท้ายโปรแกรม ต้องวางท้ายโปรแกรมจริงๆ โดยเริ่มต้นที่ด้วย ** (Col.1,2)
ถ้ามีมากกว่า 1 ตาราง RPG จะเลือกแบบเลียงลำดับ
0010.00 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDS
0011.00 E MT1 1
12 3
0012.00 E MT2 3
12 2
0013.00 C*…
FMT
** ...+... 1 ...+... 2
0076.00 **
For MT1 1 Line Contain 1 Data
0077.00 JAN
0078.00 FEB
0080.00
MAR
0081.00 APR
0082.00 MAY
0083.00
JUN
0084.00 JUL
0085.00 AUG
0086.00
SEP
0087.00 OCT
0088.00 NOV
0089.00
DEC
0090.00 **
For MT2 1 Line contain 3 Data
0091.00 010203
0092.00 040506
0093.00 070809
0094.00 101112
สร้างโปรแกรมทดสอบ
รับค่า
เดือน (เลขที่) W1MTH2
Enter
แสดงค่า เดือน (อักษร) W1MTH3
MoveL*blanks W1MTH3
Z-add1 i#
W1MTH2 LokupMT2,i# 80
*in80 IFEQ
‘1’ Found
MoveLMT1,i# W1MTH3
ENDIF
III. Array ที่กำหนดค่าให้เลย จาก File
การกำหนดข้อมูลจาก
File ก็ต้องไปประกาศ File ที่จะใช้ ดังนี้
FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......
0009.00 FFILE1 IT
F 3 EDISK
0010.00 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDS
0011.00 E M1 1 12 3