ภาคต่อของ Internal Table และ Selection Screen
เนื้อหาเกี่ยวกับ ABAP Programming ที่ผ่านมา น่าจะทำให้หลายท่านเข้าใจการเขียนโปรแกรม ABAP ในระบบ SAP มากขึ้น ไม่มากก็น้อย และถ้าใครได้ติดตามเนื้อหา ABAP มาอย่างต่อเนื่อง ผมคิดว่าคุณพร้อมแล้วที่จะเข้ามาในโลกของการพัฒนาระบบงาน SAP โดยใช้ภาษา ABAP เพราะเนื้อหาส่วนสำคัญที่สุด ก็คือส่วนของคำสั่ง Open SQL นั่นเอง โปรแกรม ABAP ทุกโปรแกรมที่เราเขียนขึ้นมานั้น ไม่พ้นที่จะต้องมีการอ่านข้อมูลจาก Database Server ของระบบ SAP และสำหรับเนื้อหาในฉบับนี้ ผมจะพูดถึงเรื่องของหน้าจอ Selection Screen ต่อไปจากเรื่องของ Internal Tableการเรียงลำดับข้อมูลใน Internal Table
เราจะใช้คำสั่ง Sort ในการเรียงลำดับข้อมูลใน Internal Table เช่น หลังจากมีข้อมูลที่ Internal Table เรียบร้อยแล้ว ถ้าเราต้องการเรียงลำดับของข้อมูลตามชื่อของลูกค้า เราสามารถเขียนโปรแกรมได้ดังต่อไปนี้Data itab like customers occurs 0 with header line.
Select * from customers into table itab.
Sort itab by name.
และถ้าต้องการเรียงลำดับของข้อมูลจากมากไปหาน้อย ก็ให้ใช้ออปชัน descending เช่น
Sort itab by name descending.
ดังนั้น ที่ผมเคยกล่าวไว้ในเรื่องเกี่ยวกับคำสั่ง Select ว่า เราไม่ควรใช้ออปชัน Order by ของคำสั่ง Select ในการเรียงลำดับข้อมูลของตารางในฐานข้อมูล เพราะความเร็วในการทำงาน (Performance) จะไม่ค่อยดีสักเท่าไร เพราะเป็นการเรียงลำดับของข้อมูลที่ Database Server ทางแก้ก็คือ ให้ทำการอ่านข้อมูลมาเก็บไว้ที่ Internal Table จากนั้นค่อยสั่งเรียงลำดับของข้อมูลจากคำสั่ง Sort ต่อไป วิธีนี้จะดีกว่าเพราะเป็นการเรียงลำดับของข้อมูลที่ Memory Space นั่นเอง
การอ่านข้อมูลจาก Internal Table
การอ่านข้อมูลจาก Internal Table มีอยู่ 2 วิธีด้วยกันคือ การอ่านแบบ Multiple Record และแบบ Single Record มาดูแบบแรกกันก่อน โดยที่การอ่านข้อมูลจาก Internal Table ในแบบ Multiple Record นั้น เราจะใช้คำสั่ง Loop at ... Endloop เช่นData itab like customers occurs 0 with header line.
Select * from customers into table itab.
Loop at itab.
Write: / itab-id, itab-name.
Endloop.
หน้าที่ของคำสั่ง Loop at ก็คืออ่านข้อมูลใน Internal Table ตามที่ระบุใน เรคอร์ดที่พอยน์เตอร์ (Pointer) ชี้อยู่ (ถ้าเป็นการอ่านเรคอร์ดแรก พอยน์เตอร์จะชี้อยู่ที่เรคอร์ดแรก) จากนั้นระบบจะคัดลอกข้อมูลทั้งแถวมาไว้ที่ Header Line ดังรูปที่ 13
รูปที่ 13 |
จากนั้นเมื่อพบคำสั่ง Endloop ระบบก็จะเช็กว่ามีข้อมูลเรคอร์ดถัดไปที่จะต้องอ่านอีกหรือไม่ ถ้ามีก็จะเลื่อน Pointer ไปยังเรคอร์ดถัดไป จากนั้นก็จะโอนการทำงานกลับไปยังคำสั่ง Loop at เพื่ออ่านข้อมูลไปไว้ที่ Header Line ต่อไป การทำงานก็จะเป็นเช่นนี้ ไปจนกระทั่งหมดข้อมูลใน Internal Table แล้วโปรแกรมก็จะข้ามไปทำงานยังคำสั่งถัดจาก Endloop นั่นเอง ถ้าเราสังเกตดีๆ จะพบว่า การทำงานของคำสั่ง Loop at ... Endloop จะคล้ายกับการทำงานของคำสั่ง Select ... Endselect ทุกประการ แตกต่างกันตรงที่ว่า คำสั่ง Select เป็นการอ่านข้อมูลที่ Result Set ในพื้นที่ของ DB Interface แต่คำสั่ง Loop at จะเป็นการอ่านข้อมูลจากเนื้อข้อมูลของ Internal Table ใน Memory Space
ดังนั้นการอ่านข้อมูลจากตารางในฐานข้อมูลมาเก็บไว้ที่ Internal Table จากนั้นก็ใช้คำสั่ง Loop at ในการอ่านข้อมูลจาก Internal Table จะมีความเร็วสูงกว่า การอ่านข้อมูลจากตารางในฐานข้อมูลโดยตรงจากคำสั่ง Select นอกจากนี้เรายังใช้ตัวแปรระบบที่ชื่อ sy-tabix ในการแสดงค่ารอบปัจจุบันของการวนลูปในบล็อกของ Loop at ... Endloop (เหมือนกับค่า sy-index ในบล็อกของ Do กับ WHILE หรือ sy-dbcnt ในบล็อกของ Select... Endselect) แต่ตัวแปรระบบ sy-tabix นั้น สามารถใช้ได้เฉพาะภายในบล็อกของ Loop at ... Endloop เท่านั้น ซึ่งจะแตกต่างจากตัวแปรระบบ sy-dbcnt ที่เราใช้งานนอกบล็อก Select ... Endselect ได้
นอกจากนี้ ในคำสั่ง Loop at ยังใช้ Where Clause ในการกรองข้อมูลได้ตามปกติเหมือนกับคำสั่ง Select เช่น
Loop at itab where id > 1. หรือ
Loop at itab where name < > 'John'.
สำหรับการใช้ Template หรือ Wildcard ใน Where Clause ของคำสั่ง Loop at เราจะใช้ค่า * แทนตัวอักษรอะไรก็ได้กี่ตัวก็ได้ (เหมือนกับค่า % ของคำสั่ง Select) และ + แทนตัวอักษรอะไรก็ได้หนึ่งตัว (เหมือนกับค่า _ ของคำสั่ง Select) เช่น ถ้าเราต้องการอ่านข้อมูลของ Internal Table เฉพาะชื่อของลูกค้าที่ตัวอักษรตัวที่สองเป็นค่า a เราสามารถเขียนคำสั่งได้ดังนี้
Loop at itab where name cp '+a*'.
โดยที่เราจะใช้ cp แทน = ใน Where Clause (เหมือนกับ Like ของคำสั่ง Select) สำหรับการอ่านข้อมูลใน Internal Table แบบ Single Record นั้น เราจะใช้คำสั่ง Read Table เช่น ถ้าต้องการอ่านข้อมูลจาก Internal Table สำหรับค่า id มีค่าเท่ากับ 1 เราสามารถเขียนคำสั่งได้ดังนี้
...
Read table itab with key id = 1.
If sy-subre = 0.
Write: / itab-id, itab-name
Endif.
การทำงานของคำสั่ง Read Table นั้น ระบบจะอ่านข้อมูลที่ Internal Table ตามเงื่อนไข ถ้าพบข้อมูลที่ต้องการ ระบบก็จะคัดลอกข้อมูลของเรคอร์ดนั้นๆ ที่เนื้อข้อมูลของ Internal Table ไปไว้ที่ Header Line ของ Internal Table พร้อมทั้งให้ค่าศูนย์กับตัวแปรระบบ sy-subrc แต่ถ้าไม่พบข้อมูลค่าของตัวแปรระบบ sy-subrc ก็จะได้ค่าที่มากกว่าศูนย์ และจะไม่มีการแตะต้อง Header Line ของ Internal Table แต่อย่างใด เช่นเดียวกัน การทำงานของคำสั่ง Read Table นั้นจะคล้ายกันกับคำสั่ง Select Single นั่นเอง สำหรับการอ่านข้อมูลที่มีเงื่อนไขมากกว่าหนึ่งฟิลด์ เราจะไม่ใช้ and ใน Where Clause เช่น
...
Read table itab with key name = 'John'
City = 'New York'.
และถ้าต้องการให้การอ่านข้อมูลแบบ Single Record ใน Internal Table มีประสิทธิภาพดีที่สุด ในกรณีที่ข้อมูลใน Internal Table มีปริมาณมาก เราสามารถใช้ออปชัน Binary Search ได้ เช่น
...
Sort itab by name.
Read table itab with key name = 'David'
binary search.
แต่ก่อนที่จะใช้ออปชัน Binary Search ได้นั้น เราจะต้องเรียงลำดับข้อมูลตามค่าฟิลด์ที่ระบุในออปชัน with key ของคำสั่ง Read Table เสียก่อน มิฉะนั้นเราอาจได้ข้อมูลผิดๆ ไปก็ได้ แล้วพบกันใหม่ในตอนหน้าครับ
Selection Screen
การเขียนโปรแกรม ABAP ที่ผ่านมานั้น เรายังไม่มีส่วนของการปฏิสัมพันธ์กับผู้ใช้ระบบแต่อย่างใด ก็คือเมื่อเราสั่งเอ็กซิคิวต์โปรแกรม ABAP เราก็จะได้หน้าจอ List โดยทันที เมื่อโปรแกรม ABAP ถูกประมวลผลในทุกคำสั่งเสร็จสิ้นโดยสมบูรณ์ แต่ถ้าเรา ต้องการให้โปรแกรมมีการปฏิสัมพันธ์กับผู้ใช้ระบบ เช่น ให้ผู้ใช้ระบบใส่เงื่อนไขที่ต้องการแสดงข้อมูล จากนั้นเมื่อสั่งเอ็กซิคิวต์โปรแกรม ก็จะได้ข้อมูลใน List ตามเงื่อนไขที่ได้ระบุไว้ ซึ่งในส่วนของการปฏิสัมพันธ์กับผู้ใช้ระบบนี้ ในภาษา ABAP นั้น จะมีคำสั่งอยู่สองคำสั่งด้วยกัน ในการสร้างหน้าจอที่มีการปฏิสัมพันธ์กับผู้ใช้ระบบ ก็คือคำสั่ง Parameters กับคำสั่ง Select-options ซึ่งหน้าจอที่ได้จากการทำงานของสองคำสั่งนี้ เราจะเรียกว่าหน้าจอ Selection Screenคำสั่ง Parameters
คำสั่ง Parameters เป็นคำสั่งที่ใช้ในการสร้างหน้าจอ Selection Screen โดยที่เราจะได้ช่อง Input ให้ผู้ใช้ระบบใส่ข้อมูลลงไป เช่นตัวอย่างโปรแกรมดังต่อไปนี้Parameters: tmp1(10) type c,
tmp2(5) type n,
tmp3 like sy-datum,
id like customers-id.
เมื่อสั่งเอ็กซิคิวต์โปรแกรมข้างต้น เราจะได้หน้าจอ Selection Screen ดังรูปที่ 1
รูปที่ 1 |
Report ztest.
Parameters tmp(10) type c.
Write: / tmp.
เมื่อเอ็กซิคิวต์โปรแกรม ระบบจะทำการสร้างตัวแปร tmp ที่ Memory Space ดังรูปที่ 2
รูปที่ 2 |
รูปที่ 3 |
รูปที่ 4 |
รูปที่ 5 |
Parameters tmp(10) type c lower case.
ภายหลังจากที่ระบบ Assign ค่าข้อมูลของตัวแปรจากหน้าจอ Selection Screen ไปที่ Memory Space เรียบร้อยแล้ว ระบบก็จะประมวลผลคำสั่ง ABAP ถัดไปคือ write: / tmp. ซึ่งหมายถึงการนำข้อมูลของตัวแปร tmp จาก Memory Space ไปเขียนที่ List Buffer เพื่อแสดงข้อมูลที่หน้าจอของผู้ใช้ระบบต่อไป จะเห็นได้ว่าคำสั่ง Parameters เป็นคำสั่งที่ใช้ในการสร้างตัวแปร ดังนั้นเราจึงควรที่จะเขียนคำสั่ง Parameters นี้ ไว้ที่ส่วนต้นของโปรแกรมเหมือนกับคำสั่ง Data และตัวแปรที่ได้จากคำสั่ง Parameters จะเหมือนกับตัวแปรที่ได้จากคำสั่ง Data ทุกประการ
ถ้าเราต้องการให้ค่าเริ่มต้นหรือค่าดีฟอลต์ (Default) ของตัวแปรที่สร้างจากคำสั่ง Parameters ให้ใช้ออปชัน default (คล้ายกับออปชัน value ของคำสั่ง Data โดยที่เราสามารถใช้ตัวแปรใดๆ ในการให้ค่าเริ่มต้นกับตัวแปร Parameters ได้ เช่น default sy-datum แต่ออปชัน value ทำเช่นนี้ไม่ได้) เช่น
Parameters today like sy-datum default sy-datum.
เราจะได้ข้อมูลที่ Memory Space ดังรูปที่ 6
รูปที่ 6 |
รูปที่ 7 |
รูปที่ 8 |
รูปที่ 9 |
Parameters tmp(10) obligatory.
ถ้าเราไม่ระบุชนิดของตัวแปรจากออปชัน type ในคำสั่ง Parameters ระบบจะถือว่าเป็นตัวแปรชนิด C และถ้าไม่ระบุ Length ระบบก็จะถือว่าเป็นค่า 1 ไปโดยปริยาย ซึ่งจากการระบุออปชัน obligatory ในคำสั่ง Parameters ทำให้เราไม่สามารถผ่านหน้าจอ Selection Screen ไปทำงานคำสั่งถัดไปได้ หากไม่ใส่ข้อมูลของตัวแปร tmp ที่หน้าจอ Selection Screen โดยที่ระบบจะแสดงข้อความ Make an entry in all required fields ที่บรรทัด Status Line ดังรูปที่ 10
รูปที่ 10 |
Parameters: check1 as checkbox,
check2 as checkbox default 'X',
radio1 radiobutton group test,
radio2 radiobutton group test.
ตัวแปร Check Box กับ Radio Button ที่ได้ใน Memory Space นั้น จะเป็นชนิด C และมี Length เป็นค่า 1 เสมอ
ที่มา : http://www.arip.co.th/articles.php?id=406417
ไม่มีความคิดเห็น:
แสดงความคิดเห็น