วันพุธที่ 22 กรกฎาคม พ.ศ. 2558

Tip:SQL Read File (many Member)

Tip:SQL Read File (many Member)

CREATE ALIAS    QTEMP.myALIAS    FOR     LIB.QRPGSRC (PGM1)
SELECT   QTEMP.myALIAS
DROP ALIAS      QTEMP.myALIAS

File ใน DB2/400  (มีโครงสร้าง พิเศษ) สามารถจัดเก็บ 1 File ได้หลาย Member

ตย. Source Code (เช่น QRPGSRC, QDDSSRC)  ที่เก็บ RPG, Physical,Logical,Display File
ตย. File ที่ IBM มักจะแนะนำให้ใช้  คือ  File Monthly แยก Member ตาม ปี/เดือน เป็นต้น
       (ไม่เหมาะกับ SQL)

คำสั่งมาตรฐาน SELECT  ไม่มี  Syntax ที่ใช้อ้างอิง โครงสร้างพิเศษ ข้างต้น
ต้องสร้าง  object  ที่ระบุ Member เจาะจง   รู้จักกันในชื่อ   ALIAS

ชุดคำสั่งข้างบน ทำให้อ่าน Member ที่เจาะจงได้
(เรียกใช้งานได้ใน iSeries Navigator)

ตย. ใน DotNet : ต้องการสร้าง Class เกี่ยวกับ Database โดยสร้างจาก DB2
       ณ.วันนี้ (2015/07/23)  ยังไม่มีเครื่องมือช่วยสร้าง

       บน DB2        LIB.QDDSSRC  (myFile)  จัดเก็บลักษณะนี้

              R  MYFILER1
                 FLDA        10    COLHDG('FIELD-A')
                 FLDB         8    COLHDG('FIELD-B')
                 ...  
                                  มีประมาณ 30-50 field

       บน  DotNet  ต้องสร้าง  code ลักษณะนี้ (ตย. แบบย่อ)

              Class myFILE
                  Property  FLDA  as  String
                  Property  FLDB  as  String
                  ...

                  Sub GetData  (byVal myID as String)
                      '...SQL to DataTable
                      Loop  Data Table
                           FLDA = dt.FLDA
                           FLDB = dt.FLDB
                           ...
                      End loop
                  End Sub
              End Class

               ถ้าต้องทำ  1-2  File - เปิด Editor แล้ว Copy / Paste  เร็วที่สุด
               แต่ถ้าต้องทำ มากกว่า  5 file แต่ละ File มี Field มาก     ลองสร้าง Tool
               สังเกต  Code สีชมพู  (ที่มีลักษณะแน่นอน)

Code สีชมพูดในส่วนที่ 2 ทำง่ายกว่า ครับ

Select srcdta
      ,substr(srcdta,19,6) || ' = dt.' || substr(srcdta,19,6)
From qtemp.myAlias 
Where substr(srcdta,7,1)<>'*' and substr(srcdta,17,1)=' ' 
  and substr(srcdta,19,6)<>'      '

SQL Result
     A            MXOPEC         2          COLHDG('OPEC CODE')                  MXOPEC = dt.MXOPEC
  ++ A            MXCOMC         1          COLHDG('COMC CODE')                  MXCOMC = dt.MXCOMC

Code สีชมพูดในส่วนที่ 1 เพิ่มรายละเอียด ครับ
Select srcdta
      ,' Property ' || substr(srcdta,19,6)
       || Case Trim(substr(srcdta,36,2)) 
             When '  ' Then ' As String'
             Else ' As Float'  End 
       || ' '' ' 
       || Replace(Replace(Trim(substr(srcdta,44,30)),'COLHDG(''',''),''')','') 
From qtemp.myAlias 
Where substr(srcdta,7,1)<>'*' and substr(srcdta,17,1)=' ' 
  and substr(srcdta,19,6)<>'      '

SQL Result
     A            MXTYCD         5          COLHDG('TYPY CODE')                 Property MXTYCD As String ' TYPE CODE
  C  A            MXTYPE        25          COLHDG('TYPY')                       Property MXTYPE As String ' TYPE
     A            MXWEIT         7  3       COLHDG('WEIGHT')                     Property MXWEIT As Float ' WEIGHT
     A            MXODOW         7  4       COLHDG('O/W')                       Property MXODOW As Float ' O/W

Reference
http://search400.techtarget.com/tip/Using-SQL-on-System-i-to-color-source-code-and-inline-comments

วันอังคารที่ 14 กรกฎาคม พ.ศ. 2558

Download Spool File to PC

Download iSeries : Spool File to PC

เป็นงานประเภทหนึ่ง ที่ต้องทำกัน  มีทางเลือกในการทำหลายแบบ  เลือกตามความถนัดครับ

1. ใช้ iSeries Navigator  ลาก  แล้ววางลง Folder เลย
2. ใช้ CPYTOIMPF
3. เขียนโปรแกรม

1. ใช้ iSeries Navigator  ลาก  แล้ววางลง Folder เลย

    a. เปิด iSeries Navigator 
    
 
    b. เลือก iSeries (AS/400, Server) กรณีที่คุณมีหลายเครื่อง
    

    c. เปิด OutQ ที่เก็บ Spool
        AS/400 (Server) > Basic Operation > Printer Output
        * OutQ ที่เห็น  จะ *Default  ตาม UserProfile ที่ Sign On
    
        เปิดดู Spool    โดย Double Click หรือ Right click > Open

         Drag (ลาก) Spool File ที่ต้องการ  Drop (วาง) ไปที่ PC:Desktop หรือ Folder ปลายทาง
         หรือ Spool File + Right Click > Copy   แล้วไปที่ Folder + Right Click > Paste

         ถ้าต้องการเปลี่ยน OutQ
              Printer Output + Right Click > Customize this View > Include > ป้อน OutQ ที่ต้องการ
         

        สังเกต  เลือก Spool File + Right Click > มีตัวเลือก Convert to PDF

2. ใช้ CPYTOIMPF

    ขออภัยครับ  ผมแสดงให้ดูไม่ได้   (เข้าใจว่า) ที่ AS/400 ต้องซื้อ (ติดตั้ง) Integrate File System  (โหมดที่เปลี่ยน AS/400 เป็น Folder ที่ PC ทั่วไปมองเห็น)  หลายคนจะคุ้นเคยกับชื่อ copy document

3. เขียนโปรแกรม  

    โดยใช้เทคนิค Copy Spool File เป็น Physical-File ก่อน แล้วจึง Download ลงมาผ่าน ตัวเลือก (บน Client Access) หรือ RTOPC cmd
ตย. 
    0. สร้าง WorkFile  
CRTPF FILE(SARAYUT/A)      RCDLEN(200)   
    1. CPYSPLF FILE(QSYSPRT) TOFILE(SARAYUT/A) JOB(241844/USNADS/QPRTJOB
        ระบุ  Spool File ต้องระุบ   เต็ม  Spool file name +  (Spool File No.) +  Job No/User/Job
    2. คำสั่ง download  to PC
        จาก Client Access  (ใช้เพื่อสร้าง โครงสร้าง .fdf ก่อนเขียนโปรแกรมเรียกใช้)
        จาก Start > program
        จาก Command  (เขียน Batch โปรแกรมได้)










วันอังคารที่ 16 ธันวาคม พ.ศ. 2557

รวม DB2 SQL Technique

รวม DB2 SQL Technique


  • ตรวจค่าเป็น Null
  • เลือกแสดงข้อมูลชุดแรก เช่น 10 แถวแรก
  • เพิ่ม col. RunNo หรือ Sequence
  • อ่าน BOM File
  • iSeries Navigator : เรียกใช้ CL command

ตรวจค่าเป็น Null

ปรกติใช้  ตรวจหลัง Join (ไม่พบ จะได้ค่า  Null)
ซึ่งมักจะพบกับการใช้  LEFT JOIN     (ไม่ใช่  LEFT INNER JOIN)

กรองค่าด้วย
WHERE   field1 IS NULL
WHERE   NOT   field1   IS NULL

ตรวจสอบค่า เขียนได้หลายแบบ

IFNULL(field1,0) as field1
ถ้าเปลี่ยนเป็น T-SQL ใช้  Coalesce(field1,0) as field1

หรือ เขียนแบบ"ยาว"
CASE WHEN    field1 IS NULL   THEN   0   ELSE   field1  END  AS field1

เลือกแสดงข้อมูลชุดแรก เช่น 10 แถวแรก

SELECT   field1,field2    FROM    lib.file   FETCH FIRST 10 ROWS ONLY

เพิ่ม col. RunNo หรือ Sequence

SELECT    field1,field2 ,ROW_NUMBER() OVER () as Seq    FROM  lib.file   ORDER BY field1

      field1    field2
      A         aaa
      B         bbb
      C         ccc
      D         ddd
      E         eee

เลือกแสดงข้อมูลชุดแรก เช่น 10 แถวแรก
SELECT   field1,field2    FROM    lib.file   FETCH FIRST 10 ROWS ONLY
หรือ
SELECT   * FROM
(SELECT    field1,field2 ,ROW_NUMBER() OVER () as Seq    FROM  lib.file   ORDER BY field1
) as F1
WHERE   Seq < 10

seq   field1    field2
1     A         aaa
2     B         bbb
3     C         ccc
4     D         ddd
5     E         eee

เลือกแสดง  10 ตัวถัดไป  (Top 10)
SELECT   * FROM
(SELECT    field1,field2 ,ROW_NUMBER() OVER () as Seq    FROM  lib.file   ORDER BY field1
) as F1
WHERE   Seq > 10

อ่าน BOM File

BOM ปรกติต้องสร้าง File/Field ในลักษณะนี้
Parent Child
A a1
A b1
A c1
A d1

a1 a21
a1 a22
c1 c21
c1 c22

c21 d1 (ใช้ d1 ซ้ำ)

BOM File จะต้องแสดงผลอย่างน้อย 2 แบบได้
#1 แสดงโครงสร้าง
lvl-0 lvl-1 lvl-2 lvl-3
A a1 a21
a22
b1
c1 c21 d1
c22
d1

SQL ธรรมดา  จะไม่สามารถ  แสดงแบบข้างต้นได้

#2 แสดง  การใช้วัตถุดิบ รวม (ข้อมูล Node สุดท้าย ของแต่ละโครงสร้าง)
lvl-0 รวมวัตถุดิบ
A a21
a22
b1
d1 (รวม 2 ตัว)
c22

SQL ธรรมดา  จะไม่สามารถ  แสดงผลได้

ตย. การสร้างให้ผลลัพธ์  ของสินค้า "A"  พร้อมที่จะนำไปใช้กับ  #1

WITH   RPL(level, fParent, fChild, Path) AS
  (      SELECT 1, fParent  ,fChild  ,TRIM(fParnet) || '\ ' || xChild as Path
          FROM   lib.file   AS  root
          WHERE   fParent='A'

         UNION ALL

         (   SELECT xParent.level+1, xChild.fParent, xChild.fChild
, Trim(xParent.Path) || '\ ' || xChild.fChild   as Path
              FROM  RPL  as  xParent

          INNER JOIN  
(SELECT fParent, fChild  FROM   lib.file 
                         WHERE  fParent  <>  'A'
                ) xChild
             ON xParent.fChild = xChild.fParent  
          )
  )
SELECT  fParent, level, fChild  ,Path   FROM RPL  ORDER By Path;

ผลลัพธ์
Parent Level Child Path
A 1       a1      A\a1
a1 2       a21     A\a1\a21
a21 3 a22     A\a1\a21\a22
A 1 b1      A\b1
A 1 c1      A\c1
c1      2 c21     A\c1\c21
        c21     3 d1      A\c1\c21\d1
c1      2 c22     A\c1\c22
A 1 d1      A\d1

คำอธิบาย
- ใช้  เทคนิค กำหนดตัวแปร  WITH
        RPL( .. , .. ,.. ) ตัวแปร ชนิด data set (ไม่ใช่ ค่า)
- ใช้  เทคนิค Recursive (เรียกตัวมันเอง)  RPL ถูกเรียกใช้ในตัวมันเอง
มี 2 ชุด
- ตัวแรก เฉพาะ Main Root ออกมา ต้องระบุ  ค่าที่จะค้น
- ตัวที่ 2  จะเรียกใช้  "ตัวมันเอง"
- Path ช่วยในการเรียง และเห็นภาพ

iSeries Navigator : เรียกใช้ CL command

เทคนิคนี้ Developer ที่ทำหน้าที่ Admin ด้วย  จะใช้งานบ่อยครับ
สั่ง CL Cmd แล้วให้แสดงผลลัพธ์เป็น file แล้วนำมา process ต่อ
ตย. ต้องการดู file  10 ตัวแรกใน Lib = Sarayut


วันอังคารที่ 29 กรกฎาคม พ.ศ. 2557

Tip การเขียน SQL กับ DB2

Tip: กับการเขียน DB2 

ผมพบปัญหาว่า  SQL แล้วเครื่องทำงาน  "ช้า"
สิ่งแรกที่ผมจะทำคือ  ปรับ SQL    ถ้ายังไม่ดีขึ้น จะสร้าง Index, L-File

ตัวอย่างวันนี้   ผมสงสัยกับการเขียน SQL แบบต่างๆ มีผลต่อความเร็วหรือไม่ ?
File ที่มี Field = Y,M,D  แยกกัน  (พบบ่อย ในระบบที่สร้างมานาน)
มักจะสร้าง Logical-File  ที่มี Key แบบนี้  Y,M,D

Q: การเขียน SQL Statement แบบไหน  ทำงานเร็วที่สุด
(1) sql ...    เขียนตาม หลักการข้างต้น
and Y = wFromY and M =wFromM and D>= wFromD
and Y = wToY and M =wToM and D<= wToD

2)  ...sql...
       and (Y = wFromY and M =wFromM and D>= wFromD)
and (Y = wToY and M =wToM and D<= wToD)

3)  ...sql...
and Y|| M || D >= wFromY || wFromM || wFromD
and Y|| M || D <= wToY || wToM || wToD

ใคร เลือกข้อ 1)  เขียนผิดน๊ะครับ ลองทดสอบข้อมูล  ดูในช่วงนี้ 2014/06/25 - 2014/07/02

ตัวผม  มักเลือก ข้อ 2)
เพราะเคยอ่านคำแนะนำพบว่า  การสร้าง Field ใหม่ DB Engine จะทำงาน "หนัก"

เพื่อลดข้อสงสัย ก็ต้องใช้  Visual Explain ตรวจดู
>> ข้อ 3  ทำงานเร็วกว่า ข้อ 2  ... ดูจาก Total Estimate Run Time

Visual Explain ของ SQL ข้อ 2


Visual Explain ของ SQL ข้อ 3

คำอธิบาย (แก้ตัว) ที่ดีคือ
DB Engine จะทำการแปล SQL แล้วเลือก  วิธีที่เร็วที่สุด   โดยการเปรียบเทียบกับกรณีต่างๆ
นับเป็นรายละเอียดที่  เข้าใจยาก ....
แต่ทดสอบ  การเดาผ่าน Visual Explain ได้

ถ้าไปสัมนากับ IBM เขาจะแนะนำว่า  Table (File) ที่จำนวน rows มาก
, มีความหลากหลายมาก ควรสร้าง Index (L-File)    ควรสร้าง Index File

จากภาพ Visual Explain   มุมขวาล่าง Table Scan (= การอ่านตามลำดับ ก่อน/หลัง)
เมื่อกดเลือก  ด้านขวาจะให้ข้อมูล  และ แนะนำ
- File ตัวนี้ใหญ่  มี 3 ล้าน Rows ,  เพื่อความเร็ว  ควรสร้าง Index File
>> ถ้าผมต้องการให้เร็วขึ้น  ก็ต้องสร้าง L-File แล้วครับ



วันอังคารที่ 27 พฤษภาคม พ.ศ. 2557

ดัก ErrorMsg ป้องกัน Dump กัน

ดักจับ ErrorMsg กัน

บางครั้ง โปรแกรมเมอร์  มักพบปัญหาที่คาดไม่ถึง "ชนิดยาก"
เช่น Error เกิดขึ้นตอนกลางคืน (ขณะทดสอบอย่างหนัก ไม่ยักพบปัญหา) เป็นต้น

การดักจับ Error (handler) เทียบกับภาษาอื่น
- ใน CL  คือ  MonMsg
- ใน .net  คือ Try .. Catch ...

การดักจับ Error ใน RPG มีได้ 4 วิธี


  • ใช้ Error indicator หรือ an 'E' operation code extender 
  • ใช้ MONITOR group
  • ใช้ Error subroutine 
  • ใช้ Default exception



แต่ละวิธี  มีจุดเด่น/จุดด้อย ต่างกัน  คนที่สนใจไปอ่านเพิ่มได้ครับ
วันนี้เราจะมาพูดถึงตัวที่   ทำง่าย ที่สุด นั่นคือ  Error Subroutine ครับ

เพียงแค่ประกาศ  เพิ่มส่วนนี้
CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEq
C*=================================
C           *PSSR     BEGSR                        
C*-------------------------
C**
C                     SETON                     LR 
C   LR                RETRN                        
C                     ENDSR                        
C*=================================

ประยุกต์ อื่นๆ
- ให้ทำงานต่อ หรือ หยุด  หรือ ทำ Rollback (อันนี้ผมไม่ได้ใช้)
- ให้ ส่งค่าตัวแปร  กลุ่มที่อยากรู้ออกมา เช่น ใช้คำสั่ง  DSPLY
- ให้ ส่งสถานะ  ตำแหน่งที่มีปัญหา,ชื่อ Error   (ตัวแปรจากระบบ)
IDsname....NODsExt-file++.............OccrLen+..........
I           SDS                                     
I                                     *ROUTINE ELOC 
I                                     *STATUS  ESTS
I                                        1  10 PPGMID
I                                       11  150PSTS  
I                                       21  28 PLINE  

Note ถ้าใช้ RPGILE จะมี ตัวช่วย ให้เลือกมากกว่านี้

การทดลอง
รู้แล้ว ควรจะทดลองซะหน่อย ครับ

1.  เขียนโปรแกรมสั้นๆ      1 หารด้วย 0   

C           100       DIV  0         J#      30   
C                     SETON                     LR
C   LR                RETRN                       

     สั่ง run  ... จะเกิด Error ดังนี้
xxxx 900 tried to divide by zero (factor 2) (C G S D F).

    ให้ตอบ Msg เป็น "D" = dump  เราจะได้ Spool  และเห็น  ค่าตัวแปรต่างๆ ณ. จุดที่เกิด Error

RPG/400 FORMATTED DUMP                                         
Program Status Area:                                           
Program Name . . . . . . . . . . . . . :   QTEMP/xxxx        
Program Status . . . . . . . . . . . . :   00102               
                tried to divide by zero (factor 2) (C G S D F).
Previous Status  . . . . . . . . . . . :   00000               
Statement in Error . . . . . . . . . . :   900                 
RPG Routine  . . . . . . . . . . . . . :   *DETC               
Number of Parameters . . . . . . . . . :   001  

...

*...+....1....+....2....+....3....+....4....+....5....+....6....+
 ZIGNDECD 0603C4  CHAR(1)       '0'                             
 ZPGMSTUS 05FDF6  CHAR(400)     'XXXXXX    0010200000900     
          05FE55    +96         '                            
          05FEB4    +191        '        20                  
          05FF13    +286        '380528141106300001QRPGSRC   

    Note ตำแหน่ง ค่าต่างๆในตัวแปร ดูได้ที่ ZPGMSTUS
    Note ค่าใน Spool หลายตัว ส่งผ่านเป็น  ตัวแปร  นำมาใช้งานได้  ESTS กับ PSTS เป็นค่าเดียวกัน


วันอาทิตย์ที่ 9 กุมภาพันธ์ พ.ศ. 2557

5 ทักษะที่ ควรมี

ผมได้ไปอ่านบทความ  ที่  http://search400.techtarget.com
คือ 9 ทักษะที่ควรมี  (ในสายงาน RPG)
แต่ผมปรับเนื้อหาให้เหมาะกับ  สภาพแวดล้อมที่ผมเห็น การเปลี่ยนแปลงในองค์กรมาให้ดู

RPG โปรแกรมเมอร์ที่ทำงานมานาน  จะคุ้นเคย (และรู้สีกดี) กับสภาพแวดล้อมที่ปิด(จำกัด)
(จำน้อยๆ  ทำอะไรมากไม่ได้   กลายเป็นไม่จำเป็นต้องทำอะไรมาก ด้วย)

แต่ในความเป็นจริง  Application ในภาษาอื่นๆ มีจุดเด่นมากขึ้น
และ User ก็ได้เห็น (เปิดโลกไปแล้ว)  ทำให้เราหลีกหนีไม่ได้

สำหรับ  สายงาน RPG ผมแนะนำให้รู้  Skill ดังต่อไปนี้ครับ (ช่วงเริ่มต้น)
ซึ่งจะทำงาน  ของคุณ  "ง่ายขึ้น" (เรียนรู้ + ฝึก   แล้ว นำมาใช้ได้เลย)  ดังต่อไปนี้
1. SQL
2. DB2/400
3. RPG IV 
4. ใช้ Tool : Code/400
5. ใช้ Tool : iSeries Navigator 


1. SQL 
    พนักงานรุ่นใหม่ ถูกสอนให้ใช้  SQL ในการติดต่อกับฐานข้อมูล
    ดังนั้น  เพื่อให้คุยกับเขารู้เรื่อง  ก็จำเป็นต้องใช้  เหมื่อนกันครับ  
             ควรรู้สิ่งดีๆ เหมือนคนรุ่นใหม่  มากกว่าให้คนรุ่นใหม่ มาหัดใช้วิธีเก่า/ช้ากว่า

    ควรใช้  Run SQL Script  ใน   iSeries Navigator 
    - จัดเก็บ แยก SQL ที่ใช้บ่อยได้   เช่น SQL ที่ใช้หา  ความผิดปรกติของ data

2. DB2/400    หลายคนแค่เรียนรู้ว่า  ใช้อย่างไร ? (และจำกัด)
    แต่ในความเป็นจริง DB2 มีหลักการดีๆ  ที่เกิดขึ้นก่อนเจ้าอื่นๆ  
    เพียงแต่ใน RPG ยุคแรกๆ ไม่ได้ใช้งาน
    >> ควรอ่าน เทียบกับ Std Database (พร้อมจะอ้างอิง, ใช้ กับ Database อื่นได้)




3. RPG IV   
    เริ่มเขียนในสไตล์นี้   ibm พยายามให้ทีมงานเดิมสามารถปรับเปลี่ยนได้  โดยการเปลี่ยนทีละน้อย  ข้อดีก็คือ  จะรู้สึกไม่ยาก (เมื่อเทียบกับไปเรียนภาษาใหม่)

    -Sub procedures    
     ใน RPG-II,III  เรามักจะเขียนต่อเนื่องกันไป (Top-Down) และใช้ Goto  เป็นหลัก
     ทำให้อ่าน code ยาก  ตั้งแต่ RPG IV แทบทุกอย่างจะเขียนแบบ Sub-Procedure

    -Integrated Language Environment (ILE)
     RPGILE เป็น  อีกระดับของ RPG ที่  "เปิด" กว้างในการติดต่อกันระหว่าง Application
     ทำให้เราข้ามขีดจำกัดของแต่ละภาษา   เช่น  ติดต่อกับโปรแกรม Java ได้

4. ใช้ Tool : Code/400   
    เป็นโปรแกรมที่อยู่ใน WDSC WebSphere Studio แล้ว  (ติดตั้งจาก CD ที่ได้มา   ติดตั้งบน Windows)
    ทำให้การเขียนโปรแกรม  ได้เร็วและง่ายขึ้น  (มีคนสรุปว่า เร็วขึ้นมากกว่า 20%)
    คิดเล่นๆ  - นำ code กลับไปทำที่บ้าน หรือ offline ได้  (compile ไม่ได้)
                   ช่วยในการ  ร่างโปรแกรม (draft)

5. ใช้ Tool : iSeries Navigator หรือ System i Navigator
    เป็นเครื่องมือพื้นฐานที่ติดตั้งมาบน CA/400 (Client Access/400) 
    -Operations Navigator       เดิม   เราต้อง "จำคำสั่่ง"  ในการจัดการต่าง  แต่ด้วยตัวนี้มองผ่านภาพ,กลุ่มคำ  แล้วเลือก  (ในสไตล์ windows)  ทำให้ใช้งานได้ง่ายกว่ามากครับ   เหมาะกับคนที่จำคำสั่งได้เล็กน้อย
    -Databases function          ต่อเนื่องจาก ข้อ 1  ครับ


ในบทความพูดถึง  การมีทักษะกับ  The Integrated File System (IFS)
แต่ผู้เขียน  ไม่ได้ทำงานกับงานลักษณะนี้  จึงขอบายครับ

Tips เพิ่มความเร็วใน Code-1

คำเตือน - Tips บางเรื่อง  เหมาะกับบางเหตุการณ์ น๊ะครับ
ผมพยายามจะ  บอกว่า  มัน "น่าทำ" ใน เหตุการณ์ไหน ? 
ดังนั้น  อย่าท่อง  "แบบย่อ"    ถ้าใช้ผิดเรื่อง อาจทำให้  งาน "ช้าลง" ได้ครับ

A. ลด Condition
     ที่มา   การทำงานแบบ Cond จะต้องใช้  "CPU มาก" (คนอ่าน Code ก็อ่านยาก)
               การเขียน  RPG ทั่วไปจะเขียนสั้น  ไม่ใช่ Structure  ทำให้ต้องแยกเป็นชิ้น

 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.
C           W1SEL      COMP 'A'                      31 ADD
C           W1SEL      COMP 'C'                      32 CHG
C           W1SEL      COMP 'D'                      33 DEL
 *...
C           KG122      CHAINPG010L2              80      
C    31     *IN80      CABEQ'0'                      41 ERR 
C   N31     *IN80      CABEQ'1'                      42 ERR

     ตย. ข้างต้น   ในทุกรอบ จะต้องผ่าน 5 Condition

     เมื่อเปลี่ยนมาแบบนี้  จะทำงานเร็วกว่า (ผ่าน 2 - 4 Condition)
 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.
C           KG122      CHAINPG010L2              80      
C                      SELEC
C           W1SEL      WHEQ 'A'                      
C           *IN80      CABEQ'0'                      41 ERR 
C           W1SEL      WHEQ 'C'                      
C           *IN80      CABEQ'1'                      42 ERR
C           W1SEL      WHEQ 'D'                      
C           *IN80      CABEQ'1'                      42 ERR
C                      ENDSL

B. อ่านได้เร็ว และ เข้าใจง่ายขึ้น
    แทนที่  การกำหนดค่ายาวๆ  ด้วย  Constance  

    ในภาษาใหม่  เรามักกำหนด  constance ไว้ด้านบน  (ทุกคนจะเห็นผ่านตา  ก่อนทำงาน)
    แต่ใน RPG   การกำหนดค่าที่ยาวๆ    มักจะใช้ Array ซึ่งต้องประกาศไว้  "ท้าย" โปรแกรม

    โดย  กำหนดตัวแปร  Constance ใน I-Spec   (ต้องประกาศไว้ด้านบน)
    ตย. ต้องการ  ตรวจว่า  มีอักษรไหน ไม่ใช่ ตัวเลข  ใน String หรือไม่ ? เริ่มตรวจที่ตำแหน่งที่ 3
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6
I*    field Data for CHECK                             
I            DS
I              '0123456789'          C         DIGITS  
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6
C*                    -----CHECK *all is DIGITS        
C                     MOVE 'xx123z5' STRING 7         
C           DIGITS    CHECKSTRING:3  RESULT 30      80
C*                ==> result = 6  found *in80='1'