วันอาทิตย์ที่ 11 สิงหาคม พ.ศ. 2556

การใช้ Array

การใช้ Array

หลักการ           

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




วันพฤหัสบดีที่ 4 กรกฎาคม พ.ศ. 2556

มาทำรายงานกัน (ต่อ)


มาทำรายงานกัน (ต่อ)


บทความที่แล้วพูดถึง  “วิธีการคิด” ภาพรวม ... อาจจะดูซับซ้อนไปนิด (ดูบ่อยๆ ก็คุ้นๆน๊ะครับ)
ตย.1 สร้างรายงาน  ที่อ่านข้อมูล  100 %) ต่อไปนี้  
รายงานที่ต้องการ

วิเคราะห์  รูปแบบรายงาน

               จากแนวคิด  ต้องออกแบบรายงาน โดยแบ่งพื้นที่ออกเป็นส่วนๆ ได้แก่  ส่วนหัวกระดาษ  (Head)   ส่วนรายละเอียด (Detail)   และ ส่วนท้ายรายงาน   (ในที่นี้  ผมไม่ได้ควบคุม Footer)
ส่วนหัว   แยกเป็น  ส่วนที่เป็น Standard (ประกาศให้รู้ว่า report มาจากอะไร) + ชื่อ Column 


  • แสดงชื่อโปรแกรมที่เรียก  (ให้ใช้ ตัวแปรจาก I-spec ด้วย  SDS)
  • Description
  • วัน/เวลา ที่สั่งพิมพ์                วันที่ใช้ ตัวแปรพื้นฐานได้ *DATE
  • หน้า (page)           O-Spec มีตัวแปรให้
  • ชื่อ Column           (ขึ้นกับ data)

Tip  ใน RPG/400 กำหนด Font ชนิด Underline ไม่ได้   ต้องสั่งพิมพ์  2 ครั้ง  (อักษร, เส้นใต้)   มักจะใช้เทคนิคสั่งพิมพ์บรรทัดเดิม  (บรรทัดแรก  สั่งพิมพ์  โดย “ไม่ขึ้นบรรทัดใหม่” ->  บรรทัดที่ 2 ตีเส้นใต้  แล้วขึ้นบรรทัดใหม่)

ส่วนรายการ                         ขึ้นกับ data
ส่วนท้ายรายงาน                 บอกให้รู้ว่า  สิ้นสุดแล้ว (ถ้าไม่แสดง  ทำให้รู้ว่า  โปรแกรมหยุดทำงานแบบผิดปรกติ)
                                             บางโปรแกรมจะเพิ่ม  การแสดงสรุปที่จุดนี้  (จำนวนรวม)

ก่อนเขียน โปรแกรม

Q1: จะพิมพ์บน  รูปแบบกระดาษอย่างไร ?         (ยุคใหม่  คือ  กระดาษ A4)  
A1: เครื่อง Main Frame. Mini Comp จะมี  Line Printer ซึ่งพิมพ์ได้เร็ว และใช้งานได้นาน (แพงด้วย)  เช่น พิมพ์ pay slip, รายงานสรุป (ที่ต้องเก็บไว้อ้างอิง) เป็นต้น
      รูปแบบกระดาษ ของ AS/400 ที่มีมาให้คือ  QPRINT, QSYSPRT, QUSRPRT
      ดูรายละเอียดได้ด้วยคำสั่ง  DSPFD   QPRINT 
  (ปรกติจะดูช่องที่แสดง)
Q2: จะพิมพ์ตำแหน่ง อะไร ?  (ดูไม่ auto – ถ้าไปลองทำให้เหมือนใน MS Office ก็ต้องกำหนดยุ่งยากคล้ายกัน)
A2: การสั่งพิมพ์  ต้องควบคุมทีละ บรรทัด!   เช่น
         “เมื่อกระดาษ  พร้อมจะพิมพ์”   
         เริ่มต้นพิมพ์  ส่วนหัวกระดาษ  ให้เลื่อนกระดาษขึ้นไป  2 บรรทัด  ก่อนพิมพ์
         ส่วนหัวกระดาษ  ให้พิมพ์ข้อความ,ตัวแปร  ที่ตำแหน่ง ... (นับจากท้าย หรือ นับถัดไป)
         ส่วนหัวกระดาษ  พิมพ์บรรทัดแรกเสร็จ  ต้องพิมพ์ “ซ้ำ” อีกครั้ง   แล้วจึงขึ้นบรรทัดใหม่

Source Code



คำอธิบาย Source Code

Format ของ Date ใช้แบบ YYYYMMDD
ใช้ File=SQ010L1 ,Input = อ่านอย่างเดียว ,Field อ้างอิงจาก External      (ไม่กำหนดใน I-Spec) ,เปิดใช้ Key
ใช้ Printer File=QPRINT ,Output = บันทึกอย่างเดียว  ,Field กำหนดในเอง (ใน O-Spec)
     , 
ความกว้าง 132 อักษร, ใช้ *inOF เป็นตัวบอกว่าถึง OverFlow ของ Printer File แล้ว
     , ควบคุมการเปิด
/ปิด Printer File เอง (User Control)
ดึงชื่อ โปรแกรมผ่าน เป็นตัวแปร  (ไม่ต้องไป fix ค่าใน O-spec)
ประกาศ F-Spec … UC ต้องสั่ง OPEN ก่อนใช้งาน Printer File
ก่อนพิมพ์ HED010 (Skip Before) เลื่อนกระดาษ 3 บรรทัด

ก่อนพิมพ์ HED010 (Space Before) เลื่อนกระดาษ (0 บรรทัด)
หลังพิมพ์ HED010 (Space After) เลื่อนกระดาษ 1 บรรทัด (ขึ้นบรรทัดใหม่)
B = Blank ให้ Clear ค่านี้หลังพิมพ์
2= Edit Code(2) รูปแบบการพิมพ์  (มี comma, ไม่แสดงเครื่องหมาย -, ถ้าค่าเป็น 0 จะแสดงช่องว่าง, … (ดูตารางด้านล่าง)

 รายงานที่ดูจาก OutQ


สังเกต เนื่องจากใช้เทคนิค  พิมพ์ทับ 2 ครั้ง  หัวกระดาษจะมองไม่เห็น 
       (ทางแก้ไขคือ  พิมพ์เส้นใต้  "ก่อน"  พิมพ์อักษร)




วันพุธที่ 26 มิถุนายน พ.ศ. 2556

Subfile Advance 1

Sub-File Advance -1

อ่านข้อมูลจาก Sub-File

จาก ตย. ก่อนนี้ เราสร้าง Subfile Refer ได้แล้ว
บทความนี้เราจะปรับให้  Subfile Refer รับค่าได้

(ทบทวน) หลักการ

A. จะแสดงอะไร  (เช่น 3 Field, แสดงครั้งละ 10 row, เริ่มต้นที่ row ที่ 8)
B. นำข้อมูลไป ใส่ใน ข้อ A
C. จัดการแสดงผล

เมื่อเทียบกับ หลักการ เราจะปรับแต่ละหัวข้อ  ดังนี้
A.  กำหนดให้มี field    ที่ "รับค่า" (เลือก,ไม่เลือก)
B.  ค่าดังกล่าวใส่ไว้ใน  Subfile
C. (หลังจากแสดงผลแล้ว)  ทำการอ่านข้อมูลจาก Subfile (ตรวจว่ามีการ  เลือก หรือ ไม่)

เมื่อมีการเลือก (โดย  ป้อนค่า)  ใน sub-file  ให้นำค่าที่เลือก  ไปใช้งาน
(เช่น เปิดหน้าจอ  แสดงรายละเอียดเพิ่มเติม)
สิ่งที่ต้องทำ  เพิ่มเติม   มีดังนี้

A. กำหนดให้มี field    ที่ "รับค่า" (เลือก,ไม่เลือก)
     ส่วนการ deign
     ส่วน Code ที่เพิ่ม
B. ใส่ค่าดังกล่าวใส่ไว้ใน  Subfile
     เพิ่ม Code

C. (หลังจากแสดงผลแล้ว)  ทำการอ่านข้อมูลจาก Subfile (ตรวจว่ามีการ  เลือก หรือ ไม่)
เนื่องจาก Sub-file มีผลต่อหลาย rows
ทำให้  เราต้อง "ค้นหา" ว่า  มีการกระทำกับ row ไหน ?
หลังจาก Exfmt  ต้องเพิ่มขั้นตอน ดังกล่าว   กรณีนี้เราใช้ ReadC  (Read Next Change)

แต่เนื่องจากว่า  การป้อน แก้ไขใน Sub-file   รวมถึงการป้อน blank เข้าไปด้วย
ซึ่ง  เราจะเข้าใจตรงกันว่า  ป้อน blank คือ ไม่ได้เลือกอะไร
เพื่อจะแยกกรณีดังกล่าวจึงต้อง"ยกเว้น"  การเปลี่ยนแปลงที่  ป้อน Blank

สรุป

เมื่อเข้าใจหลักการ  การพัฒนาในขั้นต่อไป  ก็ปรับในจุดที่ต้องการ 



วันจันทร์ที่ 24 มิถุนายน พ.ศ. 2556

SubFile แบบง่าย

SubFile แบบง่าย

Subfile-Refer

SubFile เป็นการแสดงผลหลาย record ในหนึ่งหน้าจอ

เทียบกับ DotNet ก็คือแสดงผลแบบ GridView ครับ (แต่ GridView ง่ายกว่ามาก)

20 ปีที่แล้ว เป็นเทคนิคที่สุดยอดมาก  แต่  ณ.ปัจจุบัน เป็นงานพื้นฐาน (ต้องเขียนได้เร็ว)
แต่เนื่องจาก ยังต้องใช้เครื่องมือ (Tool) พื้นฐาน รุ่นเก่า  การสร้างจึ่งต้องมีขั้นตอน

ผู้เขียนโชคดีที่ได้อ่านเอกสารการเขียนโปรแกรมชุดหนึ่ง  (เอกสารจากญี่ปุ่น)
ได้อธิบายแนวทางที่ชัดเจน  สามารถนำไปประยุกต์ต่อได้  มาลองดูกันครับ

หลักการ Subfile (อีกแล้ว)

A. จะแสดงอะไร  (เช่น 3 Field, แสดงครั้งละ 10 row, เริ่มต้นที่ row ที่ 8)
B. นำข้อมูลไป ใส่ใน ข้อ A
C. จัดการแสดงผล

เตรียม data ที่จะใช้งานดังนี้

A. จะแสดงอะไรใน subfile (เช่น 3 Field, แสดงครั้งละ 10 row, เริ่มต้นที่ row ที่ 8)


a.1 รายละเอียดข้างต้น เป็นการกำหนดที่ Display-File
     อยากออกแบบแล้วแสดงผลแบบนี้  (แสดง 2 field, page ละ 4 rows)
     ออกแบบหน้าจอ  จะได้หน้าตาแบบนี้ (ใน STRSDA)
     การ Code ส่วน Sub-File จะระบุดังนี้
     เทคนิค - ใช้ Indicator ตัวเดียว คือ *IN55
     ในส่วน  "รับค่า" และข้อความ  ด้านบน  จะระบุ ถัดไปตามนี้
      การออกแบบ  แยกเป็น 2 record format
- ชนิด Subfile-Data     ใช้บอกโครงสร้าง File (คล้าย File/Field Description) =  SQ0110S1
- ชนิด Subfile-Control    ใช้กำหนด การแสดงผล (คล้าย File Description) = SQ0110C1
     Subfile อ้างอิงไปยัง Subfile Data อะไร
     Subfile Page จำนวนที่แสดงที่หน้าจอ เช่น 4
     Subfile Size  เลือกให้ค่าเท่ากับ Subfile Page หรือ Subfile Page +  1 ก็ได้ครับ
     Subfile End  เหมาะกับ ตย.นี้มาก (อ่านข้อมูลจนหมด)  
        ถ้ายังมีข้อมูลต่อ (next page) ให้แสดงเครื่องหมาย "+" ที่มุมขวาล่างของจอ
     Subfile Record Number ต้องระบุ "ตัวแปร" เพื่อติดต่อ
     กรณีนี้  เมื่อระบุ  ค่า row ใน page จะแสดงที่หน้าจอ page นั้น (เช่น SubFile Page = 4 เมื้อป้อน RRN = 6  Subfile จะแสดงใน page ที่ 2 เป็นต้น)


a.2 กำหนดใน F-spec ต้องประกาศ เพื่อเรียกใช้ Sub-file และระบุ RRN ให้กับมัน
      (ในระบบ DB2 ทุก file ต้องมี RRN กำกับ)


     สำหรับคนที่อยากเข้าใจ Code
     K = Continue Line
            SFILE = ประกาศจะใช้ Sub-File กับ Record Format (DSPF) = SQ0110S1
                     กำหนด RRN ให้กับตัวแปร RRN01 (ยังไม่ได้กำหนดขนาด)

B. นำข้อมูลไป ใส่ใน Subfile (ข้อ A)

b.1 reset ก่อนใช้งาน
      ใน DSP-F เราใช้ *IN55 ควบคุม  การแสดงผล กับ reset (delete)
      RRN01 (อ้างอิงจาก F-Spec) ขนาด 4,0  เริ่มต้นมีค่าเป็น 0 (ไม่มีข้อมูล)


b.2 Loop  อ่านข้อมูลใส่ใน A
      จุดสำคัญ   ต้อง  เพิ่ม RRN ให้ทุกครั้งที่ write Subfile-Data

C. คำสั่งแสดงผล Subfile

แต่เนื่องจาก Subfile มีข้อมูลหลาย rows
การดูผล ก็ใช้ page up/down ได้ หรือ  เลือกการแสดงผลไปที่ page ใดก็ได้ โดยระบุ บรรทัดที่ (RRN)
เช่น  ต้องการให้แสดงที่ page ที่ 2 (RRN= 5 ถึง 8)


หลายคนอาจจะมองว่า จัดแบบนี้ดูแปลกๆ
ในบทต่อๆไป  การจัดแบบนี้จะช่วยให้เรา "ปรับ" แต่งได้ง่ายครับ

สรุป

จะเห็นว่า  หลักการเข้าใจนาน  แต่โปรแกรมเขียน "ไม่มาก"!
ส่วนหนึ่งเกิดจาก การ "ลด" ตัวแปร ทำให้จัดการ "ง่าย"
ถ้าทำบ่อยๆ จะใช้เวลาไม่นาน (ผู้สอน  มักจะสร้างใหม่เพื่อสอน  แทนการเปิดให้ลอก)



วันพุธที่ 12 มิถุนายน พ.ศ. 2556

Tips:ใช้ PSDS และ INFDS

PSDS และ INFDS  เป็นวิธีการดึงค่าจาก memory ขณะ run มาใช้งาน
แยกเป็น ข้อมูลของ Program กับ ข้อมูลของ File (แต่ละตัว  ต้องระบุ)

PSDS = Program status data structure

ประกาศ SDS ใน I-Spec



ตย. สไตล์การเขียน Report ใน RPG มักจะแสดงชื่อโปรแกรม  ที่มุมบนซ้าย หรือ ขวา
      (เพื่อให้รู้ว่า report นี้มาจากโปรแกรมตัวไหน)  วิธีพื้นฐาน  ก็คือ Fix ค่าใน O-spec เช่น

      code ทั่วไปจะเป็นลักษณะนี้
OQSYSPRT E  2 3           HED010                     
O                                    7 'PG0160R'   

      เคยพบมั๊ยครับ  copy/เปลี่ยนโปรแกรม เป็น PG0161R แล้วลืมเปลี่ยนชื่อตาม
      ???  เวลาตรวจสอบโปรแกรม "ผิดตัว" ทำให้ "เสียเวลามาก" ... แป่ว

ทางแก้ไข   ทำให้เป็น  ตัวแปรซะ  (แล้วทุกครั้งที่เขียนโปรแกรมใหม่  ให้  copy ไปใช้)  ประกาศดังนี้
I           SDS                                      
I                                     *PROGRAM PGMID
I                                      244 253 JOBNAM
I                                      254 263 USR
I                                      264 269 JOBNBR
...
OQSYSPRT E  2 3           HED010                     
O                         PGMID     10 

เราสามารถเพิ่ม  รายละเอียดที่จำเป็น (ในด้าน Securityได้)
เช่น ข้อมูลที่บ่งบอกว่า job อะไรที่เรียกใช้ report

    JOBNAM = ชื่อ Job ที่ทำงานใน iSeries เช่น ชื่อจอ เป็นต้น
    USR = ชื่อ User ที่ Log On เข้าใช้ใน iSeries เช่น  SOMCHAI เป็นต้น
    JOBNBR = run no (มักใช้แยก  กรณีที่ User 1 คนเข้าใช้งาน  )

วิธีประกาศใน RPG-ILE (แตกต่างเล็กน้อย)
D          SDS
D  PROC_NAM    *PROC
D  JOB_NAME    244   253
D  USER        254   263

Keyword อื่นๆที่น่าสนใจ  - (บทความใน internet จะพูดถึงตัวนี้กันมาก)
*STATUS  ใช้ดักจับ Error (คล้าย Try ...Catch ... ใน Dot Net)
ใช้เพื่อดักจับปัญหา  โปรแกรมที่จะเกิด Dump
เช่น อ่านข้อมูล  ชนิด "ตัวเลข"  แต่บางครั้ง  อาจจะพบ อักษรติดเข้ามา (มักพบใน data transfer)
หรือ การอ่านข้อมูลเพื่อ update แต่โปรแกรมอื่น lock record ไว้
Refer
http://publib.boulder.ibm.com/iseries/v5r1/ic2924/books/c092508381.htm
http://wiki.midrange.com/index.php/Program_Status_Data_Structure


INFDS = File Information data structure

ประกาศ  INFDS ใน F-Spec และ I-Spec (เรียก Feedback areas)
INFDS เองจัดกลุ่มข้อมูลไว้ 5 แบบ (ทำให้เลือกใช้ง่ายขึ้น) ได้แก่ File,Open,Input/Output,Device,Get Attribute  ในที่นี้จะเลือก,แนะนำบางตัวที่ควรใช้บ่อยครับ


ตย. สร้าง sub-file Select ไว้มีข้อมูล    5 page
เมื่อ User เลือกตัวเลือก ใน page ที่ 3  แล้วให้โปรแกรม  ไปแสดงผล DSPFW2
เมื่อ DSPFW2 ทำงานเสร็จ  ต้องการให้   ให้กลับไปที่ Page ที่ 3
        ... ถ้าไม่ควบคุม  ตำแหน่งที่แสดงผล จะไปอยู่ที่ page แรกหรือสุดท้าย
        >> code ด้านล่าง  เป็นการเก็บค่า sub-file RRN ไว้  แล้วนำมาบังคับแสดงผล


ตย. Display File : MYDSPF
A          R MYDSPFC1                  SFLCTL(MYDSPFS1) 
...
A            S1RRN1         4S 0H      SFLRCDNBR

ตย  RPG เรียกใช้ INFDS กับ Display File
FMYDSPF CF  E                    WORKSTN      KINFDS WSID 
...

   กำหนด Data Structure เพื่อดึงค่า
IWSID       DS
I                                    B 370 3710CURLOC
I                                    B 376 3770CURRRN
...
C           STP010    TAG
C*          -------------            
C                     EXFMTMYDSPFC1
...                       Select -> show DSPFW2
C                     Z-ADDCURRRN    S1RRN1
C           CURLOC    DIV  256       CURROW
C                     MOD            CURCOL
C*                    ---F4 => *IN04 = '1'
C     04    CURROW    IFEQ 12
C           CURCOL    IFGE 15
C           CURCOL    ANDLE25
C                     EXSR ITEMREF
C                     END

C           CURCOL    IFGE 30
C           CURCOL    ANDLE40
C                     EXSR TERIREF
C                     END
C                     END

C                     GOTO STP010
...


ตย. การสร้าง Help, Prompt จากตำแหน่ง Cursor
ถ้าวางอยู่ตำแหน่ง  Row=12, Col. ระหว่าง   15-25  เมื่อกด F4 = Item No Refer
ถ้าวางอยู่ตำแหน่ง  Row=12, Col. ระหว่าง   30-40  เมื่อกด F4 = Teritory Refer


... หลังแสดงหน้าจอ
ตัวแปร CURRRN จะเก็บตำแหน่ง  RRN ที่เลือกไว้ทำให้เรารู้ว่า User เปิด SubFile Page ไหนล่าสุดไว้ได้
ตัวแปร CURROW,CURCOL จะเก็บตำแหน่ง Cursor สุดท้าย  (ROW,COL) ไว้
(ถ้าเป็น RPGILE ไม่ต้องมา  หาร 256  ดึงค่าได้โดยตรงครับ)

Refer
http://www.ilerpgprogramming.com/2010/11/exploring-program-status-and-file.html