ผมได้ไปอ่านบทความ ที่ 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)
แต่ผู้เขียน ไม่ได้ทำงานกับงานลักษณะนี้ จึงขอบายครับ
วันอาทิตย์ที่ 9 กุมภาพันธ์ พ.ศ. 2557
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'
แทนที่ การกำหนดค่ายาวๆ ด้วย 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'
วันเสาร์ที่ 8 กุมภาพันธ์ พ.ศ. 2557
จะทำ Security กับ File อย่างไร ?
จะทำ Security กับ File อย่างไร ?
ในระบบที่สร้างมานาน กับบริษัทฯ ที่ไม่กังวลเรื่องความปลอดภัยเช่น โรงงาน ,บริษัท(ที่ไม่ใช่ ธนาคาร,ประกันชีวิต)
การออกแบบ กับ Security มักจะออกแบบให้ ง่าย ไว้ก่อน
เนื่องจาก Security จะทำให้ดี ต้องรู้จริง และ วางแผน (ทั้ง องค์กร, วิธีทำงาน และ IT)
ในอดีต ไม่มีใครสนใจ และไม่มีใครตรวจ
การทำ Security อาจจะอยู่ในรูปแบบ
- Lock ด้วย IT ที่ประตูทางเข้า UserProfile
- ห้าม! ด้วย วาจา, ประกาศเป็นกฏ (ต่างๆ)
- (ยังเชื่อใน) ความไว้วางใจ ว่าข้างต้น ยังถูกต้อง
วันนี้ สภาพแวดล้อม ที่เปลี่ยนไป
- มีกฏหมาย, มีหน่วยงานตรวจสอบ ทั้งจากภายในและภายนอก
- ต้อง Share ข้อมูลต่างๆ มากขึ้น
- ผู้ใช้งาน มีมากและหลากหลาย
ผลที่ตามมา
- ไม่รัดกุม (ทางเข้าในปัจจุบัน มีมากกว่าที่เห็น)
- ขาดความยืดหยุ่น - มีข้อมูลแต่ ห้ามๆๆๆ จน Share กับใครไม่ได้ หรือ ขั้นตอนมาก
- เมื่อมีคนมากขึ้น ความเชื่อใจเปลี่ยนเป็น ไม่ไว้ใจซึ่งกันและกัน
การออกแบบ ที่ดี คือ ทำตามคำคู่มือในหนังสือของ iSeries
ในขณะที่ คำแนะนำ "เหมาะสม" จะเกิดจาก การปรับสภาพแวดล้อม
- องค์กร, หน้าที่ ที่ชัดเจน
สิ่งที่จะเข้าใช้ (Function, Object) ... กำหนดหน้าที่ + สิทธิ ในการ เข้าใช้
- วิธีทำงานปัจจุบัน ... ทบทวน ปรับวิธีจากความคุ้นเคย ให้เหมาะ กับ หน้าที่+สิทธิข้างต้น
- IT ... จัด เทคนิค,ตัวเลือก ที่เหมาะกับสิ่งที่ต้องทำข้างต้น
ตย.
* ลงทะเบียน ระดับบุคคล + จัดสิทธิร่วม หลาย บุคคล ให้เป็น "กลุ่ม"
(IBM แนะนำให้เริ่มที่ UserProfile)
- บางบริษัทฯ มี admin คนเดียวแต่มี programmer หลายคน
เพื่อลดงาน Admin ได้ให้ programmer สร้าง database จัดการกันเอง
>> OS จะมองไม่เห็น "ตัวตน" การจัดสิทธิใน Lib หรือ File จะทำ "ยุ่งยาก"
>> เมื่ออ่านต่อจนจบ จะพบว่า การเลือกวิธีนี้ ทำให้ งานด้านหลังทำ "ยากขึ้นไปอีก"
# ถ้าอนุญาต ให้ Programmer จัดการ (และมักจะให้ User Admin ทำต่อ)
>> Admin เพียงแค่ สร้างโปรแกรมแล้วให้ Programmer หรือ User ระดับ admin จัดการได้
ปัญหาอยู่ที่ไหน ? Admin ไม่เขียนโปรแกรม, ใช้เครื่องมือใหม่ ไม่คล่อง, ...
แก้ไขให้ถูกจุด -> งานจะวิ่งต่อได้ สะดวก
* การออกแบบ P-file และ L-File ที่มีโครงสร้าง เหมือนกัน (จำง่าย)
เช่น P-file ข้อมูลพนักงาน มี เงินเดือน
L-file แบบเดิม จะเห็นทุกช่องเหมือน P-file
--- ไม่อนุญาตให้ ใครใช้ข้อมูลพนักงาน ---
>> copy data ไป อีก table (ตัด field ที่ไม่ต้องการ) ทำทุกคืน
เกิดปัญหา ไม่ real time (ยื่นลา ตอนเช้า ต้อง รอดูผลพรุ่งนี้)
Run โปรแกรมให้ ถี่ขึ้น (AddJobSchE)
หรือ ใช้เครื่องมือของ Admin (เช่น Replicate)
L-file มีคุณสมบัติ อีกอันหนึ่ง คือ การสร้าง View ให้เหมาะกับ การใช้งาน
>> จำกัดสิทธิ การใช้ Lib, P-file
>> สร้าง Lib ที่แยก และ share แบบจำกัด
สร้าง L-file ให้เหมาะกับ การใช้งาน เช่น ไม่มี Field เงินเดือน
* ภาษา โปรแกรมที่ใช้
ภาษามาตรฐานใหม่ ที่ไม่ใช่ RPG มีทางเลือกที่ยืดหยุ่นกว่ามาก
ขนาดหน้าจอ, รายงาน ที่เกินข้อกำหนด จัดวางให้ใช้งานได้ง่าย
? ทีมงานดั้งเดิม ไม่ยอมเปลี่ยน
>> แผน/ขั้นตอน การเปลี่ยน ภาษาหลัก หรือ เพิ่มภาษารอง ในการใช้งาน
>> ถ้าทำได้ จะมีทางเลือก ต่อไปนี้ช่วย
สร้างเป็น Class ที่ Encapsulate แล้ว (ไม่เห็น Source Code) ให้เรียกใช้
(เหมาะกับ ภาษารอง ใช้ภาษาเดียว เช่น Java, ASP, Php เป็นต้น)
Web Service : วิธีการที่ถูกออกแบบมาเพื่องานลักษณะนี้ อาจจะมีข้อจำกัดมากกว่า เพราะทำบน internet ได้
>> สร้าง Web Service ด้วย Java, DotNet
ข้อแนะนำอื่นๆ
- ทดสอบ ก่อนเปิดใช้การปรับแล้วทำเลย สไตล์ลูกทุ่ง ไม่เหมาะกับงาน Security บางกรณีต้องหยุดเครื่องกันเลย
- จะเห็นว่า ปัญหาใหญ่ คือ ทีมงานหลัก
Key Man ถ้ามองแค่ "เบา" สำหรับตนเอง จะกระทบกับภาพรวม
คนที่เกี่ยวข้อง ถ้ายังคิดว่า อะไรก็ได้ แต่ทำแบบเดิมๆ น๊ะ (ก็ไม่ได้ทำเพื่อเป้าหมาย)
วันพุธที่ 22 มกราคม พ.ศ. 2557
DB2 กับ RPG ภาค2
ผู้ที่ระบบที่ใช้ต่อเนื่องมานาน เกิน 15 ปี
น่าจะพบปัญหาเดียวกันนี้น๊ะครับ
Q1: Physical File = สร้างโดยไม่ระบุ Primary Key (Unique)
แล้วจะรู้ได้อย่างไรว่า Primary Key คือ อะไร ?
การ Insert/Update/Delete จะชี้ได้ถูกต้อง อย่างไร ?
A1: ถ้าระบบฯ มีอยู่แล้ว
- เชื่อว่า โปรแกรม Maintenance ดั้งเดิม ทำงานถูก ได้ช่วยไกด์เรา
- ตรวจสอบซ้ำ (จากตัว data)
SQL : Select Primary Keys ,count(*) From Lib.File
Group by Primary Keys
Having count(*) > 1
ถ้ามี rows ออกมา แสดงว่า Primary Keys ไม่ถูกต้อง
อธิบาย
- Primary Keys (มีมากกว่า 1 Field ได้)
- ตามนิยาม เมื่อชี้ข้อมูลด้วย Primary Keys จะพบแค่ 1 row เท่านั้น
- หลังการ กรองค่า (Having) ถ้า Primary Keys ถูกต้อง ต้องไม่มี rows แสดงออกมา
อืนๆ - บางที่ จะมีการเก็บ ข้อมูลที่ "ลบ" ไว้ใน File (ทำให้ ข้อมูลกลุ่มนี้ ไม่เป็นไปตามกฏ)
ดังนั้น ต้องแยกข้อมูลกลุ่มนี้ ออกไปก่อน
เช่น itemNo ถ้าลบ จะใส่ "#" นำหน้า ป้อนแล้วลบ 2 ครั้ง จะมีรายการนี้ซ้ำ 2 รายการ
- ตรวจจาก Business Concept
เช่น Stock File (ItemNo, ItemName, WH , Loca, Vendor, OnHandQty)
นิยามว่า ItemNo จัดวางอยู่ที่ พื้นที่ (WH,Loca)
Primary Keys = ItemNo, WH(WareHouse),Loca
นิยามว่า ItemNo จัดวางอยู่ที่ พื้นที่ (WH,Loca) โดยต้องแสดงแยกตาม Vendor
Primary Keys = ItemNo, WH(WareHouse),Loca, Vendor
>> จะเห็นว่า ถ้าใครโชคดี ใช้ DB ที่มีโครงสร้างสมบุรณ์ (มี Field มาก)
แต่ไม่ได้กำหนด Primary Key ไว้ สามารถเดา "ได้หลากหลาย"
แต่ไม่ได้กำหนด Primary Key ไว้ สามารถเดา "ได้หลากหลาย"
Q2: ทำไม สร้าง Field ใน Logical File เหมือนใน Physical File
สร้างแตกต่าง ระดับ Field ได้หรือไม่ ?
A2: ได้ครับ
ดั้งเดิม เราจะทำให้มัน เข้าใจ(จำ)ง่าย - เป็นเทคนิคที่ดีสำหรับระบบขนาดใหญ่
แต่ระบบ DB ปัจจุบัน ที่สอนกัน (จนเป็นมาตรฐาน)
แยกเรียก Logical File ว่า Index กับ View
- View ว่าสร้างเพื่อให้ คนอื่น ใช้งานง่าย หรือ จำกัด Security
- Index ทำเพื่อความเร็วในการ Access
CL - สร้างโปรแกรมช่วย ลดการทำงาน-1
CL - สร้างโปรแกรมช่วย ลดการทำงาน-1
CL = Control Language เป็นภาษาที่ใช้จัดการ คำสั่ง บน OS/400ถ้าเทียบกับ Windows ก็คือ เขียน/สร้าง Batch File เพื่อใช้คำสั่งย่อย ต่อเนื่องกัน
เทคนิคช่วยลด เวลา ในการทำงานซ้ำๆได้ครับ
ตย. ทุกเดือนต้อง Backup Data (เช่น Lib1/File1 -> LibB/FileH) โดยกำหนดขั้นตอนดังนี้
(1). แยกข้อมูลตาม ช่วงเวลา (เช่น 1 member ต่อ 6 เดือน เป็นต้น)
(2). เมื่อย้ายข้อมูลเสร็จ จะนำข้อมูล
2.1 จัดเก็บใน Cartridge
2.2 จัดเก็บใน History Server (ที่ราคาถูกกว่า เช่น MS SQL Server)
ต้องรวม Member กลับไปเป็น 1 Member
(LibB/File1-หลาย member -> LibH/FileH 1 member)
ผมสนใจข้อ 2.2 ซึ่งต้องทำแบบ Manual ดังนี้
a. ตรวจดูว่า LibB/File1 มี member ชื่ออะไรบ้าง ? ด้วยคำสั่ง
DSPFD FILE(LibB/File1) TYPE(*MBRLIST)
(จดรายชื่อไว้)
b. Copy รวม data ด้วยคำสั่ง
CPYF FROMFILE(LibB/File1) TOFILE(LibH/FileH) FROMMBR(ระบุชื่อ) TOMBR(*FIRST) MBROPT(*ADD)
ตย. มี 10 File แต่ละ File มี 5-10 member ที่ชื่ออ่านยาก การทำแบบ Manual จะใช้เวลา "นาน" และเสี่ยงที่จะผิดพลาด (จดชื่อผิด)
เราจะสร้างโปรแกรมช่วย ลดการทำงาน ในข้อ 2.2 กัน
โดยสร้างโปรแกรม และทำงานดังนี้ CALL BK2HT (LibB File1 LibH FileH)
สร้าง CL โดยปรับขั้นตอนตามนี้
(รับค่า &LibB &File1 &LibH &FileH)
a. DSPFD FILE(&LibB/&File1) TYPE(*MBRLIST) OUTPUT(*OUTFILE) OUTFILE(QTEMP/A)
Loop อ่าน File QTEMP/A
b. CPYF FROMFILE(&LibB/&File1) TOFILE(&LibH/&FileH)
FROMMBR(&mlname) TOMBR(*FIRST) MBROPT(*ADD)
จากนั้น เพิ่มรายละเอียดต่างๆ เช่น
- ตรวจ Lib/File ต้องมี
- ถ้ามี File แต่ไม่มี Member
- ...
มาดู code BK2HT แบบเต็มๆกัน
---------------------------------------------------------------------
PGM PARM(&LIBB &FILE1 &LIBH &FILEH)
DCLF FILE(A)
DCL VAR(&LIBB) TYPE(*CHAR) LEN(10)
DCL VAR(&FILE1) TYPE(*CHAR) LEN(10)
DCL VAR(&LIBH) TYPE(*CHAR) LEN(10)
DCL VAR(&FILEH) TYPE(*CHAR) LEN(10)
CHKOBJ OBJ(&LIBB/&FILE1) OBJTYPE(*FILE)
MONMSG MSGID(CPF9801) EXEC(GOTO CMDLBL(STP090)
CHKOBJ OBJ(&LIBH/&FILEH) OBJTYPE(*FILE)
MONMSG MSGID(CPF9801) EXEC(GOTO CMDLBL(STP090)
DSPFD FILE(&LibB/&File1) TYPE(*MBRLIST) OUTPUT(*OUTFILE) OUTFILE(QTEMP/A)
/*-- Start Loop --*/
STP010:
RCVF
MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(STP090))
CPYF FROMFILE(&LibB/&File1) TOFILE(&LibH/&FileH)
FROMMBR(&mlname) TOMBR(*FIRST) MBROPT(*ADD)
GOTO CMDLBL(STP010)
/*-- End Loop --*/
STP090:
ENDPGM
---------------------------------------------------------------------
ก่อน compile ให้เรียกใช้คำสั่งข้อ a. ก่อน (เพื่อสร้าง Object = QTemp/A)
อื่นๆ
เทคนิคนี้ใช้บ่อย ได้กับงานที่เรียกใช้ CL Cmd ติดต่อกัน- ตรวจ data size ในระบบ file ไหนมีขนาดใหญ่ เกินกำหนด
- ตรวจ job ที่ (กำลัง) ทำงานใน subsystem
- ...
ตย. ข้างต้น เมื่อดุดีๆ จะพบว่า ถ้าปรับขั้นตอน (1) ให้ไปเก็บใน LibH/FileH 1 member เลย ก็ไม่ต้องทำ 2.2 ที่ไม่ทำเพราะ (1) เป็นโปรแกรมที่เก่ามาก และมีเทคนิคเฉพาะหลายอย่าง ... การปรับถือว่าไม่คุ้ม
วันอาทิตย์ที่ 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 มิติเท่านั้น
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+
ได้ 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+
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+
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
สมัครสมาชิก:
บทความ (Atom)