การสร้างฟอร์ม
ฟอร์มเป็นตัวกลางที่สำคัญตัวหนึ่งที่จะทำการติดต่อระหว่างผู้ใช้งานกับข้อมูลต่างๆ
ไม่ว่าจะเป็นการป้อนข้อมูล
การแสดงข้อมูล
หรือการแสดงข่าวสารต่างๆที่เกิดขึ้นในระบบงาน
การที่เราจะทำการสร้างฟอร์มขึ้นมาสักฟอร์มหนึ่งนั้นมันไม่ได้ยากอะไรหรอก
แต่การที่จะควบคุมการทำงานของฟอร์มนั้นมันไม่ได้ง่ายสักเท่าใด
คุณจะคุมการทำงานของฟอร์มได้อย่างไรนั้นก็ขึ้นอยู่กับการออกแบบ
และการจิตนาการของท่านทั้งหลาย
ถ้าคุณเข้าใจหลักการและวิธีการที่ผมจะแนะนำในบทนี้แล้ว
ก็คิดว่าจะเป็นแนวทางในการออกแบบและสร้างฟอร์มของคุณต่อๆไป
ลักษณะของฟอร์มในการป้อนข้อมูลโดยทั่วๆไปแล้วจะมีอยู่
2 แบบคือ
1.ฟอร์มการป้อนข้อมูลทีละเรคคอร์ด
เช่น ฟอร์มที่ใช้ป้อนข้อมูล
ลูกค้า, สินค้า , พนักงานขาย
เป็นต้น
2.ฟอร์มการป้อนข้อมูลที่มีความสัมพันธ์แบบหนึ่งต่อหลายๆเรคคอร์ด
เช่น
ฟอร์มที่ใช้ป้อนข้อมูลใบส่งสินค้า
เป็นต้น
การสร้างฟอร์มป้อนข้อมูลทีละเรคคอร์
อย่างที่กล่าวไว้ข้างต้นว่า
การสร้างฟอร์มนั้นไม่ยากแต่การควบคุมการทำงานนั้นไม่ได้ง่ายเหมือนกับการสร้างฟอร์ม
ก่อนอื่นเราต้องนึกก่อนว่าฟอร์มที่เราจะสร้างต้องการให้มีลัษณะเป็นอย่างไร
และต้องคำนึงถึงข้อผิดพลาดที่จะเกิดจากการป้อนข้อมูล
เพื่อที่จะได้ทำการควบคุมข้อผิดพลาดเหล่านั้น
ซึ่งสิ่งหลังนี้แหละจะบ่งบอกถึงความสามารถในการเขียนโปรแกรมของคุณ
เรามาลองทำฟอร์มป้อนข้อมูล
สินค้ากันก่อน
หลักการทำฟอร์มป้อนข้อมูลจะประกอบไปด้วย
4 ส่วนใหญ่ๆ (ของผู้เขียนเอง)
ส่วนแรกเป็นส่วนของ
ฟอร์มการป้อนข้อมูล
ส่วนที่สองเป็นส่วนของปุ่มควบคุม(toolbar)
ในบทนี้ผมไม่ได้แสดงวีธีสร้างไว้
ให้ไปดูในหัวข้อง Visual Class Libary
ส่วนที่สามเป็นส่วนของเมธอตคำสั่งในการควบคุมการทำงานของฟอร์ม
ส่วนที่สี่เป็นส่วนของการตรวจสอบความผิดพลาดในการป้อนข้อมูล(check
error)
เรามาเริ่มกันเลย
ส่วนของฟอร์มการป้อนข้อมูล
1. ที่ command windows ป้อนคำสั่ง
SET DEFA TO C:\MYAPP
MODIFY COMMAND MYPROJECT
(โปรเจ็ก
myproject คุณสามารถ download
โปรแกรมตัวอย่างได้ที่
เริ่มสร้างระบบงาน)
2. คลิ๊กที่แท็ป Docs
แล้วเลือก New
จากนั้นให้ทำการคลิ๊กที่ New Form
3. กำหนด form properites
โดยคลิ๊กเมาส์ปุ่มขวา แล้วเลือก
properties กำหนดคุณสมบัติของฟอร์ม
ดังนี้
Caption = แฟ้มข้อมูลสินค้า
Icon = C:\myapp\bmp\thai.ico
MaxButton = .F.
MinButton = .F.
Top = 60
4. ที่ Form Control คลิ๊กที่คอนโทล
View Class ()
เพื่อนำ Sub-Class MyToolbar
ที่ผมได้สร้างเตรียมไว้ให้นำมาไว้ใน
ฟอร์ม ของเรา(วิธีการสร้าง
Class ใหม่ ดูที่ Visual Class Library)
แล้วคลิ๊กที่ Add จากนั้นให้เลือก
ไฟล์ mytoolbar แล้วคลิ๊กที่ปุ่ม Open
จากนั้นให้คลิ๊กที่ ปุ่ม toolbar1
แล้วมาคลิ๊กที่ฟอร์ม แล้วตอบ YES
ทีนี้ในฟอร์มของคุณก็จะมีปุ่มทูลบาร์ปรากฎอยู่
ซึ่งเรียกรวมทั้งทูลบาร์
และฟอร์มว่า เป็น ฟอร์มเซ็ต(form set)
แนะนำ คุณสามารถเพิ่ม หรือลบฟอร์ม ในฟอร์มเซ็ตได้โดยการเลือกเมนู Form แล้วเลือก Add New Form เพื่อทำการเพิ่มฟอร์ม หรือ Remove Form เพื่อทำการลบ ฟอร์ม หรือ Visual Class Library |
เมื่อคุณต้องการให้ Form Control
กลับมาเป็นปรกติของ Visual FoxPro
ก็ให้คลิ๊กที่ แล้วเลือก Standard
5.
ให้ทำการคลิ๊กเมาส์ปุ่มขวาที่
ฟอร์ม แล้วเลือก Data Environment...
จากนั้นให้ทำการเลือก แฟ้ม product
แล้วคลิ๊กปุ่ม Add
เมื่อเลือกเสร็จแล้วให้คลิ๊กที่ปุ่ม
Close
6. ที่แฟ้ม product
ให้คลิ๊กเมาส์ปุ่มขวา แล้วเลือก
Properties แล้วกำหนดค่าดังนี้
BufferModeOverried = 3
Order = prod_id
BufferModeOveried
จะเป็นการกำหนดการป้องกันการป้อนข้อมูลในตาราง(table)
ซึ่งการกระทำนั้นจะทำการโอนข้อมูลของคุณเก็บไว้ที่หน่วยความจำของคอมพิวเตอร์ก่อน
เมื่อได้กระทำกับข้อมูลใน
บัฟเฟอร์เรียบร้อยแล้วเราจะใช้คำสั่ง
TABLEUPDATE() ในการ update
ขอมูลลงสู่ตารางอีกที
หรือถ้าต้องการยกเลิกการเปลี่ยนแปลงให้ใช้คำสั่ง
TABLEREVERT() ในการกำหนด
บัฟเฟอร์นั้นเราจำเป็นต้องคำนึงถึงฟอร์มที่ใช้ในการป้อนข้อมูลด้วยว่าควรจะกำหนดบับเฟอร์เป็นแบบใด
ดังต่อไปนี้ 1 ไม่มีการกำหนดบัฟเฟอร์ 2 เป็นการกำหนดบัฟเฟอร์เพื่อป้องกันเรคคอร์ที่ทำงานอยู่ ณ.ขณะนั้นไม่ให้ผู้อื่นเข้ามาใช้งานได้อีก(lock record) จนกว่าเรคคอร์นั้นจะถูกปล่อยออกมา(unlock record) 3 เป็นการกำหนดบัฟเฟอร์เพื่อป้องกันเรคคอร์ ที่ทำงานอยู่ไม่ให้ผู้อื่นเข้ามาใช้งานเฉพาะตอนที่จะ update ข้อมูล 4 เป็นการกำหนดบัฟเฟอร์เพื่อป้องกันตาราง จนกว่าตารางนั้นจะถูกปล่อยออกมา(unlock record) 5 เป็นการกำหนดบัฟเฟอร์เพื่อป้องกันตาราง เฉพาะตอนที่จะ update |
ส่วนของปุ่มควบคุม
5. ที่ Form Control คลิ๊กที่คอนโทล
View Class ()
เพื่อนำ Sub-Class MyControl
ที่ผมได้สร้างเตรียมไว้ให้นำมาไว้ใน
ฟอร์มแล้วคลิ๊กที่ Add
จากนั้นให้เลือก ไฟล์ mycontrol
แล้วคลิ๊กที่ปุ่ม Open
แล้วทำการสร้างฟอร์มตามภาพด้านล่าง
กำหนด Properties ของ
คอนโทรแต่ละตัวดังนี้
Mtextbox1
ControlSource = Product.Prod_id
InputMark = XXXXX
Mtextbox2
ControlSource = Product.Name
Mtextbox3
ControlSource = Product.Um
InputMark = XXXXXXXXXX
Mtextbox4
Alignment = 1
ControlSource = Product.UnitPrice
InputMark = 9,999,999.99
Mtextbox5
Alignment = 1
ControlSource = Product.On_Hand
InputMark = 9,999,999
เอาละครับถึงตรงนี้ก็เสร็จสิ้นสำหรับการสร้างรูปแบบของฟอร์ม
ง่ายไหมครับ
แต่ยังไม่จบหรอกครับยังหรือวิธีการควบคุมฟอร์ม
และการตรวจสอบการป้อนข้อมูล(check
error)
เรามาดูกันว่าเราจะควบคุมให้ฟอร์มทำงานอย่างไรเมื่อเรากดปุ่มต่างๆบนทูลบาร์
6. ให้คุณทำการสร้าง method
ขึ้นมาดังนี้
ที่เมนู Form เลือก New
Method... พิมพ์ชื่อ เมธอตว่า msetenabledoff
กดปุ่ม Add แล้วพิมพ์ชื่อ msetenabledon
กดปุ่ม Add
สองเมธอตที่สร้างนี้จะเป็นตัวกำหนดลักษณะของคอนโทรต่างๆว่าจะทำอย่างไร
ให้กดปุ่ม Close
เพื่อทำการปิดหน้าต่าง New Method
ที่เมนู Form เลือก New
Property... พิมพ์ชื่อ property ว่า m_newrecord กดปุ่ม
Add แล้วกดปุ่ม Close
7.
ทำการป้อนคำสั่งในส่วนของเมธอต
โดยทำการคลิ๊กขวาที่ฟอร์ม เลือก
Properties ใน List box ให้เปลี่ยนจาก Form1 เป็น
Formset1 ซึ่งจะอยู่เหนือ Form1
ขึ้นไปอีกบรรทัด
จากนั้นคลิ๊กที่แท๊ป Method
แล้วกำหนด เมธอต ดังนี้
ที่ msetenabledoff
ทำการป้อนคำสั่งดังนี้
_Screen.Activeform.Setall("Enabled",.F.,"MtextBox")
ที่ msetenabledon
ทำการป้อนคำสั่งดังนี้
_Screen.Activeform.Setall("Enabled",.T.,"MtextBox")
8. ต่อมากำหนด Properties
ในส่วนของเมธอตของ toolbar1 ดังนี้
CmdEdit ที่ Click Event ป้อนคำสั่ง
thisformset.form1.setall("Enabled",.T.,"Mtextbox")
thisformset.form1.Mtextbox1.Enabled=.F.
thisformset.setall("Enabled",.F.,"Mcommandbutton")
thisformset.Toolbar1.cmdSave.Enabled=.T.
thisformset.Toolbar1.cmdCancel.Enabled=.T.
thisformset.form1.Mtextbox2.Setfocus
_SCREEN.ActiveForm.Refresh
คงจะสงสัยว่าทำไมผมให้ป้อนคำสั่งแต่ในเฉพาะ
CmdEdit เท่านั้น
เนื่องจากว่าคำสั่งต่างๆผมได้กำหนดไว้ใน
Visual Class Library เรียบร้อยแล้ว
ซึ่งการกำหนดคำสั่งต่างๆคุณสามารถเข้าไปดูได้ใน
Visual Class Library
9. ให้กำหนด Properties ในส่วนของ
Form1 ดังนี
Init Event ทำการป้อนคำสั่ง
thisform.SetAll("Enabled",.F. ,"Mtextbox")
if recc() > 0
thisformset.toolbar1.cmdtop.click
endif
Activate Event ทำการป้อนคำสั่ง
thisformset.toolbar1.Visible = .T.
thisformset.form1.closable = .T.
thisformset.toolbar1.Dock(0)
select product
thisformset.form1.refresh
Deactivate Event ทำการป้อนคำสั่ง
thisformset.toolbar1.Visible = .F.
ส่วนของการตรวจสอบข้อผิดพลาด
เมื่อคุณได้ทำการสร้างฟอร์มมาถึง
ณ. จุดนี้คุณก็สามารถที่จะ run
ฟอร์มได้แล้ว
แต่ฟอร์มของคุณนั้นก็ยังขาดส่วนที่สำคัญที่สุดไปอีกส่วนหนึ่งก็คือการตรวจสอบข้อผิดพลาด
ก่อนที่เราจะทำการทำในส่วนนี้ผมขออธิบายวิธีการซักหน่อยก่อน
ในการเช็คข้อผิดพลาดนั้นสามารถทำได้หลายแบบหลายวิธี
แต่ที่ผมจะกล่าวถึงนี้จะก็จะเป็นอีกวิธีการหนึ่งในการตรวจสอบขอผิดพลาดที่เกิดขึ้น
ซึ่งจะแบ่งเป็น 2 ส่วนด้วยกันคือ
ส่วนของการเช็คข้อผิดพลาดทั้งหมด
ก่อนการเก็บข้อมูล เนื่องจากว่าลัษณะการทำงานของ
windows นั้นเราจะใช้
เมาส์เป็นหลักจึงทำให้ผู้ใช้งานสามารถไป
ที่ใดก็ได้ใน windows
บางครั้งอาจจะทำการกดปุ่ม
บันทึกข้อมูลทั้งๆที่ไม่ได้ป้อนข้อมูลอะไรไว้เลย
เราจึงทำเป็นที่จะต้องมีส่วนนี้เพื่อดักข้อผิดพลาดที่อาจเกิดขึ้น
ส่วนของการเช็คข้อผิดพลาดระหว่างการป้อนข้อมูล
ในส่วนนี้จะเป็นการเช็คข้อผิดพลาดระหว่างการป้อนข้อมูล
(invalid input)
เช่นในกรณีที่ผู้ใช้ทำการป้อนรหัสสินค้าที่มีอยู่แล้วซ้ำเข้าไปอีก
เราก็สามารถแจ้งเตือนให้ผู้ใช้ทราบได้
ณ. ขณะนั้นได้ทันที เป็นต้น
ส่วนของการเช็คข้อผิดพลาดทั้งหมด
ก่อนการเก็บข้อมูล
10. ให้คุณทำการสร้าง method
ขึ้นมาดังนี้
ที่เมนู Form
เลือก New Method... พิมพ์ชื่อ เมธอตว่า
mcheckerror กดปุ่ม Add แล้วกดปุ่ม Close
เพื่อทำการปิดหน้าต่าง New Method
11.
ทำการป้อนคำสั่งในส่วนของเมธอต
mcheckerror โดยทำการคลิ๊กขวาที่ฟอร์ม
เลือก Properties ใน List box ให้เปลี่ยนจาก Form1
เป็น Formset1 ซึ่งจะอยู่เหนือ Form1
ขึ้นไปอีกบรรทัด
จากนั้นคลิ๊กที่แท๊ป Method
แล้วป้อนคำสั่งในเมธอต mcheckerror
ดังนี้
With ThisFormset.FORM1
if ThisFormSet.m_newrecord
if empty(.mTextBox1.Value)
.mTextBox1.setfocus
messagebox("กรุณาป้อนรหัสสินค้า",288,"")
return .f.
endif
endif
if empty(.mTextBox2.Value)
.mTextBox2.setfocus
messagebox("กรุณาป้อนชื่อสินค้า",288,"")
return .f.
endif
Endwith
return .t.
ในส่วนของการตรวจสอบข้อผิดพลาดนี้จะเป็นการตรวจสอบทั้งฟอร์ม ซึ่งจะเกิดตอนที่ผู้ใช้งานจะทำการเก็บข้อมูล ถ้าต้องการที่จะเพิ่มการเช็คข้อมลูอย่างอื่นอีกคุณก็สามารถเพิ่มเข้าไปในส่วนนี้ได้เลย
ส่วนของการเช็คข้อผิดพลาดระหว่างการป้อนข้อมูล
ในการเช็คข้อผิดพลาดระหว่างการป้อนข้อมูลนั้นมีอยูหลายแบบอีกเหมือนกัน
แต่ที่นิยมใช้กันมากก็คือ
ใช้ในส่วนของ Valid Event
เคล็ดไม่ลับ การตรวจสอบการป้อนข้อมูลซ้ำ (duplicate record) เราสามารถทำได้โดยใช้คำสั่ง TABLEUPDATE() โดยมีหลักอยู่ว่า ถ้าสามารถทำการ update ข้อมูลได้สำเร็จ ค่า TABLEUPDATE() จะเป็น .T. แต่ถ้าไม่สามารถทำการ update ได้ไม่ว่ากรณีใดๆก็ตาม ค่า TABLEUPDATE() จะมีค่าเป็น .F. |
เราจะมาดูว่าจะทำการเช็ครหัสสินค้าที่ได้ป้อนไแล้วอย่างไร
12.
ให้คุณคลิ๊กเมาส์ปุ่มขวาที่
Mtextbox1 เลือก Properties...
แล้วทำการป้อนคำสั่งใน Valid Event
ดังนี้
if .not. tableupdate()
messagebox('มีรหัสสินค้า ' + allt(this.value) +
'นี้อยู่แล้ว')
return 0
endif
13. ทำการ Save
ฟอร์มโดยตั้งชื่อว่า PRODUCT
แล้วลองเรียกฟอร์มขึ้นมาดู
เคล็ดไม่ลับ ใน Valid Event คำสั่ง return เป็นการบอกให้ทราบว่าจะสามารถผ่านออกจากฟิลด์การป้อนข้อมูลนี้ไปได้หรือไม่ ถ้ามีค่าเป็น .T. แสดงว่าสามารถผ่านออกจากฟิลด์ได้ ถ้ามีค่าเป็น .F. แสดงว่าไม่สามารถออกจากฟิลด์นี้ได้แล้วจะขึ้น ข้อความแจ้งว่า Invalid Input ซึ่งเป็นข้อความแจ้งข้อผิดพลาดของ Visual FoxPro เราสามารถทำให้ไม่แสดงได้โดยการใช้ return 0 แทน .F. |
Data Session
ดาต้าเซสชัน(data session)
มันคืออะไรกันแน่ ?
เมื่อก่อนการเขียนโปรแกรม dBASE , Foxbase
จะเป็นงานในลักษณะเปิดโปรแกรมขึ้นมาแล้ก็ทำการป้อนข้อมูล
เพียงอย่างใดอย่างหนึ่งเท่านั้น
เช่นป้อนข้อมูลใบส่งสินค้า
แต่ถ้าเราต้องการป้อนข้อมูลลูกค้า
เราก็ต้องออกจากการป้อนใบส่งสินค้าก่อนแล้วถึงจะค่อยเข้าสู่โปรแกรมป้อนข้อมูลลูกค้า
แต่ในปัจจุบันเมื่อเรามาใช้ Visual
FoxPro
เราสามารถเปิดงานหลายๆงาน(เปิดฟอร์ม)พร้อมกันได้
ปัญหาเรื่องการเปิดปิดไฟล์จึงเกิดขึ้น
เพราะว่าใน Main Visual FoxPro
นั้นยอมให้เราเปิดแฟ้มข้อมูลได้เพียงครั้งเดียว
เช่น ถ้าเราเปิด customer.dbf แล้ว
เราก็ไม่สามารถเปิดได้อีกเป็นต้น
หรือถ้าเราปิดฟอร์มที่มีแฟ้ม
customer.dbf อยู่สักสองฟอร์ม
แล้วปิดไปสักฟอร์มหนึ่ง แฟ้ม
customer.dbf ก็จะถูกปิดไปด้วย
ฟอร์มที่เปิดเหลืออยู่อีกฟอร์มหนึ่งก็จะเกิด
Error (ในกรณี่ที่เรากำหนด properties ใน Data
Environment เป็น AutoClose Table เป็น .T.)
เอาล่ะที่กล่าวมาทั้งหมดเพื่อที่จะทำให้เห็นภาพอย่างคร่าวๆว่าทำไมจึงต้องมี
ดาต้าเซสชัน(data session)
ดาต้าเซสชัน มีอยู่สองประเภทคือ
1. Default Data Session ใน Visual
FoxPro จะกำหนดให้เป็น Defalut
เสมอถ้าเราไม่ทำการเปลี่ยน
2. Private Data Session
จะกำหนดให้การปิดแฟ้มข้อมูลแยกออกจากกันเป็นเอกเทศแต่ละฟอร์มก็จะแยกออกจากกัน
แล้วเราจะกำหนดเป็นแบบใหนดี?
ขอแนะนำว่าให้กำหนดเป็นแบบ Private Data
Session
จะดีกว่าซึ่งจะทำให้เราไม่ต้องกังวลในการสร้างฟอร์ม
หรือเมื่อเราทำการเขียนโปรแกรมในแบบหลายผู้ใช้
(LAN)
เราจะกำหนดดาต้าเซสชัน
ไว้ที่ไหน?
เราจะกำหนดดาต้าเซสชัน ไว้ใน Form
Properties หรือ Formset Properties ในส่วนของ DataSession
มาถึงตอนนี้ผมก็ของให้คุณไปทำการเปลี่ยน
ดาต้าเซสชัน
ที่อยู่ในฟอร์มของโปรแกรมตัวอย่างให้เป็น
Private Data session
ก่อนที่เราจะไปเรียนรู้เรื่อง
ฟอร์มการป้อนข้อมูลที่มีความสัมพันธ์แบบหนึ่งต่อหลายๆเรคคอร์ด
เรามาดูกันในเรื่องเทคนิคและวิธีการใช้งาน
คอนโทล(Control) ต่างๆที่มีอยู่ใน Form Designer
กันก่อน
เทคนิคนำมาเล่าสู่กันฟัง
คุณสามารถนำไปประยุกต์ได้อีกหลากหลายและหลายหลาก
เทคนิคเกี่วยกับ Form
จะทำการ Refresh
ฟอร์มหลายๆฟอร์มพร้อมกันทำอย่างไร
?
ให้ใช้คำสั่ง
FOR I = 1 TO
_SCREEN.FORMCOUNT
_SCREEN.FORMS(I).REFRESH)
ENDFOR
ส่งผ่านค่าออกจากฟอร์ม
ตอนเรียกฟอร์มขึ้นมาใช้งานให้ใช้คำสั่ง
DO FORM MyForm TO MyVar
หลังจากที่ออกจากฟอร์มแล้วเราจะนำค่า
MyVar ไปทำอะไรต่อก็ได้
ในฟอร์มของเราให้กำหนดดังนี้
1. ที่เมนู Form เลือก New Properties
แล้วกำหนดชื่อเป็น MyReturnVar
2. ที่ฟอร์มกำหนด Properties
ในส่วนของ Windowtype เป็น 1
3.
นำค่าที่ต้องการส่งกลับมาใส่ไว้ใน
MyReturnVar
(อันนี้ขึ้นอยู่ว่าคุณจะใ่ส่ไว้ในส่วนใหน่เช่นใน
Click Event ของ Command Button เป็นต้น)
THISFORM.MyReturnVar =
THISFORM.TEXT1.Value
4.
ค่าที่ส่งกลับนำไปใส่ไว้ที่ Form
Properties ในส่วนของ Unload Method
โดยพิมพ์คำสั่ง
RETURN
THISFORM.MyReturnVar
ส่งผ่านค่าเข้าสู่ฟอร์ม
ตอนเรียกฟอร์มขึ้นมาใช้งานให้ใช้คำสั่ง
DO FORM MyForm WITH MyVar
ในฟอร์มของเราให้กำหนดดังนี้
1. ที่ฟอร์มในส่วนของ Init Event
ให้ใ่ส่
PARAMETER MyVar
THISFORM.TEXT1.Value = MyVar
&&
เป็นการนำค่าที่ส่งผ่านมาใส่ไว้ใน
Text1
ส่งผ่านค่าอะเรย์ (Array)
เข้าสู่ฟอร์ม
ตอนเรียกฟอร์มขึ้นมาใช้งานให้ใช้คำสั่ง
DO FORM MyForm WITH MyArray1
ในฟอร์มของเราให้กำหนดดังนี้
1. ที่เมนู Form เลือก New Properties
แล้วกำหนดชื่อเป็น MyArray2(1)
2. ที่ฟอร์มในส่วนของ Init Event
ให้ใ่ส่
PARAMETER MyArray1
DIMENSION
MyArray2(ALEN(MyArray1)) &&
สร้างอะเรย์ขนาดเท่ากับค่าอะเรย์ที่ส่งผ่านเข้ามา
=ACOPY(MyArray1,THIS.MyArray2) &&
ย้ายตัวแปรอะเรย์ที่ส่งผ่านเข้ามาไปไว้ที่ตัวแปรอะเรย์ในฟอร์ม
เทคนิคเกี่ยวกับ Label Control
กำหนดข้อความ(Label) แบบแนวตั้ง
เมื่อคุณทำการสร้าง Label
ขึ้นมาแล้วต้องการให้แสดงในแนวตั้ง(Vertical)
สามารถทำได้ดังนี้
1. ที่ Label Properties ในส่วนของ Caption
พิมพ์
="T" + CHR(13) +
"E" + CHR(13) + "S" + CHR(13) + "T"
2. ที่ Label Properties ในส่วนของ
AutoSize กำหนดเป็น .F.
แล้วทำการปรับขนาดของ Label
ให้แสดงตามต้องการ
เทคนิคเกี่ยวกับ TextBox Control
กำหนดแถบแสงให้กับข้อความ
ในการกำหนดแถบแสงให้กับข้อความใน
textbox นั้นมีอยู่หลายวิธีด้วยกัน
ดังนี้
วิธีแรก
จะเป็นการกำหนดแถบแสดงโดยทั่วๆไป
กำหนดใน textbox properties
ในส่วนของ Format เป็น K และกำหนด
SelectedBackColor เป็น 0,0,128
วิธีที่สอง
จะเป็นการกำหนดแถบแสดงโดยทั่วๆไปเหมือนกันแต่ขี้เกียจกำหนดในทุกๆ
object
กำหนดที่ Form
ในส่วนของ Init Event โดยใช้คำสั่ง Setall
มาช่วย เช่น
THISFORM.SetAll("Format","K","TextBox")
THISFORM.SetAll("SelectedBackColor",RGB(0,0,128),"TextBox")
วิธีที่สาม
กำหนดที่ textbox properties
ในส่วนของ GotFocus Method ดังนี้
IF NOT EMPTY(THIS.Value)
KEYBOARD"{END}"
KEYBOARD"{SHIFT+HOME}"
ENDIF
เทคนิกเกี่ยวกับ Grid Control
ตั้งแต่ Visual FoxPro เป็นต้นมา
กริดก็เป็นพระเอกมาตลอด
ผมพูดแบบนี้คงไม่ผิด
เนื่องจากว่าในการเขียนฟอร์มนั้นกริดเป็นตัวหนึ่งที่มีประโยชน์มาก
สามารถทำงานได้หลายอย่าง
ซึ่งวิธีการใช้งานถ้าดูกันไปลึกๆแล้วมันมีวิธีการมากมายเหลือเกินสุดแต่ผู้เขียนโปรแกรมจะจัดการกับมัน
ในตอนนี้ผมจะสรุปเป็นตัวอย่างให้ดูว่าจะมีวิธีการควบคุมมันอย่างไรโดยจะแยกออกเป็นฉากๆไป
ขอเริ่มด้วยฉากแรกก่อนซึ่งเป็นการทำ
Increment Search หรือโปรแกรมสอบถามข้อมูล
การทำ Increment Search โดยใช้กริด (Download)
การค้นหาข้อมูลใน Visual FoxPro
นั้นมีด้วยกันหลายวิธีหลายแบบ
คุณอาจใช้ combo box หรือ
list box ช่วยก็ได้
แต่สำหรับผมแล้วถ้าข้อมูลมากๆละก็ต้องใช้กริดช่วย
ซึ่งอาจเป็นวิธีโบราณไปสักหน่อยแต่ก็ไม่ล้าสมัยครับ
และมันยังสามารถนำไปประยุกต์ได้มากมายหลายอย่างขึ้นอยู่กับคุณๆทั้งหลาย
ก่อนอื่นคุณจะทำการค้นหาข้อมูลในฟิลด์ใดนั้นคุณต้องไปสร้างดัชนีให้กับฟิลด์นั้นๆก่อน
ในที่นี้ผมจะทำการสร้างโปรแกรมสำหรับค้นหาชื่อลูกค้า
ดังนั้นเราก็ต้องไปทำการสร้างดัชนีให้กับฟิลด์ชื่อลูกค้า
(NAME) โดยทำดังนี้
1.
ให้เรียกโปรเจ็กขึ้นมาแก้ไข
โดยพิมพ์ MODIFY PROJECT MYPROJECT
2.
เข้าไปแก้ไขแฟ้มข้อมูล(table) ของ CUSTOMER
ซึ่งอยู่ใน แท๊ป DATA ในส่วนของ Databases
-> MyDatabase -> Table
3. ที่ Table Designer
ให้คลิ๊กที่แท๊ป Indexes ที่ช่อง Name
ให้พิมพ์ NAME ช่อง Type เลือก Regula ช่อง
Expression พิมพ์ NAME
เสร็จแล้วคลิ๊กที่ปุ่ม OK
เพื่อทำการเก็บข้อมูล
เคล็ดไม่ลับ แก้ปัญหาจัดเรียงลำดับตามภาษาไทยด้วยการเข้าไปกำหนดที่ เมนู Tools เลือก Options... คลิ๊กที่แท๊ป Data ที่ช่อง Collating sequence เปลี่ยนเป็น Thai หรือใช้คำสั่ง SET COLLATE TO "THAI" |
ทีนี้เราก็มาทำการสร้างฟอร์มที่ใช้ในการค้นหาข้อชื่อลูกค้ากันต่อ
1.
ให้คุณทำการสร้างฟอร์มขึ้นมาโดยทำการคลิ๊กที่แท๊บ
Documents แล้วเลือก Form
แล้วทำการคลิ๊กที่ปุ่ม New
แล้วเลือก New Form
2.
ทำการคลิ๊กขวาที่ฟอร์มแล้วเลือกเมนู
Data Environment... เลือกแฟ้มข้อมูล CUSTOMER
แล้วคลิ๊กที่ปุ่ม Add
จากนั้นคลิ๊กที่ปุ่ม Close
3.
คลิ๊กขวาที่แฟ้ม CUSTOMER เลือก Properties
แล้วกำหนด
Order = Name
4. ทำการสร้าง Text box
ขึ้นมา แล้วกำหนด Properties ดังนี้
FontName = MS Sans Serif
High = 23
Width = 300
5. ทำการสร้าง Grid
ขึ้นมา
จากนั้นให้ทำการคลิ๊กปุ่มขวาที่
กริดที่เราได้สร้างขึ้นแล้วเลือก
Builder... จากนั้นให้ทำการเลือกแฟ้ม
CUSTOMER แล้วเลือกฟิลด์ Name และ Cust_ID
แล้วทำการคลิ๊กที่ปุ่ม OK
6. กำหนด properties ของ Grid
ดังนี้
DeleteMark = .F.
FontName = MS Sans Serif
GridLines = 0
Hight = 200
ReadOnly = .T.
RecordMark = .T.
ScrollBar = 2
Width = 350
7. กำหนด properties ของ Grid
-> Column1 ดังนี้
Resizeable = .F.
Width = 280
8. กำหนด properties ของ Grid
-> Column1 -> Header1 ดังนี้
Alignment = 2
Caption = ชื่อลูกค้า
9. กำหนด properties ของ Grid
-> Column1 -> Text1 ดังนี้
ForeColor = 255,255,255
BackColor = 0,0,128
10. กำหนด properties ของ Grid
-> Column2 ดังนี้
Resizeable = .F.
Width = 50
11. กำหนด properties ของ Grid
-> Column2 -> Header1 ดังนี้
Alignment = 2
Caption = รหัส
12. กำหนด properties ของ Grid
-> Column2 -> Text1 ดังนี้
Enabled = .F.
13. ทำการกำหนด method
ดังนี้
ที่ Text1 -> InteractiveChange
Event พิมพ์
SET NEAR ON
SEEK
ALLTRIM(THIS.VALUE)
nRecno = RECNO()
THISFORM.grid1.&cSetBack
THISFORM.grid1.&cSetFore
THISFORM.REFRESH
ที่ Grid1 -> AfterRowColChange
Event พิมพ์
nRecno = RECNO()
THIS.REFRESH
ที่ Grid1 -> Init Event
พิมพ์
PUBLIC nRecno ,
cSetBack , cSetFore
nRecno = RECNO()
cSetBack =
'setall("Dynamicbackcolor","IIF(RECNO()=nRecno,RGB(0,0,128),RGB(255,255,255))","Column")'
&&เป็นการกำหนดสีฉากหลัง
cSetFore =
'setall("Dynamicforecolor","IIF(RECNO()=nRecno,RGB(255,255,255),RGB(0,0,0))","Column")'
&&เป็นการกำหนดสีตัวอักษร
THIS.&cSetBack
THIS.&cSetFore
14. จากนั้นก็ทำการ
save ฟอร์ม ให้ตั้งชื่อเป็น CUSTINQ
แล้วลองเรียกมาดูว่าเป็นอย่างไร
ส่วนคุณจะนำไปประยุกต์อย่างไรนั้นก็ขึ้นอยู่กับความต้องการของคุณ
การนำคอนโทรมาไว้ในกริด (Download)
เราสามารถนำคอนโทรต่างๆมาใส่ไว้ในกริดได้เช่น
Text Box , Combo Box , Edit Box เป็นต้น
ซึ่งมีวิธีการง่ายๆดังต่อไปนี้
1.
ให้คุณทำการสร้างฟอร์มขึ้นมาโดยทำการคลิ๊กที่แท๊บ
Documents แล้วเลือก Form
แล้วทำการคลิ๊กที่ปุ่ม New
แล้วเลือก New Form
2.
ทำการคลิ๊กขวาที่ฟอร์มแล้วเลือกเมนู
Data Environment... เลือกแฟ้มข้อมูล CUSTOMER
แล้วคลิ๊กที่ปุ่ม Add
แล้วก็เลือกแฟ้มข้อมูล Salesman
แล้วคลิ๊กปุ่ม Add
จากนั้นคลิ๊กที่ปุ่ม Close
3. ถ้าใน Data Enviroment
มีการสร้างความสัมพันธ์ระหว่างแฟ้ม
Customer กับ Salesman
ก็ให้เอาออกเพราะเราไม่ได้ใช้
เอาออกได้โดยคลิ๊กเมาส์ที่เส้นโยงความสัมพันธ์ระหว่างแฟ้มแล้วกดปุ่ม
Delete
4. ทำการสร้าง Grid
ขึ้นมา โดยคลิ๊กเมาส์ที่แฟ้ม Customer
ใน Data Environment แล้วลากมาไว้ในฟอร์ม
คุณก็จะได้กริดของ แฟ้ม Customer
5.
จากนั้นให้กำหนด Properties ของ Form1
ดังนี้
Hight = 300
Width = 600
6.
จากนั้นให้กำหนด Properties ของ Grid1
ดังนี้
FontName = MS Sans Serif
RowHight = 30
Left = 15
Hight = 300
Width = 600
ถ้าเราสังเกตดูที่กริดในส่วนของ
Properties
ในคอลัมน์ต่างๆของฟิลด์นั้นจะประกอบไปด้วย
3 ส่วนคือ Column -> Header -> Control
ซึ่งก็เป็นที่มาของเรื่องนี้ไงครับ
7.
จากนั้นให้ทำการนำคอนโทรมาใส่ไว้ที่
Term_Day โดยทำการคลิ๊กขวาที่กริด
แล้วเลือกเมนู Edit
ต่อจากนั้นก็ทำการคลิ๊กที่คอนโทร
Spinner ที่ Form Control
เมื่อทำการคลิ๊กเรียบร้อยก็ทำการคลิ๊กที่ตรงกรอบ
ab| ที่ฟิลด์ Term_Day
เท่านี้คุณก็จะได้คอนโทร Spiner
มาเรียบร้อยโรงเรียนจีน
8.
เนื่องจากตอนนี้ที่คอลัมน์ของ
Term_Day ยังเป็นคอนโทร Text Box
อยู่คุณต้องทำการเปลี่ยนให้เป็นคอนโทร
Spinner โดยทำการกำหนด Properties ของ Column5
ดังนี้
CurrentControl = Spinner1
9. ให้คุณเปลี่ยน
Column6 (ฟิลด์ Sales_ID) ให้เป็นคอนโทร Combo Box
โดยทำการคลิ๊กเมาส์ขวาที่กริด
แล้วเลือกเมนู Edit เหมือนเดิม
แล้วก็ทำคล้ายๆกับข้อ 7
โดยเปลี่ยนเป็น คอนโทร Combo Box แทน
แล้วก็กำหนด CurrentControl ให้เป็น Combo1
10.
เห็นไหมครับว่าการที่เราจะเพิ่มคอนโทรต่างๆเข้ามาในกริดมันไม่ได้ยากอะไรเลย
แต่เมื่อเราทำการเพิ่มคอนโทรเข้ามาแล้วก็ยังมีคอนโทรส่วนเกินที่เราไม่ต้องการเช่น
Text1 ใน Column5 กับ Column6
ถ้าต้องการที่จะลบทิ้งก็สามารถทำได้โดย
ให้คุณเลือกคอนโทรของกริดที่ต้องการลบจาก
properties dialogbox แล้วทำการเลือกคอนโทรจาก
list box ของ properties
ซึ่งตอนนี้เราต้องการลบ ที่ Text1 ใน
Column5 ของกริด ดังรูป
จากนั้นก็ไปทำการคลิ๊กที่ title
ของฟอร์ม แล้ก็กดปุ่ม Delete
เท่านี้ก็เรียบร้อย
(ปล.อธิบายเป็นภาษาเขียนนี่มันยากจริงๆ)
ส่วน คอนโทร Text1 ของ Column6
ก็ทำในลักษณะเดียวกัน
11. ให้คุณกำหนด
properties ของ Spinner1 ในกริดดังนี้
KeyboardHighValue = 999
KeyboardLowValue = 0
SpinnerHighValue = 999
SpinnerLowValue = 0
12. ให้คุณกำหนด
properties ของ Combo1 ในกริดดังนี้
BoundColumn = 1
ColumnCount = 2
ColumnWidths = 0,200
FontName = MS Sans Serif
RowSource = Salesman.Sales_ID , Name
RowSourceType = 6
การทำ header
ของกริดให้สามารถแสดงได้หลายบรรทัด
(เป็นการยืมคอนโทรอื่นมาใช้แทน)
13. ให้คุณกำหนด
properties ของ Grid1 ดังนี้
HeaderHight = 45
14. ให้คุณกำหนด
properties ของ Grid1 -> Column1 -> Header1 ดังนี้
Caption = เคาะ Spacebar หนึ่งครั้ง
15. ให้คุณสร้าง Label
ขึ้นมาแล้วนำมาแปะไว้ที่ส่วนของ
header
ของกริดตามแต่คุณต้องการว่าจะไว้ที่ไหนใน
header แล้วกำหนด properties ของ Label ดังนี้
BackStyle = 0
Caption = ="รหัสลูกค้า"
+ CHR(13) + "Customer ID"
16. จากนั้นก็ทำการ
save ฟอร์ม ให้ตั้งชื่อเป็น CUSTGRD
แล้วลองเรียกมาดูว่าเป็นอย่างไร
การเพิ่ม ลบ แก้ไข
ข้อมูลบนกริด (Download)
และแล้วเราก็มาสู่ส่วนที่สำคัญที่สุดส่วนหนึ่งของ
Visual FoxPro ก็ว่าได้
ถ้าคุณสามารถทำความเข้าใจในหลักการและ
วิธีการที่ผมจะอธิบายในตอนนี้ได้ก็ถือว่าคุณประสบความสำเร็จไปอีกขั้นหนึ่ง
แต่คุณต้องรู้จักประยุกต์อีกนิดหน่อยเพื่อที่จะได้ในสิ่งที่ต้องการ
อธีบายโปรแกรม...ก่อน
ตัวอย่างที่ผมจะนำเสนอต่อไปนี้เป็นเพียงวิธีการหนึ่งเท่านั้น
โดยจะเป็นการแสดงแฟ้มข้อมูลลูกค้า(CUSTOMER)
ขึ้นมาแก้ไข เพิ่ม หรือลบ ก็ได้
ซึ่งจะประกอบไปด้วย Shortcut Menu
โดยการคลิ๊กเมาส์ขวาที่คอลัมน์
รหัสลูกค้า
แล้วจะมีเมนูให้เลือกว่าจะ
เพิ่ม หรือ ลบข้อมูล
ส่วนการแก้ไขข้อมูลนั้นคุณก็สามารถแก้ไขได้ตลอดเวลา
แต่โปรแกรมจะทำการตรวจสอบว่า
ในรายการ(record)
ใดมีการเปลี่ยนแปลง
โปรแกรมจะแสดงข้อความ(message)
เพื่อให้ confirm
ว่าจะเก็บข้อมูลหรือไม่
หรือคุณอาจจะทำการคลิ๊กเมาส์ปุ่มขวาก็จะมีเมนูว่าจะให้
Save หรือ Cancel รายการนั้นๆ
และก็แถมท้ายด้วยการเช็ค Error Duplicate
ของรายการในกริด
1.
ให้คุณทำการสร้าง shotcut menu
ขึ้นมาก่อน (คุณอาจใช้ command button
แทนก็ได้
แต่ผมมีความชอบส่วนตัวเลยอยากให้ทำ)
โดยพิมพ์คำสั่งที่ command window ดังนี้
CREATE
MENU CUSTGRD1
เลือก Shortcut
แล้วทำการกำหนดรายการดังรูป
คลิ๊กที่ปุ่ม Edit ของ Append New Record
แล้วป้อนคำสั่งดังนี้
APPEN BLANK
GO BOTT
_Screen.Activeform.lSkip = .T.
_Screen.Activeform.lAppend = .T.
_Screen.Activeform.Refresh
คลิ๊กที่ปุ่ม Option ของ Append New Record
ในส่วนของ Skip for
ทำการป้อนคำสั่งดังนี้
_Screen.ActiveForm.LSkip && เป็นการ
skip รายการเมนู้เมื่อ LSkip มีค่าเป็น
.T.
คลิ๊กที่ปุ่ม Edit ของ Delete A Record
แล้วป้อนคำสั่งดังนี้
IF MESSAGEBOX("ต้องการลบรายการ
" + Customer.Cust_ID, 292, "")
Delete
=Tableupdate(.T.)
_Screen.ActiveForm.Refresh
ENDIF
คลิ๊กที่ปุ่ม Option ของ Delete A Record
ในส่วนของ Skip for
ทำการป้อนคำสั่งดังนี้
_Screen.ActiveForm.LSkip && เป็นการ
skip รายการเมนู้เมื่อ LSkip มีค่าเป็น
.T.
หลังจากนั้นก็ทำการคลิ๊กที่เมนู
Menu แล้วเลือก Generate...
เพื่อทำการสร้างเมนูโปรแกรม
เมื่อสร้างเสร็จกด Ctrl + W
เพื่อทำการ Save เมนู
2.
ให้คุณทำการสร้าง shotcut menu
ขึ้นมาอีกตัว โดยพิมพ์คำสั่งที่
command window ดังนี้
CREATE
MENU CUSTGRD2
เลือก Shortcut
แล้วทำการกำหนดรายการดังรูป
คลิ๊กที่ปุ่ม Edit ของ Save
แล้วป้อนคำสั่งดังนี้
=Tableupdate(.T.)
_Screen.ActiveForm.LSkip = .F.
_Screen.Activeform.lAppend = .F.
คลิ๊กที่ปุ่ม Edit ของ Cancel
แล้วป้อนคำสั่งดังนี้
=Tablerevert(.T.)
_Screen.ActiveForm.LSkip = .F.
_Screen.Activeform.lAppend = .F.
หลังจากนั้นก็ทำการคลิ๊กที่เมนู
Menu แล้วเลือก Generate...
เพื่อทำการสร้างเมนูโปรแกรม
เมื่อสร้างเสร็จกด Ctrl + W
เพื่อทำการ Save เมนู
3.
เมื่อคุณทำการสร้าง shortcut menu
เรียบร้อยแล้วให้คุณทำการเรียกฟอร์ม
CUSTGRD ที่ได้สร้างไว้ขึ้นมาแก้ไข
โดยพิมพ์คำสั่ง
MODIFY FORM CUSTGRD
4.
ทำการคลิ๊กเมาส์ปุ่มขวาที่ฟอร์ม
แล้วเลือกรายการ Data Environment...
ทำการคลิ๊กเมาส์ปุ่มขวาที่ table CUSTOMER
แล้วเลือกรายการ Properties...
แล้วกำหนดค่าดังนี้
BufferModeOverride = 5
เพราะในการทำงานที่เกี่ยวกับการปรับปรุงข้อมูลโดยใช้
คำสั่ง TABLEUPDATE() เราจำเป็นต้องกำหนด
tabel เป็นแบบ buffer เสมอ
5. ทำการสร้าง
property โดยเลือกที่เมนู Form
แล้วคลิ๊กที่ New Property... ป้อน
nRecNum คลิ๊กปุ่ม Add
nWhatRow คลิ๊กปุ่ม Add
LAppend คลิ๊กปุ่ม Add
LSkip คลิ๊กปุ่ม Add แล้วคลิ๊กปุ่ม Close
อีกครั้ง
6. ทำการสร้าง method
โดยเลือกที่เมนู Form แล้วคลิ๊กที่
New Method... ป้อน
mShortcut คลิ๊กปุ่ม Add
แล้วคลิ๊กปุ่ม Close อีกครั้ง
7.
คลิ๊กขวาที่ฟอร์ม เลือกรายการ
Properties แล้วกำหนด คุณสมบัติของ Form
ดังนี้
nRecNum = 0
nWhatRow = 0
LAppend = .F.
LSkip = .F.
ส่วนเมธอต mShortcut ป้อนคำสั่งดังนี้
cChange =
GetFldState(-1,"Customer")
IF
AT('2', cChange) > 0 .OR. AT('4', cChange) > 0
DO CUSTGRD2.MPR
ELSE
DO CUSTGRD1.MPR
ENDIF
8. ที่ Form
ในส่วนของ Init Event ป้อนคำสั่ง SET DELETE ON
ทำการเช็คว่ามีการป้อนข้อมูลในรายการ(record)
9. ที่ Grid1 ในส่วนของ
AfterRowColChange ป้อนคำสั่งดังนี้
LPARAMETERS nColIndex
IF ThisForm.lAppend
ThisForm.nWhatRow = This.ActiveRow
ThisForm.lAppend = .F.
ELSE
lMov = .F.
IF ThisForm.nWhatRow # This.ActiveRow
ThisForm.nWhatRow = This.ActiveRow
nHold= RECNO()
GO ThisForm.nRecNum
cChange = GetFldState(-1,'Customer')
IF AT('2', cChange)>0 .or. AT('4',cChange) > 0
This.Refresh
lMov = .T.
IF MessageBox("Update Record",4)= 6
=TableUpdate(.T.)
ELSE
=TableRevert(.T.)
ENDIF
ThisForm.lSkip = .F.
ELSE
IF AT('4',cChange) = 0 .and. AT('1',cChange) = 0
= TableRevert(.T.)
ThisForm.nRecNum = nHold
ThisForm.lSkip = .F.
ENDIF
ENDIF
GO nHold
IF lMov
lMov =.F.
ENDIF
ENDIF
ENDIF
This.Refresh
แนะนำคำสั่ง ในการกระทำกับ record
ที่เรากำหนดตารางเป็นแบบบับเฟอร์(table
buffer)
นั้นเราจะทราบได้อย่างไรว่ามีการเพิ่มเรคคอร์ด
ลบเรคอร์ด แก้ไขฟิลด์ ใดๆบ้าง
เพื่อที่เราจะได้ทำการปรับปรุงข้อมูลที่ถูกต้องเข้าสู่ตาราง
(TABLEUPDATE) Visual FoxPro
ได้มีคำสั่งเตรียมไว้ให้เราเรียบร้อยแล้วซึ่งก็คือ
GETFLDSTATE() รูปแบการใช้งาน GETFLDSTATE(cFieldName | nFieldNumber [, cTableAlias | nWorkArea]) หลังจากที่ทำการเรียกใช้งานคำสั่งแล้วจะส่งค่ากลับมาเป็นตัวเลข ซึ่งมาค่าอยู่ระหว่าง 1 ถึง 4 1 = บอกให้รู้ว่าฟิลด์นี้ยังไม่มีการแก้ไข 2 = บอกให้รู้ว่าฟิลด์นี้ได้มีการแก้ไขข้อมูล หรือ ลบเรคคอร์ด 3 = จะเป็นสถานะของการเพิ่มข้อมูล และยังไม่มีการป้อนข้อมูลเข้าไป 4 = จะเป็นสถานะของการเพิ่มข้อมูล และได้มีการป้อนข้อมูลเข้า หรือ ลบเรคคอร์ด nFieldNumber ถ้ามีค่า -1 จะเป็นการแสดงสถานะของทั้งเรคคอร์ด เช่นค่าที่ได้จะเป็น 121121 โดยที่ค่าตัวแรกจะหมายถึงว่าเรคคอร์ดนั้นๆได้ถูกลบออกไปหรือไม่ ส่วนค่าถัดไปแสดงถึงฟิลด์ต่างว่าเปลี่ยนแปลงหรือไม่ ตัวอย่าง ให้คุณทำการเรียกแฟ้มข้อมูล ลูกค้าขึ้นมา โดยพิมพ์คำสั่งที่ command window ดังนี้ SET MULTILOCKS ON USE CUSTOMER =CURSORSETPROP("BUFFERING",5,"CUSTOMER") GO 2 DELETE ?GETFLDSTATE(-1,"CUSTOMER") && โปรแกรมจะแสดงค่า 2111111 GO 1 REPLACE NAME WITH "abc" ?GETFLDSTATE(-1,"CUSTOMER") && โปรแกรมจะแสดงค่า 1121111 บอกให้ทราบว่าฟิลด์ NAME ได้ถูกแก้ไข ?GETFLDSTATE("NAME") && โปรแกรมจะแสดงค่า 2 บอกให้ทราบว่าฟิลด์ NAME ได้มีการแก้ไข APPEN BLANK ?GETFLDSTATE(-1) && โปรแกรมจะแสดงค่า 3333333 บอกให้ทราบว่ามีการเพิ่มเรคคอร์ดใหม่และยังไม่มีการแก้ไข TABLEREVERT(.T.) && ยกเลิกสิ่งที่เราทำไปทั้งหมด |
9. ที่ Grid1
ในส่วนของ BeforeRowColChange ป้อนคำสั่ง
IF EOF()
GO BOTT
ENDIF
ThisForm.nRecNum = RECNO()
10. ที่ Grid1 ในส่วนของ
Init ป้อนคำสั่ง ThisForm.nRecNum = RECNO()
11. ที่ Grid1 ในส่วนของ
RightClick ป้อนคำสั่ง =thisform.MShortcut()
12. ที่ Grid1 ในส่วนของ
Column1->Text1 ใน RightClick ป้อนคำสั่ง =thisform.MShortcut()
13.
เมื่อคุณทำเสร็จแล้วให้ทำการเก็บฟอร์มนี้เป็นชื่อใหม่
โดยการคลิ๊ก เมนู File เลือก Save As
แล้วพิมพ์ชื่อเป็น CUSTGRD1
คลิ๊กที่ปุ่ม Save
จากนั้นก็ลองเรียกฟอร์มขึ้นมาลองป้อนข้อมูลดู
ส่วนการเช็ค Duplicate Record
ก็ใช้วิธีเดียวกันกับตัวอย่างข้างต้น
ที่ใช้ IF .NOT. TABLEUPDATE()
การสร้างฟอร์มแบบที่มีความสัมพันธ์หนึ่งต่อหลาย
(one to meny) Download
หลังจากที่คุณได้ทำการเรียนรู้วิธีการสร้างฟอร์มแบบต่างๆไปบ้างแล้ว
ต่อมาในส่วนนี้ก็จะกล่าวถึงหลักและวิธีการสร้างฟอร์ม
one to meny
ในตัวอย่างต่อไปนี้สอนการทำใบส่งสินค้า
(invoice) ซึ่งจะประกอบไปด้วยตาราง(table)
หลายๆตารางมาเชื่อมความสัมพันธ์กัน(relation)
เอาละครับเรามาเริ่มกันเลยแล้วกัน
ให้คุณทำการป้อนคำสั่งที่ command windows
ดังนี้
CLOSE ALL
OPEN DATABASE MYDATABASE
CREATE FORM INVOICE
แล้วเข้าไปกำหนด property
ของฟอร์มในส่วนของ Load Event
โดยป้อนคำสั่ง SET DELETE ON
ทำการสร้าง Property โดยเข้าไปที่เมนู
Form แล้วเลือก New Property ป้อนชื่อ LNew
เมื่อคุณทำการสร้างฟอร์มแล้วให้คุณทำตามขั้นตอนต่อไปนี้
กำหนดความสัมพันธ์ของตาราง
1.
ทำการคลิ๊กเมาส์ปุ่มขวาที่ฟอร์มแล้วเลือก
Data Enviroment...
2.ที่ Data enviroment
ให้ทำการคลิ๊กเมาส์ปุ่มขวาแล้วเลือก
Add...
คลิ๊กที่ตาราง INV_HEAD แล้วคลิ๊กปุ่ม
Add
คลิ๊กที่ตาราง INV_DTL แล้วคลิ๊กปุ่ม
Add
คลิ๊กที่ตาราง CUSTOMER แล้วคลิ๊กปุ่ม
Add
คลิ๊กที่ตาราง PRODUCT แล้วคลิ๊กปุ่ม
Add แล้วคลิ๊กที่ปุ่ม Close อีกที
3.
ถึงตอนนี้คุณก็จะได้ตารางข้อมูล
และก็มีเส้นเชื่อมโยงความสัมพันธ์แสดงอยู่ที่
Data Environment
ผมอยากให้คุณเอามันออกให้หมดก่อน
โดยทำการคลิ๊กเมาส์ที่เส้นเชื่อมโยงความสัมพันธ์แล้วกดปุ่ม
Del ที่ keyboard
4.
ตอนนี้เรามาสำรวจความสัมพันธ์ระหว่างตารางกันก่อนว่าอะไรควรจะเชื่อมกับอะไร
ตาราง INV_HEAD เชื่อมกับตาราง INV_DTL
โดยใช้ฟิลด์ INV_NO
ตาราง INV_HEAD เชื่อมกับตาราง CUSTOMER
โดยใช้ฟิลด์ CUS_ID
ตาราง INV_DTL เชื่อมกับตาราง PRODUCT
โดยใช้ฟิลด์ PROD_ID
5.
การโยงความสัมพันธ์ระหว่างตารางนั้นทำได้โดยการคลิ๊กที่ฟิลด์ในตารางแม่(parent)
แล้วลากไปวางที่ฟิลด์ในตารางลูก(child)
ให้คุณทำดังนี้
คลิ๊กที่ฟิลด์ INV_NO ในตาราง INV_HEAD
แล้วทำการลากไปวางไว้ที่ ฟิลด์
INV_NO ของตาราง INV_DTL
คลิ๊กที่ฟิลด์ CUS_ID ในตาราง INV_HEAD
แล้วทำการลากไปวางไว้ที่ ฟิลด์
CUS_ID ของตาราง CUSTOMER
คลิ๊กที่ฟิลด์ PROD_ID ในตาราง INV_DTL
แล้วทำการลากไปวางไว้ที่ ฟิลด์
PROD_ID ของตาราง PRODUCT
ข้อควรจำ ในการกำหนดความสัมพันธ์ให้กับตารางใดๆนั้น เราต้องกำการสร้างแฟ้มดัชนี(index) ให้กับฟิลด์ในตารางลูก (child table) ที่เราจะทำการเชื่อมโยงก่อนเสมอ |
6.
จากนั้นให้กำหนด property
ของแต่ละตาราง
โดยทำการคลิ๊กเมาส์ที่ปุ่มขวาของตารางแล้วเลือก
Properties... ให้กำหนด property
ของแต่ละตารางดังนี้
ตาราง INV_HEAD
BufferModeOverried = 2
Order = INV_NO
ตาราง INV_DTL
BufferModeOverried = 4
Order = INV_NO
ตาราง CUSTOMER
Order = CUST_ID
ตาราง PRODUCT
Order = PROD_ID
สร้างฟอร์มตามตัวอย่าง
6. ทำการสร้าง
Command Button ตัวแรกแล้วกำหนด property ดังนี้
Caption
= เพิ่มใบส่งสินค้า
Name
= CmdAppend
Click
Event ป้อนคำสั่งดังนี้
thisform.lNew = .T.
sele inv_head
go bott
nInv_No = inv_head.inv_no + 1
INSERT INTO INV_HEAD (inv_no,date) ;
VALUES (nInv_no,date())
with thisform
.txtDate.Enabled = .T.
.txtCust_id.Enabled = .T.
.txtDate.setfocus
.cmdAppend.Enabled = .F.
.cmdChange.Enabled = .F.
.cmdSave.Enabled = .T.
.cmdCancel.Enabled = .T.
.Grid1.Enabled = .T.
.Grid1.Column1.Text1.Enabled = .F.
.Grid1.Column5.Text1.Enabled = .F.
.cmdAppendItem.Enabled = .T.
.cmdDeleteItem.Enabled = .T.
.refresh
endwith
7. ทำการสร้าง Command
Button ตัวที่สองแล้วกำหนด property ดังนี้
Caption
= แก้ไขใบส่งสินค้า
Name
= CmdChange
Click
Event ป้อนคำสั่งดังนี้
thisform.lNew = .F.
with thisform
.txtDate.Enabled = .T.
.txtCust_id.Enabled = .T.
.txtDate.setfocus
.cmdAppend.Enabled = .F.
.cmdChange.Enabled = .F.
.cmdSave.Enabled = .T.
.Grid1.Enabled = .T.
.Grid1.Column1.Text1.Enabled = .F.
.Grid1.Column5.Text1.Enabled = .F.
.cmdAppendItem.Enabled = .T.
.cmdDeleteItem.Enabled = .T.
.refresh
endwith
8. ทำการสร้าง Command
Button ตัวที่สามแล้วกำหนด property ดังนี้
Caption
= บันทึกใบส่งสินค้า
Name
= CmdSave
Enabled
= .F.
Click
Event ป้อนคำสั่งดังนี้
sele inv_head
=tableupdate(.F.)
sele inv_dtl
=tableupdate(.T.)
sele inv_head
with thisform
.txtDate.Enabled = .F.
.txtCust_id.Enabled = .F.
.combo1.setfocus
.cmdAppend.setfocus
.cmdAppend.Enabled = .T.
.cmdChange.Enabled = .T.
.cmdSave.Enabled = .F.
.cmdCancel.Enabled = .F.
.cmdAppendItem.Enabled = .F.
.cmdDeleteItem.Enabled = .F.
.Grid1.Enabled = .F.
.refresh
endwith
9. ทำการสร้าง Command
Button ตัวที่สี่แล้วกำหนด property ดังนี้
Caption
= ยกเลิก
Name
= CmdCancel
Enabled
= .F.
Click
Event ป้อนคำสั่งดังนี้
sele inv_head
=tablerevert(.T.)
sele inv_dtl
=tablerevert(.T.)
sele inv_head
if eof() .and. Thisform.lNew
GO BOTT
endif
with thisform
.txtDate.Enabled = .F.
.txtCust_id.Enabled = .F.
.combo1.setfocus
.cmdAppend.setfocus
.cmdAppend.Enabled = .T.
.cmdChange.Enabled = .T.
.cmdSave.Enabled = .F.
.cmdCancel.Enabled = .F.
.cmdAppendItem.Enabled = .F.
.cmdDeleteItem.Enabled = .F.
.refresh
endwith
10.
ให้คุณทำการลากฟิลด์ใน Data Environment
ของตาราง INV_HEAD
แล้วนำมาว่างไว้ที่ฟอร์ม
โดยทำการลากมาทีละฟิลด์
เริ่มจาก INV_NO, DATE, CUST_ID
11.
ต่อจากนั้นให้ลากฟิลด์ NAME
ที่ตาราง CUSTOMER
แล้วมาวางไว้บนฟอร์ม
ทำการตกแต่งตามชอบใจ
แล้วทำการกำหนด Properties ของแต่ละ object
txtInv_no
กำหนด property ดังนี้
Enabled = .F.
txtDate
กำหนด property ดังนี้
Enabled
= .F.
Format = E
txtCust
กำหนด property ดังนี้
Enabled
= .F.
ป้อนคำสั่งที่ Valid Event ดังนี้
=SEEK(this.Value,"Customer")
thisform.refresh
txtName
กำหนด property ดังนี้
Enabled = .F.
12.
ต่อจากนั้นให้ลากฟิลด์ NAME
ที่ตาราง CUSTOMER
แล้วมาวางไว้บนฟอร์ม กำหนด property
ดังนี้
Enabled
= .F.
13. ให้ไปที่ Data Environment
แล้วทำการลากตาราง INV_DTL
นำมาวางไว้บนฟอร์ม คุณก็จะได้
กริดของตาราง INV_DTL แล้วกำหนด property
ของ กริดดังนี้
AllowHeaderSizing
= .F.
AllowRowSizing
= .F.
DeleteMark
= .F.
Enabled
= .F.
ScrollBars
= 2
SplitBar
= .F.
14.
ตอนนี้คุณก็จะได้กริดมาอยู่บนฟอร์มแล้ว
แต่ column
ในกริดยังไม่เป็นฟิลด์ที่เราต้องการ
ฉะนั้นเราจะทำการจัดการกับมันก่อน
สิ่งที่เราต้องการให้มีอยู่บนกริดจะประกอบไปด้วย
รหัสสินค้า(PROD_ID), ชื่อสินค้า(NAME),
จำนวน(QUANTITY), ราคาต่อหน่วย(UNITPRICE),
รวมจำนวนเงิน(QUANTITY * UNITPRICE)
ลบคอลัมน์ออกจากกริด
15.
ทำการลบคอลัมน์ที่ไม่ต้องการออกก่อน
โดยการคลิ๊กปุ่มขวาที่กริดแล้วเลือก
Edit จากนั้นให้คลิ๊กที่ ab|
ของคอลัมน์ INV_NO
จากนั้นก็ทำการกดปุ่ม Del ที่ keyboard
โปรแกรมจะถามว่า Remove column and all contained objects?
ให้กดปุ่ม Yes
เพิ่มคอลัมน์ในกริด
16.
ให้คุณทำการคลิกเมาส์ที่ฟอร์มหนึ่งครั้งเพื่อออกจากการ
Edit กริดก่อน
แล้วทำการคลิ๊กเมาส์ปุ่มขวาที่กริดอีกครั้ง
เลือก Properties แล้วกำหนด
ColumnCount = 5
17.
มาถึงตรงนี้คุณก็จะได้คอลัมน์จำนวน
5 คอลัมน์
สำรวจว่าแต่ละคอลัมน์มีอะไรบ้าง
COLUMN2 ->
ControlSource = inv_dtl.prod_id
COLUMN3 ->
ControlSource = inv_dtl.quantity
COLUMN4 ->
ControlSource = inv_dtl.unitprice
COLUMN1 ->
ControlSource = (none)
COLUMN5 ->
ControlSource = (none)
18.
ให้ทำการเข้าไปที่ property ของ COLUMN1
แล้วกำหนดดังนี้
ControlSource = product.name
ColumnOrder = 2
19.
ให้ทำการเข้าไปที่ property ของ COLUMN2
แล้วกำหนดดังนี้
ControlSource = inv_dtl.quantity * inv_dtl.unitprice
สร้าง combobox
เพื่อใช้ในการเลือกใบ invoice มาแสดง
20. ให้ทำการสร้าง
Combobox ขึ้นมา 1
ตัวแล้วนำไปวางไว้ใกล้ๆกับ texInv_no
แล้วกำหนด property ดังนี้
High = 25
RowSource = inv_head
RowSourceType = 2
Width = 20
Click Event ป้อนคำสั่ง Thisform.Refresh
21. การสร้าง Command Button
ขึ้นมาสองตัว แล้วกำหนด property
ดังนี้
ตัวแรก กำหนด property ดังนี้
Caption = เพิ่มรายการสินค้า
Enabled = .F.
Name = CmdAppendItem
FontName = MS Sans Serif
Click Event ป้อนคำสั่ง
sele inv_dtl
INSERT INTO inv_dtl (inv_no) ;
VALUES (inv_head.Inv_no)
go bott
with thisform.grid1
.column2.setfocus
.refresh
endwith
ตัวที่สอง กำหนด property ดังนี้
Caption = ลบรายการสินค้า
Enabled = .F.
Name = CmdDeleteItem
FontName = MS Sans Serif
Click Event ป้อนคำสั่ง
sele inv_dtl
delete
sele inv_head
thisform.combo1.setfocus
thisform.grid1.column2.setfocus
thisform.refresh
คำนวณผลรวมของใบส่งของ
22.
ให้คุณทำการสร้าง Text Box
ขึ้นมาสำหรับแสดงผลรวมของใบส่งของ
แล้วกำหนด property ดังนี้
Enabled = .F.
Inputmark =
999,999,999.99
Left = 423
Top = 300
23. ทำการสร้าง method
ขึ้นมา โดยคลิ๊กที่ เมนู Form
แล้วเลื่อก New Method...
ทำการป้อนชื่อเมธอตว่า InvoiceTotal
กดปุ่ม Add แล้วกดปุ่ม Close
ต่อจากนั้นทำการป้อนคำสั่งของ
เมธอต Form1 -> InvoiceTotal ดังนี้
Select Inv_dtl
Calculate Sum(Inv_dtl.Quantity*Inv_dtl.UnitPrice) ;
For Inv_dtl.inv_no = Thisform.txtinv_no.value ;
To Thisform.text1.value
Select Inv_head
* หมายเหตุ
ในส่วนของ
เมธอตนี้คุณจะเพิ่มคำสั่งในการคำนวณอื่นๆก็ได้แล้วแต่ความต้องการ
24.
ทำการป้อนคำสั่งทึ่ Grid1
ในส่วนของเมธอต Refresh
=Thisform.InvoiceTotal()
25.
ทำการป้อนคำสั่งทึ่ Grid1 -> Column3 -> Text1
ในส่วนของเมธอต LostFocus
Local
nChange
nChange = Getfldstate("Quantity","Inv_dtl")
IF
nChange # 1 .and. nChange # 3
=Thisform.InvoiceTotal()
ENDIF
25.
ทำการป้อนคำสั่งทึ่ Grid1 -> Column3 -> Text1
ในส่วนของเมธอต LostFocus
Local
nChange
nChange = Getfldstate("Unitprice","Inv_dtl")
IF
nChange # 1 .and. nChange # 3
=Thisform.InvoiceTotal()
ENDIF
เมื่อคุณกำหนดเสร็จเรียบร้อยก็ทำการ
Save
แล้ลองเรียกโปรแกรมดูคุณก็จะเข้าใจหลักการของการทำฟอร์มแบบหนึ่งต่อหลาย
(one to meny)
ลากแล้ววาง
(Drag & Drop)
ตั้งแต่เริ่มมีโปรแกรม Windows
เกิดขึ้นมา เราก็ได้รู้จักคำว่า
Drag & Drop กันอยู่เสมอ
ซึ่งก็คือการลากวัตถุหนึ่งจากที่หนึ่งไปวาง
ณ. ตำแหน่งที่ต้องการ
สำหรับโปรแกรม Visual FoxPro
ก็ได้บรรจุคำสั่งประเภทนี้ไว้ให้ด้วยเหมือนกัน
โดยที่วิธีการทำนั้นก็ขึ้นอยู่กับว่าเราทำกับคอนโทรลประเภทใด
สำหรับตัวอย่างแรกที่จะนำเสนอต่อไปนี้จะเป็นการ
ลากแล้วว่าแบบประถม
โดยจะทำการลากจาก คอนโทรล textbox
ไปที่ textbox อีกตัวหนึ่ง ดังนี้
1.
ให้คุณทำการสร้างฟอร์มขึ้นมาโดยทำการคลิ๊กที่แท๊บ
Documents แล้วเลือก Form
แล้วทำการคลิ๊กที่ปุ่ม New
แล้วเลือก New Form
2.
ทำการคลิ๊กขวาที่ฟอร์มแล้วเลือกเมนู
Data Environment... เลือกแฟ้มข้อมูล CUSTOMER
แล้วคลิ๊กที่ปุ่ม Add
จากนั้นคลิ๊กที่ปุ่ม Close
3. ทำการสร้าง TextBox
ขึ้นมา 1 ตัว โดยการคลิ๊กที่ TextBox ใน
Form Control
แล้วก็มาทำการคลิ๊กที่ฟอร์ม
ทำการป้อนคำสั่งของ
Event Method ของ Text1->DragDrop ดังนี้
LPARAMETERS
oSource, nXCoord, nYCoord
This.Value
= oSource.Value
4. ทำการสร้าง Grid
ขึ้นมา โดยคลิ๊กเมาส์ที่แฟ้ม Customer
ใน Data Environment แล้วลากมาไว้ในฟอร์ม
คุณก็จะได้กริดของ แฟ้ม Customer
ทำการป้อนคำสั่งของ
Event Method ของ Grid1->Column1->Text1->MouseDown ดังนี้
LPARAMETERS
nButton, nShift, nXCoord, nYCoord
This.Drag(1)
5.
จากนั้นก็กดปุ่ม Ctrl-E เพื่อทำการ Save
ฟอร์มแล้วก็ Run ฟอร์ม
จากตัวอย่างข้างต้นเราจะเห็นว่า DragDrop Event จะเป็นตัวรับค่าที่ได้จากการ Drop ส่วน การกำหนดให้ object ตัวใดสามารถทำการ Drag ได้นั้นเราจะป้อนคำสั่งไว้ที่ MouseDown Event โดยใช้คำสั่ง Drag(1) เป็นตัวกำหนด