Download - เริ่มต้นกับ Visual Foxprosongkwae.com/foxdownload/เริ่มต้น... · Web viewการสร างระบบงานข นมาส กหน
เรมตนกบ Visual Foxpro การสรางระบบงานขนมาสกหนงระบบนน จำาเปนอยางยงทจะ
ตองมการเขยนโปรแกรมมาควบคมการทำางานของสวนตางๆ ใหเปนไปตามความตองการของผใชงาน ในการเขยนโปรแกรมแตละภาษาจะมวธการเขยนแตกตางกนออกไป แตโดยหลกการแลวไมวาคณจะทำาการเขยนโปรแกรมดวยภาษาอะไรกตามคำาสงและฟงกชนจะไมเหมอนกนซกทเดยว แตหลกและวธการเขยนโปรแกรมจะเปนในแนวทางเดยวกนในยคปจจบนนวธการเขยนโปรแกรม ไดพฒนาไปเปนการเขยนโปรแกรมเชงวตถ (Object-Oriented Programming OOP) ซงกอนหนานเราเคยชนกบการเขยนโปรแกรม แบบโครงสราง(Structure Programming) จะสงเกตไดวาพฒนาการดานโปรแกรมไดมความกาวหนาขนเรอยๆ ซงจะอำานวยความสะดวกในการเขยนโปรแกรมใหแกผพฒนาระบบงานมากยงขนกวาเมอกอน Visual FoxPro กเปนอกหนงโปรแกรมทไดพฒนามาจนกระทงเปนโปรแกรมแบบ OOP ซงกอนจะพฒนามาเปน Visual FoxPro นนโปรแกรมไดพฒนาเรมตนมาจาก FoxBase, FoxPro แลวกมาถง Visual FoxPro ทเรากำาลงกลาวถงอยน
เรมเขยนโปรแกรมแรก เมอคณเขาสโปรแกรม Visual FoxPro แลว ใหคณสรางโปรแกรม
ตามตวอยางดงน 1. จากเมน File เลอกคำาสง New 2. เลอก Program 3. พมพชอโปรแกรม วา Program1
หรอ ทำาการพมพคำาสงผานทาง Command Window โดยพมพ คำาสง MODIFY COMMAND Program1 แลวกดปม Enter
เคลดไมลบ ตอนเขาสโปรแกรมถาไมตองการให Visual FoxPro แสดงโลโกขนมาใหใสparameter -T ไวขางหลง VFP.EXE -T
Visual FoxPro จะทำาการสรางหนาตางขนมาใหโดยมชอวา Program1 ซงกคอชอไฟล ถงตอนนคณกทำาการปอนคำาสงตามตวอยางเขาไปไดเลย * Program1 #DEFINE myProgram "โปรแกรมของฉน" PRIVATE nVAR myForm = CREATEOBJECT("TestForm") myForm.Show STORE 1 TO nVAR DO WHILE nVAR <= 300 myForm.Height = nVAR myForm.Width = nVAR nVAR = nVAR + 1 ENDDO FOR nVAR = 4 to 400 STEP 4 myForm.left = nVAR myForm.top = nVAR / 4 ENDFOR && NEXT READ EVENTS
DEFINE CLASS Testform AS FORM Caption = myProgram Left = 1 Top = 1 Height = 1 Width = 1
ADD OBJECT MyButton AS CommandButton WITH ; Caption = "Cancel", Forecolor = RGB(255,0,0), ; Left = 100, Top = 120, Height = 30, Width = 100 * Define the command button myButton Click event method
2
PROCEDURE myButton.Click RELEASE THISFORM CLEAR EVENTS ENDPROC ENDDEFINEหลงจากทปอนเสรจเรยบรอยแลว ใหทำาการบนทกโปรแกรม โดยการกดปม Ctrl-W หรอ จากเมน File เลอกคำาสง Save กได ตอนนเรากสามารถเรยกโปรแกรมขนมาใชงานไดแลวโดย 1. จากเมน Program เลอกคำาสง Do 2. เลอกโปรแกรมทตองการ ซงกคอ Program1 แลวคลกทปม DO หรอ ทำาการพมพคำาสงผานทาง Command Window โดยพมพ คำาสง DO Program1 แลวกดปม Enter ถงตอนนถาคณทำาสำาเรจคณกจะไดเหนหนาตางขยาย แลวกเคลอนทได กขอแสดงความยนดกบคณดวย ในตอนนคณยงไมตองไปสนใจวาโปรแกรมนมคำาสงอะไรทำาไมถงเขยนแบบเดกๆ ซงคำาสงและวธการตางๆ ผมจะทำาการอธบายใหเขาใจในตอนตอๆไป ในกรณทคณตองการแกไขโปรแกรม 1. จากเมน File เลอกคำาสง Open 2. เปลย file of type เปน Program 3. เลอกโปรแกรมทตองการ แลวคลกปม OK หรอ ทำาการพมพคำาสงผานทาง Command Window โดยพมพ คำาสง MODIFY COMMAND Program1 แลวกดปม Enter เอาละเขยนโปรแกรมเปนแลวละซ ตอจากนไปเราจะมาดถงวธการและประเภทของขอมลใน Visual FoxPro กน ซงประกอบไปดวย
3
ประเภทของขอมลและฟลด (Data and Field Types) การเกบคาของขอมล (Storing Data) โอเปอเรเตอร (Operators) การสรางนพจน (Building Expressions) ประเภทของขอมลและฟลด (Data and Field Types) การเกบขอมลตางๆ ลงแฟมขอมล เราจำาเปนตองทราบวาลกษณะของขอมลทเราจะเกบนนคออะไร ควรจะเกบเปนแบบใด เพอใหตรงกบความตองการมากทสด ประเภทขอมลใน Visual FoxPro
Data Type Description Size Range
Character Any Text
1 Byte per Character
Any Characters
Currency
Monetary amounts 8 Bytes
-92222337203685477.5808 to 922337203685477.5807
Date
Chronological data Consisting of Month, Year and Date
8 Bytes 01/01/100 to 12/31/9999
DateTime
Chronological data Consisting of Month, Year ,Date and Time
8 Bytes01/01/100 to 12/31/9999, plus 00:00:00 a.m. to 11:59:59 p.m.
Logica Value of true 1 Byte True(.T.) or
4
l Boolean
or false False(.F.)
Numeric
Integers or Fractions
8 Bytes in Memory; 1-20 Bytes in table
-9999999999E+19 to .9999999999E+20
แฟมขอมลของ FoxPro จะมนามสกลวา .DBF เพอใหทนสมยหนอย ใน Visual FoxPro เลยเรยกแฟม DBF วา Table เหนทไหนกอยาไปแปลกใจ มนกคอกนเดอ ประเภทของฟลดใน Visual FoxPro
Field TypeDescription Size Range
Double
A double-precision Floating-point number
8 bytes+/-4.94065645841247E-324
Float Same as Number
8 bytes in Memory:1-20 Bytes in table
-.9999999999E+19 to .9999999999E+20
General
Reference to an OLE Object
4 bytes in table
Limited by available memory
Integer
Interger values 4 bytes -2147483647 to
2147483647 Memo
Reference to a block of data
4 bytes in table
Limited by available memory
5
เคลดไมลบ คณสามารถใชฟงกชน TYPE() เพอแสดงประเภทของขอมลทเกบได การเกบขอมล (Storing Data) การเกบขอมลของคณนนคณควรคำานงถงการเกบขอมลใหเหมาะสมกบชนดทมนบรรจอย(Container) โดยแสดงไวตามตารางดงน
Container Scope Example
Constants Private #DEFINE myprogram
"โปรแกรมของฉน" Variables Public,Private STORE 1 to nVAR
Arrays Public,Private cARRAY[1,1] = "อะเรย
ของฉน"
Fields Permanent storage REPLACE name WITH "ชอของฉน"
Object
Properties Referenced through the object
Testform.Caption = myProgram
ใน Visual FoxPro คณจะไดพบกบ Contrainer อยตลอดเวลาแลวมนคออะไร ? ผมกไมคอยจะรสกเทาไหร แตพอจะเดาๆ ไดวา มนคออะไรกตามทเกบทกอยางเกยวกบขอมลของคณ ไมวาจะเปน ตวแปร,ฟลด,อะเรย หรอแมแตคณสมบตของวตถ (Object Properties) คาคงท (Constants) คาคงทคอตวแปร ทใชเกบคาตางๆทเอาไวใชในโปรแกรมของเราโดยทไมมการเปลยนแปลง ในการกำาหนดคาคงท เราจะใชคำาสง #DEFINE ConstantName eExpression
6
เชน #DEFINE myprogram "โปรแกรมของฉน" ถาตองการยกเลกคาคงทใหใชคำาสง #UNDEF ConstantName ตวแปร (Variables) ตวแปรคอชอทเราตงขนมาเพอใชแทนคาตางๆทเราเกบไว โดยคาทเกบไวนนสามารถ เปลยนแปลงเปนคาอนๆไดตามตองการ การกำาหนดคาตวแปรเราใชคำาสง STORE หรอ = เชน STOR 1 TO nVAR nVAR = 1 ขอบเขต(scope)การใชงานตวแปรเราสามารถกำาหนดใหตวแปรนนๆเปนตวแปรแบบ ทองถน (Private) หรอเปนตวแปรแบบสาธารณะ(Public) ไดโดยการใชคำาสง สำาหรบตวแปรทองถน PRIVATE MemVarList - หรอ - PRIVATE ALL [LIKE Skeleton | EXCEPT Skeleton] สำาหรบตวแปรสาธารณะ PUBLIC MemVarList - หรอ - PUBLIC [ARRAY] ArrayName1 (nRows1 [, nColumns1]) [, ArrayName2 (nRows2 [, nColumns2])] ... แลมนมประโยชนอยางไรละ? การใชตวแปรในโปรแกรมตางๆถาเราไมไดกำาหนดวาเปน Public ทาง Visual FoxPro จะถอวาตวแปรนนเปนแบบ Private ขอแตตางของมนอยตรงท ตวแปร Private คาตางๆสามารถใชไดเฉพาะ ในโปรแกรม(procedure) นนๆเทานนเมอนำาชอตวแปรไปใชในโปรแกรมอนคาตางๆ
7
กจะถกลางออก สวน Public คาตางๆทกำาหนดไวสามารถใชไดทกทของระบบงานของคณ โดยมนจะมคาตามคาหลงสดทกำาหนดให อะเรย (Arrays) อะเรยคอชดของตวแปรทอางถงโดยใชตวเลข ตวแปรอะเรยจะเกนอยใน memory ของคอมพวเตอร มนจงทำางานไดรวดเรวมาก เมอทานฝกฝนฝมอถงขนหนงแลว การใชตวแปรอะเรยจะเปนสงจำาเปนอยางยง ในการสรางตวแปรอะเรยนนเราใชคำาสง DECLARE [cFunctionType] FunctionName IN LibraryName [AS AliasName] [cParamType1 [@] ParamName1, cParamType2 [@] ParamName2, ...] หรอ DIMENSION ArrayName1 (nRows1 [, nColumns1]) [, ArrayName2 (nRows2 [, nColumns2])] ... เชน DIMENSION cARRAY[5] DECLARE cARRAY[2,5]ฟลด (Fields) ฟลดคอชอของขอมลทเกบอยในเรคคอรด(record) ชอฟลดจะสรางโดยการสราง Table การสราง Table ใน Visual FoxPro ใชคำาสง CREATE TABLE | DBF TableName1 [NAME LongTableName] [FREE] (FieldName1 FieldType [(nFieldWidth [, nPrecision])] [NULL | NOT NULL] [CHECK lExpression1 [ERROR cMessageText1]] [DEFAULT eExpression1] [PRIMARY KEY | UNIQUE]
8
[REFERENCES TableName2 [TAG TagName1]] [NOCPTRANS] [, FieldName2 ...] [, PRIMARY KEY eExpression2 TAG TagName2 |, UNIQUE eExpression3 TAG TagName3] [, FOREIGN KEY eExpression4 TAG TagName4 [NODUP] REFERENCES TableName3 [TAG TagName5]] [, CHECK lExpression2 [ERROR cMessageText2]]) | FROM ARRAY ArrayName หรอ CREATE [FileName | ?] เชน CREATE TABLE customer (SalesID c(6), CustName c(20),; FOREIGN KEY SalesId TAG SalesId REFERENCE SALESMAN) วตถ (Object) วตถคอ คลาส(class)สำาเรจรป คณสามารถนำามนไปใชงานได งงใชไหมผมกยงงงๆอยแตงงของผมม งอ ง 20 ตว งนผมยกตวอยาง(เอาแมนำาทง 5 นำาทงนน)เลยแลวกน วาไอทเขาบอกวาเปน Object-Oriented Programming มนเปนอยางไร คณเคยเลน ตวตอ hobby หรอไม ถาไมเคยไมตองมาบอกผม มนจะแยกเปนชนๆสำาเรจมาใหแลวใชหรอไม แลวมนกจะมกาว มส มอะไรอกกชางมนกแลวกน ไอตวนแหละมนกเสมอนเปนคลาส เรากนำามนมาประกอบกน โดยนำากาวมาตดนำาสมาแตม พวกนกคอ คณสมบต(properties)ซงเรานำามาแตงแตมมนเขาไป
9
เมอทำาเสรจมนกจะเปนหนใหเรา เหมอกนกบ OOP นนแหละเอาคลาสมามวๆกนเดยว มนกออกมาเปนโปรแกรมเอง สวนระละเอยดแบบเนอ สด ตบ ไวตดตามไดในบทตอๆไป โอเปอเรเตอร (Operators) โอเปอเรเตอรจะเปนตวททำาใหคณสามารถเคลอนยายขอมล เปรยบเทยบขอมลตางๆ ใน Visual FoxPro ไดแบง โอเปเรเตอรไวดงน โอเปอเรเตอรตวอกษร (Character Operators) โอเปอเรเตอรวนทและเวลา (Date and Date Time Operators) โอเปอเรเตอรตรรกะ (Logical Operators) โอเปอเรเตอรเปรยบเทยบ (Relational Operators) โอเปอเรเตอรตวเลข (Numeric Operators) โอเปอเรเตอรตวอกษร (Character Operators) โอเปอเรเตอรตวอกษรจะใชสำาหรบเชอมตวอกษร ตงแต 2 กลมเขาดวยกน โดยการใชโอเปอเรเตอร + - และ เปรยบเทยบตวอกษร 2 กลมโดยใชโอเปอเรเตอร $ เชน ? ‘สวสด ‘ + ‘ครบ ’ สวสด ครบ (ผลลพททได) cVAR = ‘สวสด ‘ ? cVAR – ‘ครบ ’ สวสดครบ (ผลลพททได) ?'ครบ' $ 'สวสดครบ .T. (ผลลพททได)โอเปอเรเตอรวนทและเวลา (Date and Date Time Operators) ใชบวก หรอลบวนท
10
เชน SET DATE DMY ? DATE() + 30 (สมตวนทปจจบนเเปน 15/09/98) 10/15/98 (ผลลพททได) ? DATE() - {17/06/98} 90 (ผลลพททได)โอเปอเรเตอรตรรกะ(Logical Operators) ใชไดกบทกประเภทของขอมล ซงประกอบดวยโอเปอเรเตอร () , NOT หรอ ! , AND , OR เชน IF !(cVAR=’สวสด’) OR (nSaraly >= 50000)โอเปอเรเตอรเปรยบเทยบ(Relational Operators) โอเปอเรเตอรเปรยบเทยบประกอบไปดวย < นอยกวา
> มากกวา
<>, # , != เทากบ
<= ไมเทากบ
>= มากกวาหรอเทากบ
== ใชเปรยบเทยบขอความ 2 ขอความ โอเปอเรเตอรตวเลข(Numeric Operators) ใชในการคำานวณคาตางๆ ประกอบไปดวย Operator Description ลำาดบการทำางาน
( ) แบงกลมคำานวณ ลำาดบท 1 **, ^ ยกกำาลง ลำาดบท 2* , / คณ , หาร ลำาดบท 3% หาเศษ ลำาดบท 4+ , - บวก , ลบ ลำาดบท 5
11
เชน ? (4+5) * 10 - (12%10) ^ 2 86.00 (ผลลพททได) การสรางนพจน (Building Expressions) นพจนคออะไร คอถอยแถลงทมความหมายทำาใหโปรแกรมรจก สามารถปฎบตตามคำาสงได ถายงไมคอยจะเขาใจใหลองยอนกลบไปดตวอยางโปรแกรมแรก ในโปรแกรมหนงๆ จะประกอบไดวยถอยแถลงหลายๆ ถอยแถลงมาประกอบกน เชน nVAR = 1 + 2 IF (nVAT = 10/100) FOR nVAR = 4 to 400 STEP 4 ? DATE() เปนตน การเขยนนพจน เปนศลปะอยางหนงขนอยวาผทเขยนนนๆ ตองการใหโปรแกรมเปนอยางไร นพจนนนอาจประกอบไปดวย ตวอกษร โอเปอเรเตอร(Operators) คาคงท(Constants) ตวแปร(Variable) ฟงกชน(Function) ดงทไดกลาวมาแลวขางตน การตงชอใน Visual FoxPro 1. ใชตวอกษร, _ (Under Score) และตวเลข 2. ตวแรกตองขนตนดวยตวอกษร หรอ Under Score 3. สามารถตงชอไดตงแต 1 ตวถง 254 ตวอกษร ยกเวนชอ Field ใน Free Table (file ทมนามสกล .DBF) และ Index Tag ตงชอไดไมเกน 10 ตวอกษร 4. หามใชคำาสงวนใน Visual FoxPro หลกโปรแกรมเบองตน (Basic Programming)
12
ในการเขยนนพจนขนมาไมวาคณจะเขยนดวยโปรแกรมภาษาใดกตาม ซงอาจเปน ภาษา C , BASIC หรอ PASCAL คณจำาเปนจะตองเขาใจและรเกยวกบคำาสงทใชในการควบคมการทำางานของโปรแกรม ซงมอย 2 ชนด ไดแก นพจนคำาสงทใชในการทดสอบ , คำาสงทตองการใหทำางานซำาๆกน ในความคดผมนนถาผทตองการจะเปน หรอเปนโปรแกรมเมอรไมทราบคำาสงประเภทนแลว เลกเปนโปรแกรมเมอรแลวไปขายเตาฮวยจะดกวา คำาสงทเกยวกบการทดสอบ คำาสงประเภทนจะมการทดสอบคาของตวแปรเพอตดสนใจ (Decision) วาจะทำาการประมวลผลอะไรตอไป ซงทางเลอกในการตดสนใจอาจมไดหลายทางเลอกกได ใน Visual FoxPro มคำาสงประเภทนไดแก คำาสง IF..ENDIF IF lExpression Commands [ELSE Commands] ENDIF ฟงกชน IIF() IIF(lExpression, eExpression1, eExpression2) คำาสง DO CASE ... ENDCASE DO CASE CASE lExpression1 Commands [CASE lExpression2 Commands ... CASE lExpressionN Commands] [OTHERWISE
13
Commands] ENDCASE ทนเรากมาดกนวาจะใชคำาสงเหลานอยางไร ใหคณทำาการสรางโปรแกรมชอ Program2 แลวพมพคำาสงตามตวอยางดานลางแลวทำาการรนโปรแกรมนนด * Program2 #DEFINE myProgram "โปรแกรมแสดงการทดสอบเงอนไข" PRIVATE nVAR myForm = CREATEOBJECT("TestForm") myForm2 = CREATEOBJECT("DisplayColor") myForm.Show myForm2.Show myForm2.BackColor = RGB(255,0,0)READ EVENTS
DEFINE CLASS TestForm AS FORM Caption = myProgram Top = 1 Left = 0 Height = 250 Width = 300
ADD OBJECT MyButton AS CommandButton WITH ;Top = 180, Left = 36, Height = 37, Width = 73, ;Caption = "Exit"
ADD OBJECT MyGroup AS OptionGroup WITH ;AutoSize = .T. , ButtonCount = 5, BackStyle = 1, Value = 1 ,;Height=108,Left=36,Top=48,Width=78,;Option1.FontName = "CordiaUPC", Option1.FontSize = 16,;Option1.Caption = "สแดง",;Option1.Height = 18, Option1.Left = 5, ;Option1.Top = 5, Option1.Width = 68, ;
14
Option2.FontName = "CordiaUPC", Option2.FontSize = 16, ; Option2.Caption = "สเหลอง", ;Option2.Height = 18, Option2.Left = 5, ;Option2.Top = 25, Option2.Width = 68, ;Option3.FontName = "CordiaUPC", Option3.FontSize = 16, ;Option3.Caption = "สเขยว", ;Option3.Height = 18, Option3.Left = 5, ;Option3.Top = 45, Option3.Width = 68, ;Option4.FontName = "CordiaUPC", Option4.FontSize = 16, ;Option4.Caption = "สนำาเงน", ;Option4.Height = 18, Option4.Left = 5, ;Option4.Top = 65, Option4.Width = 68, ;Option5.FontName = "CordiaUPC", Option5.FontSize = 16, ;Option5.Caption = "สขาว", ;Option5.Height = 18, Option5.Left = 5, ;Option5.Top = 85, Option5.Width = 68
ADD OBJECT MyCheckBox AS CheckBox WITH ;Top = 84, Left = 144, Height = 49, Width = 121, ;FontName = "CordiaUPC", FontSize = 16, ;Caption = "แสดงหนาตาง", Value = 1
PROCEDURE myButton.ClickRELEASE THISFORMCLEAR EVENTSENDPROC
PROCEDURE myCheckBox.ClickIF myForm.myCheckBox.Value = 1myForm2.ShowELSE
15
myForm2.HideENDIFENDPROC
PROCEDURE myGroup.ClickDO CASECASE myForm.myGroup.Value = 1myForm2.BackColor = RGB(255,0,0)CASE myForm.myGroup.Value = 2myForm2.BackColor = RGB(255,255,0)CASE myForm.myGroup.Value = 3myForm2.BackColor = RGB(0,255,0)CASE myForm.myGroup.Value = 4myForm2.BackColor = RGB(0,0,128)CASE myForm.myGroup.Value = 5myForm2.BackColor = RGB(255,255,255)OTHERWISEmyForm2.BackColor = RGB(255,255,255)ENDCASEmyForm2.RefreshENDPROCENDDEFINE DEFINE CLASS DisplayColor AS FORMCaption = myProgramTop = 1Left = 320Height = 250Width = 300ENDDEFINEเมอคณไดเรยกโปรแกรมขนมาแลวคณกจะไดพบกบวธการใชคำาสง IF...ENDIF, IIF(), DO CASE...ENDCASE วาทำางานอยางไรแลวคณทราบหรอไมวา คำาสง IF กบคำาสง DO CASE ตางกนอยางไร อยาบอกวาเขยนตางกนนะครบ เปลาครบคำาสงสองคำาสงนทำางานเหมอนกน เอาแลทำามาทำาไมละ? มนตางกนทจดประสงค คำา
16
สง DO CASE เขาทำาขนมาเพอคำาความสะดวกในการเขยนโปรแกรมแบบทมทางเลอกหลายๆ ทาง สวน คำาสง IF กสามารถทำาได แตการเขยนโปรแกรมจะยงยากมากกวาครบ ยงมอกยางนงในอดตมนเกยวกบเรองของความเรวในการประมวลผลดวย แลวทานทราบหรอไมวาคำาสงไหนทำางานเรวกวากน? คำาสงทใหทำางานซำาๆกน คำาสงประเภทนจะเปนคำาสงทมการทดสอบเงอนไขแลวถาผลของเงอนไขนนเปนจรง(True) กจะทำางานซำาๆกนไปจนกวาเงอนไขจะเปนเทจ(False) แลวกจะออกจากลป(Loop) ของคำาสงนนๆ คำาสงประเภทนไดแก คำาสง DO WHILE...ENDDO DO WHILE lExpression Commands [LOOP] [EXIT] ENDDO คำาสง FOR...ENDFOR FOR MemVarName = nInitialValue TO nFinalValue [STEP nIncrement] Commands [EXIT] [LOOP] ENDFOR | NEXT คำาสง SCAN...ENDSCAN SCAN [NOOPTIMIZE] [Scope] [FOR lExpression1] [WHILE lExpression2] [Commands] [LOOP] [EXIT] ENDSCAN ใหคณทำาการสรางโปรแกรมชอ Program3 แลวพมพคำาสงตามตวอยางดานลางแลวทำาการรนโปรแกรมนนด
17
* Program3 * Test will hold references to 5 forms PUBLIC ARRAY test(1) DIMENSION test(5) STORE 1 TO nCount DO WHIL nCount <= 20 ? 'Display Loop ====> ' + ALLTRIM(STR(nCount))
nCount = nCount + 1 ENDDO WAIT WINDOW 'Press any key to continue.' * Clear the screen _SCREEN.CLS * Fill the array with forms FOR nCount = 1 TO 5 test(nCount) = CREATEOBJECT("testform") ENDFOR * Ask the user if they want to see the forms nAnswer = MESSAGEBOX("Do you want to see the forms?", ; 36, "Multiple Instances - Arrays") IF nAnswer = 6 && yesFOR nCount = 1 TO 5 IF TYPE("test(nCount)") = "O" && "O" = Object test(nCount).Show test(nCount).Top = 30*nCount test(nCount).Left = 50*nCount _SCREEN.ActiveForm.BackColor=RGB(51*ncount,255,255)&&less than or equal to 255ENDIF ENDFOR ENDIF
* Form class testform DEFINE CLASS testform AS Form ADD OBJECT cmdExit As CommandButton WITH ;
18
Caption = "E\<xit", Top = 100, Left = 140, ; Height = 29, Width = 94, Visible = .T.
PROCEDURE cmdExit.Click RELEASE ThisForm ENDPROC ENDDEFINE คำาสงทง 3 คำาสงขางตนนนมความแตกตางกนพอสมควร โดยคำาสง DO WHILE นนจะทำาการทดสอบเงอนไขไดทกประเภทไมวาจะเปน ตวเลข ตวอกษร เมอไดคาเปนจรงแลวกจะทำางานตามคำาสงในลป DO WHILE เปนคำาสงดงเดมของ foxbase สวนคำาสง FOR...NEXT และ SCAN นนเพงจะมขนในสมย FoxPro (กอน Visual FoxPro) จรงๆแลวคำาสง DO WHILE สามรถทำาไดทกอยางหรอเกอบจะทกอยางท FOR...NEXT และ SCAN ทำาได แตเขาทำาขนเพอความสะดวกในการใชงานใหมมากยงขน คำาสง FOR...NEXT จะทำาการทดสอบเงอนไขตวเลข สวนคำาสง SCAN ะทำาการทดสอบเงอนไขทอยในแฟมขอมล แตการใชงานใน 2 คำาสงหลงนจะมความงายกวา DO WHILE มากถาใชในลกษณะเดยวกน จากตวอยางขางตนผมมคำาสงหนงทจะขอแนะนำาใหคณไดทำาความรจกไว เพราะในการเขยนโปรแกรมคณจำาเปนจะตองใชมนอยางแนนนอน แลวในตวอยางตอๆไปผมจะพยายามแทรกคำาสง (command) และฟงกชน (function) ตางๆเทาทผมนกออกและใชงานไดจรง คำาสง (ฟงกชน) MESSAGEBOX( ) ฟงกชนนจะเปนการแสดงไดอะลอกบอกซ (dialog box) ขนมาเพอสงขาวสารบางอยางใหผใชงานทราบ แลวตอบคำาถามตามทตองการ มรปแบบการใชดงน MESSAGEBOX(cMessageText [, nDialogBoxType [, cTitleBarText]
19
cMessageText คอขอความทตองการใหแสดงในไดอะลอกบอกซ nDialogBoxType คอตวเลขทใชบอกวาจะใหมปมอะไรบางเพอใหผใชงานตอบกลบมา แลวจะมสญลกษณรปภาพแสดงดวยหรอไม และใชกำาหนดปม Default คาทตองการใหแสดงปมตางๆ มดงน 0 ปม OK 1 ปม OK และ Cancel 2 ปม Abort, Retry, และ Ignore 3 ปม Yes, No, และ Cancel 4 ปม Yes และ No 5 ปม Retry และ Cancel คาทตองการใหแสดงสญลกษณรปภาพ มดงน 16 สญลกษณ Stop 32 สญลกษณ Question mark 48 สญลกษณ Exclamation point 64 สญลกษณ Information (i) icon คาทใชกำาหนดปม Default มดงน 0 ปมแรก 256 ปมทสอง
20
512 ปมทสาม ในการใชงานนนถาเราตองการใหแสดงปม Yes, No ,Cancel และตองการแสดงสญลกษณ Stop แลวใหปม Default อยทปมทสอง กใหนำาคาทง 3 คานนมารวมกน จะไดคาเทากบ 3 + 16 + 256 = 275 cMessageText คอขอความทตองการใหแสดงสวนหวของไดอะลอกบอกซ เมอผใชงานตอบคำาถามกลบมากจะมคาตวเลขสงกลบมาใหเพอทเราจะไดนำาไปประมวลผลตอไป ซงมดงน 1 เมอกดปม OK 2 เมอกดปม Cancel 3 เมอกดปม Abort 4 เมอกดปม Retry 5 เมอกดปม Ignore 6 เมอกดปม Yes 7 เมอกดปม No คณสามารถทดสอบไดโดยการปอนคำาสงนท Command Windows ไดเลยแลวดวาผลเปนอยางไรบาง เชน nAnswer = MESSAGEBOX("Do you want to see the forms?" 36, "Multiple Instances - Arrays") ? nAnswer 6 (ผลลพธ เมอกดปม Yes) คลาส (Classes) ใน Visual FoxPro เราถอวา ฟอรม(Forms) , ฟอรมเซต(Form Set) และคอนโทรล(Control) ทงหมดนเปนวตถ(Object) แลวเรากนำาเอา Object ไปใชในโปรแกรมตางๆทเราเขยนขนมา
21
มาถงตอนนเรากเขาแกบของการเขยนโปรแกรมแบบ OOP อกแลวครบทาน Object ตางๆทเราเขยนขนมานนจะประกอบไปดวย คณสมบต(Properties) , อเวนต(Events) และเมธอต(Methods) เอาทวามามนไมเหนจะเกยวกบคลาสตรงไหนเลย เอาละ คลาส กบ Object มนไมเกยวกนหรอกเพราะมนไมมตะขอเกยว... แตมนมความละมายใกลเคยงกนมากเพราะ Object มนเกดมาจากคลาส อานมาถงตรงนอยาเพงงงนะครบ สวนผมนะงงไปแลว งนยกตวอยางเลยแลวกน ตวอยางกมอยวา ใน Visual FoxPro ไดจดเตรยม คลาสสำาเรจรปเตรยมไวใหเราซงเรยกวา เบสคลาส(Base Class) แลวเรานำามาเพมคณสมบต ใสอเวนต เตมเมธอต แลวเรากนำามนมาใชเราเรยกตวทนำามาใชวา Object ถงตอนนเขาใจบ หรอบเขาใจ แตมอกคำาหนงอยากจะอะธบายใหฟงสกหนอย คำาวา ซบคาลส(Sub Class) ลกษณะของ Sub Class กเหมอนกบคลาสอกนนแหละแต Sub Class จะอยตรงกลางระหวาง คลาส กบ Object จดประสงคของ Sub Class กมไวอม...ไมใช ตวอยางเชนถาเราตองการสรางฟอรมแลวมปมคำาสงเรากนำา เบสคลาส มาใสแลวกำาหนด คณสมบต , อเวนต และเมธอต เมอเรากำาหนดเสรจกจะไดเปน Sub Class แลวเรากทำาการเรยก ใชงาน เวลาเรนำามาใชกกลายเปน Object อกแลวครบทาน งงไปกงงมาอยตรงนแหละ จากทกลาวมานนทานกจะไดทราบวา การโปรแกรมเชงวตถ(OOP) นนเปนอยางไร ทนเรากทำาดวา เบสคลาส มอะไรบา ตามตารางตอไปน
22
CheckBox EditBox ListBox ShapeColumn Form OLEBoundControl SpinnerCommandButton
FormSet
OLEContainerControl
TextBox
CommandGroup Grid OptionButton TimerComboBoxr Header OptionGroup ToolBarContainer Image Page Control Label PageFrame Custom Line Separator คลาสทเราใชงานอยจะประกอบไปดวย คอนเทรนเนอร(Contrainers) และ นอน-คอนเทรนเนอร(Non-Contrainers) หรอเรยกอกอยางวา คอนโทลคลาส(Control Class) ตวคอนเทรนเนอรนนจะยอมใหนำาคลาสใดๆมาใสไวได ไมวาจะเปน คอนเทรนเนอรคลาส หรอ คอนโทรคลาส เชน เบสคลาส Form เปนคอนเทรนเนอร มนสามารถนำา ปม CommandButton มาใสไวไดเปนตน ตารางแสดง คอนเทรนเนอร
คอนเทรนเนอร คลาสทสามารถบรรจะในคอนเทรนเนอรCommand button groups
Command buttons
Container Any controlsControl Any controlsForm Sets Forms, toolbarsForms Page frames, any controls, containers,
customGrid columns
Column headers, any objects except forms, form sets, grid columns, and
23
toolbarsGrids Grid columnsOption button groups
Option buttons
Page framesPagesPages Any controls. containers, customToolbars Any controls, page fame, containerมาถง ณ. จดนคณกทราบแลววาคลาสมนคออะไร มไวทำาอะไร แตจะนำามนมาใชไดอยางไรละ เราจะนำาคลาสไปใชงานเราใชคำาสง DEFINE CLASS ClassName1 AS ParentClass [[PROTECTED PropertyName1, PropertyName2 ...] PropertyName = eExpression ...] [ADD OBJECT [PROTECTED] ObjectName AS ClassName2 [NOINIT] [WITH cPropertylist]]... [[PROTECTED] FUNCTION | PROCEDURE Name [NODEFAULT] cStatements [ENDFUNC | ENDPROC]]... ENDDEFINE เชน DEFINE CLASS TestForm AS Form ADD OBJECT cmdExit As CommandButton WITH ; Caption = "E\<xit", Top = 100, Left = 140, ; Height = 29, Width = 94, Visible = .T. PROCEDURE cmdExit.Click RELEASE ThisForm
24
ENDPROC ENDDEFINE จำาไดหรอไมวาไดพบกบคำาสงนทตวอยางโปรแกรมตางๆขางตนมาแลว จะสงเกตไดวาเมอเราได ทำาการ DEFINE CLASS ขนมาเปน Sub Class (TestForm เปน Sub Class ของ base class FORM) แลวเราตองทำาการสราง object อกครงหนง โดยใชคำาสง CREATEOBJECT(ClassName [, eParameter1, eParameter2, ...]) เชน myForm = CREATEOBJECT("TestForm") หลงจากททำาการ Create Object ขนมาแลวถาเราตองการให Object นนปรากฏในหนาจอเราตองกำาหนด เมธอตของ Object นนใหมการแสดงชนมา โดยการอางชชอของ Object ทตองการแลวใสเมธอต Show เขาไป ดงน myForm.Show เมอกอนทผมจะมาลองหดเขยนโปรแกรมแบบ Visual ผมเหนเขาเขยนคำาสงกำาหนดคณสมบตตางๆ ผมงงมาก ถาคณเปนมอใหมกคงงงแบบผมเพราะถาใน FoxPro รนกอนๆ ถาเราใช จด(.) เปนตวคนกลางเรากจะหมายถง การอางถงฟลดในแฟมขอมล หรอ บอกวาเปนตวแปร memvar แตสำาหรบ Visual FoxPro ไดมการ เพมใหเปนการกำาหนด คณสมบตและเมธอตตางๆใหกบ Object ทนเรามาด กนวาจะอางถง Object ตางๆ เพอกำาหนดคาคณสมบตและเมธอตตาาๆ ไดอยางไร วธการอางถง Object นนเรามวธการอางถงอย 2 แบบดวยกนคอ 1. การอางถงแบบสมบรณ (Absolute Referencing) 2. การอางถงแบบสมพนธ (Relative Reference)
25
การอางถงแบบสมบรณ (Absolute Reference) การอางถงแบบสมบรณ กคอการบอกไปตรงๆวา Object นนๆอยทไหนถาสงเกตใหดตวอยางทผมแสดงไว ในบทตนๆนนแหละเปนการอางแบบสมบรณ เชน myForm2.Show myForm2 คอชอ Sub Class ของ Form ทเราสรางขน Show คอเมธอตทใหทำาการแสดง ฟอรม myForm2 _SCREEN.ActiveForm.BackColor = RGB(51*ncount,255,255) _SCREEN คอการอางถงหนาจอ สวน ActiveForm เปนการอางถง Form ททำาการเปดอย ณ. ขณะนน BackColor คอกำาหนดคณสมบตใหแสดงสของพนฟอรม myForm.txtDate.ForeColor = RGB(0,0,0) && black text myForm.txtDate.BackColor = RGB(192,192,192) && gray background myFormSet.myForm.Show myFormSet.myForm.cmdButton1.SetFocus ตวอยางทงหมดขางตนนนเปนการอางถงแบบสมบรณ การอางถงแบบสมพนธ (Relative Reference) การอางถงแบบสมพนธ กคอการบอกแบบอางถงความสมพนธ ซงประกอบไปดวย keyword ตอไปน Parent The immediate container of the
object.THIS The object.THISFORM The form that contains the object.THISFORMSET The form set that contains the
26
objectตวอยางเชน THIS.Caption = 'OK' && กำาหนดใหแสดงคำาวา OK ใน Object THIS.Parent.BackColor = RGB(192,0,0) && กำาหนดสฉากหลงของฟอรม THISFORM.cmd1.Caption = 'OK' && กำาหนดใหแสดงคำาวา OK ใน object cmd1 ของ Form ปจจบน THISFORMSET.myForm.cmd1.Caption = 'OK' ถงตอนนคณคงไดทราบวธการอางถง Object ของ Visual FoxPro แลววาทำาอยางไร แตยงมขอสงเกตอยอยางหนงกคอ ลำาดบของการอางถงถาคณสงเกตใหด ลษณะของลำาดบในการอางถงจะเรมตนจากลำาดบตำาสดกคอ คณสมบต หรอ เมธอต ถดมาจะอางถง object จากนนกมาเปน ฟอรม แลวสดทายกจะเปน ฟอรมเซต คณลองทำาความเขาใจกบ การอางนดTHIS.Paret.BackColor คำาวา parent มนหมายถออะไร มนหมายถงฟอรม ใชหรอไม การกำาหนดคณสมบต (Setting Properties) คณสามารถกำาหนดคณสมบต (Properties) ของ Object ไดโดยใชรปแบบดงน Parent.Object.Property = Value เชน myForm.txtDate.Value = DATE() && display the current date myForm.txtDate.Enabled = .T. && the Control is enabled myForm.txtDate.ForeColor = RGB(0,0,0) && black text myForm.txtDate.BackColor = RGB(192,192,192) && gray background
27
จะเหนไดวาบางครงการกำาหนดคณสมบตเราจะทำาการกำาหนดคณสมบตหลายๆอยางใน Object นนๆ ซงเราไมจำาเปนตองเขยน code ตามตวอยางขางบนกได ใน Visual FoxPro ไดเตรยมคำาสงสำาหรบไวกำาหนด คณสมบตหลายๆคณสมบตไวภายใน Object เดยวกนโดยใชคำาสง WITH...ENDWITH WITH ObjectName [.cStatements] ENDWITH จากตวอยางกอนหนาเราสามารถนำามาเขยนใหมไดดงน WITH myForm.txtDate .Value = DATE() .Enabled = .T. .ForeColor = RGB(0,0,0) .BackColor = RGB(192,192,192) ENDWITH การเรยกเมธอต (Calling Method) เมอคณไดทำาการสราง Object ขนมาแลว คณสามารถทำาการเรยก เมธอต ของ Object จากทใดกไดในโปรแกรม โดยเขยน code ดงน Parent.Object.Method เชน myForm.Show myForm.cmdExit.SetFocus ในสวนของความหมายวา คณสมบตและเมธอตแตละตวมความหมายอยางไร ใชงานอยางไรนนผมจะอธบายไวในบทตอๆไป ในการอางถงเมธอตนน Visual FoxPro ไดเตรยมโอเปเรเตอรไวใหอกตวหนงซงไวอางถง parent คลาสโดยใช :: (Scope Resolution Operator) ในการอางถง เชน cmdButton::Click() มาถง ณ. จดนคณกไดทราบคลาสตางๆ ทราบถงวธการอางถงในรปแบบตางๆ ในบทตอไปกจะเปนเรองของการสรางฐานขอมล
28
จดการขอมลเบองตน (Data Base Design) คณคงทราบดอยแลววา Visual FoxPro ถกสรางขนมาเพอจดการกบฐานขอมล ซงจะมการเกบขอมลตางๆแลวนำามาประมวลผล ในบทนเราจะมากลาวกนเกยวกวการออกแบบฐานขอมล แฟมขอมล เรคอรด ฟลด เพอเปนแนวทางในการออกแบบและสรางฐานขอมลตอไป ทานทราบหรอไมวาหนวยเกบขอมลทเลกทสดของคอมพวเตอรคออะไร บต(Bit) เปนหนวยเกบขอมลทเลกทสดในคอมพวเตอร เมอเรานำาบตหลายๆบตมารวมกบกจะเปน ไบต (รหส ASCII 8 บต เทากบ 1 ไบต) ซงกคอ 1 ตวอกษรนนเอง แลวนำาตวอกษรมารวมกนแลวมความหมายอยางใดอยางหนงเราเรยกเปนฟลด(Field) นำาฟลดหลายๆฟลดมมความเกวยเนองกนมาประกอบกนรวมเปน เรคคอรด(Record) หลายๆเรคคอรรวมกนเกบไวในแฟมขอมล(File) แลวนำาแฟมขอมลหลายๆแฟมขอมลมาสรางความสมพนธกนประกอบกนเปนฐานขอมล ถาคณตองการทจะสรางระบบงานขนมาใชงานสกระบบงานหนงสงทจำาเปนอยางยงกคอ ฐานขอมล (Database) แลวฐานขอมลมประโยชนอยางไร? 1. เพอลดความซำาซอนของขอมล 2. เพอลดขอผดพลาดในการปอนขอมลไดระดบหนง 3. สามารถนำาขอมลไปใชรวมกนได 4. ควบคมดแลงาย เปนตน ผมจะขอยกตวอยางฐานขอมล ใบสงสนคา(Invoice) เพอเปนแนวทางในการออกแบบดงตอไปน กอนอนทานตองมาดกอนวาใบสงสนคานนประกอบไปดวยขอมลอะไรบาง ประกอบดวย ขอมลลกคา ขอมลสนคา ขอมลการสงสนคา เปนตน แลวเรานำาขอมลทไดนนมาออบแบบแฟมขอมล(Table) ซงสามารถจำาแนกออกเปนแฟมขอมลดงตาราง
29
แฟมขอมลลกคา(Customer)
รหสลกคา CUST_ID
ชอ NAME
ทอย ADDRESS
ยอดเงนคงคาง OUTSTNDING
วงเงนสนเชอ CREDITLMT
วนใหสนเชอ TERM_DAY
พนกงานขาย SALES_ID
00001
บ.นานนานมท
198 ถ.สาธร กทม.
150000 20000 30 S0001
00002
รานสะอาด
189 ถ.อสรภาพ กทม
0 50000 60 S0001
00003
บ.สความสำาเรจ
44 ถ.รมเกลา กทม.
9850 7500 15 S0002
แฟมขอมลพนกงานขาย(Salesman)
รหสพนกงานขาย SALES_ID
ชอ NAME
ทอย ADDRESS
อตราคอมมชชน COMMRATE
S0001 นายสมหวง393 ถ.รามคำาแหง กทม. 0.50%
S0002 นายระเบยบ
78 ซ.ออนนช กทม. 0.75%
แฟมขอมลใบสงสนคา(Invoice)
เลขทใบสงสนคา INV_NO
วนทสง DATE
รหสลกคา CUST_ID
9800001 15/09/1998 00002 9800002 01/10/1998 00001 9800003 01/10/1998 00002
30
แฟมขอมลรายการสนคา(Invoice Detail)
เลขทใบสงสนคา INV_NO
รหสสนคา PROD_ID
จำานวน QUANTITY
ราคาตอหนวย UNITPRICE
980001 AA001 5000 2.50 980001 BB001 850 10.00 980002 AA001 1000 2.25 98003 CC001 50 100.00 แฟมขอมลสนคา(Product)
รหสสนคา PROD_ID
ชอ NAME
จำานวนคงเหลอ
ON_HANDหนวยนบ UM
ราคาตอหนวย
UNITPRICE AA001 นอต 550000 ตว 2.50 BB001 เทปพนสายไฟ 4000 มวน 10.00 CC001 ส 6 กระปอง 110.00 ถาคณพจารณาดแฟมขอมลตามตารางจะสงเกตเหนวาแฟมขอมลแตละแฟมจะมความสมพนธกบอกแฟมขอมลหนง เชนแฟมขอมลใบสงสนคา กบ แฟมขอมลลกคาจะมรหสลกคาเปนตวเชอมความสมพนธ แลวแฟมขอมลลกคา กจะ เชอมกบแฟมขอมลพนกงานขายโดยมรหสพนกงานขายเปนตวสรางความสมพนธ แลวเมอไหรเราตองทำาการสรางความสมพนธระหวางแฟมขอมล? อนดบแรกในการสรางความสมพนธ(relation) เราตองคำานงถงความซำาซอนของขอมล เชนในใบสงสนคา จะประกอบไปดวยขอมลลกคา ถาลกคารายนนๆทำาการสงสนคาเสมอ เมอเราทำาการออกใบสงสนคาให ทกครงเราตองมาทำาการปอนขอมลลกคารายนนอก ซงขอมลทปอนจะมลกษณะเหมอนกนทกครงไป ดงนนเรา จำาเปนตองสรางแฟมขอมลลกคาเพอมารองรบในสวนน แลวจดการเชอมแฟมขอมลทงสอง
31
แฟมดวยรหส ซงการเชอมนเราเรยกวาการสรางความสมพนธ เมอแฟมขอมลมการสรางความสมพนธขนมากเกดเปน ฐานขอมลขน แลวใน Visual FoxPro จะสรางฐานขอมลขนมาไดอยางไร? ในบททผานมาผมไดกลางถงคำาสงทใชสราง แฟมขอมล(Table) ไวแลว ทนเราจะมาทำาการสราง แฟมขอมลขนมาตามตวอยางในตารางขางตน ใหทำาการสรางโปรแกรมเพอทำาการสราง ฐานขอมล (Database) ทำาการพมพคำาสงผานทาง Command Window โดยพมพ คำาสง MODIFY COMMAND GenStru แลวกดปม Enter แลวทำาการปอนคำาสงตอไปน *GenStru.PRG * Create Database File CREATE DATABASE myDatabase * Create Database Table CREATE TABLE Salesman (Sales_ID c(5) PRIMARY KEY, ; Name c(60),Address c(120),CommRate n(5,2)) CREATE TABLE Customer (Cust_ID c(5) PRIMARY KEY,; Name c(60),Address c(120),Creditlmt n(3,0), ; Term_day n(3,0), Sales_ID c(5), ; FOREIGN KEY Sales_ID TAG Sales_ID REFERENCE Salesman) CREATE TABLE Product (Prod_ID c(5) PRIMARY KEY, ; Name c(60),On_Hand n(7,0),UM c(10),UnitPrice n(10,2)) CREATE TABLE Inv_Head (Inv_NO n(6,0) PRIMARY KEY, ; Date d(8),Cust_ID c(5), ; FOREIGN KEY Cust_ID TAG Cust_ID REFERENCE Customer) CREATE TABLE Inv_Dtl (Inv_NO n(6,0),Prod_ID
32
c(5), ; Quantity n(6,0),UnitPrice n(10,2), ; FOREIGN KEY Inv_NO TAG Inv_NO REFERENCE Inv_Head ,; FOREIGN KEY Prod_ID TAG Prod_ID REFERENCE Product)หรอ *GenStru.PRG CREATE DATABASE 'MYDATABASE.DBC' ***** Table setup for SALESMAN ***** CREATE TABLE 'SALESMAN' (SALES_ID C(5) NOT NULL, ; NAME C(60) NOT NULL, ; ADDRESS C(120) NOT NULL, ; COMMRATE N(5, 2) NOT NULL) ***** Create each index for SALESMAN ***** ALTER TABLE 'SALESMAN' ADD PRIMARY KEY SALES_ID TAG SALES_ID ***** Change properties (if any) for SALESMAN ***** ***** Table setup for CUSTOMER ***** CREATE TABLE 'CUSTOMER' (CUST_ID C(5) NOT NULL, ; NAME C(60) NOT NULL, ; ADDRESS C(120) NOT NULL, ; CREDITLMT N(3, 0) NOT NULL, ; TERM_DAY N(3, 0) NOT NULL, ; SALES_ID C(5) NOT NULL) ***** Create each index for CUSTOMER ***** ALTER TABLE 'CUSTOMER' ADD PRIMARY KEY CUST_ID TAG CUST_ID INDEX ON SALES_ID TAG SALES_ID ***** Change properties (if any) for CUSTOMER ***** ***** Table setup for PRODUCT ***** CREATE TABLE 'PRODUCT' (PROD_ID C(5) NOT NULL, ;
33
NAME C(60) NOT NULL, ; ON_HAND N(7, 0) NOT NULL, ; UM C(10) NOT NULL, ; UNITPRICE N(10, 2) NOT NULL) ***** Create each index for PRODUCT ***** ALTER TABLE 'PRODUCT' ADD PRIMARY KEY PROD_ID TAG PROD_ID ***** Change properties (if any) for PRODUCT *****
***** Table setup for INV_HEAD ***** CREATE TABLE 'INV_HEAD' (INV_NO N(6, 0) NOT NULL, ; DATE D NOT NULL, ; CUST_ID C(5) NOT NULL) ***** Create each index for INV_HEAD ***** ALTER TABLE 'INV_HEAD' ADD PRIMARY KEY INV_NO TAG INV_NO INDEX ON CUST_ID TAG CUST_ID ***** Change properties (if any) for INV_HEAD *****
***** Table setup for INV_DTL ***** CREATE TABLE 'INV_DTL' (INV_NO N(6, 0) NOT NULL, ; PROD_ID C(5) NOT NULL, ; QUANTITY N(6, 0) NOT NULL, ; UNITPRICE N(10, 2) NOT NULL) ***** Create each index for INV_DTL ***** INDEX ON INV_NO TAG INV_NO INDEX ON PROD_ID TAG PROD_ID ***** Change properties (if any) for INV_DTL ***** *************** Begin Relations Setup ************** ALTER TABLE 'CUSTOMER' ADD FOREIGN KEY TAG SALES_ID REFERENCES SALESMAN TAG SALES_ID ALTER TABLE 'INV_HEAD' ADD FOREIGN KEY TAG CUST_ID REFERENCES CUSTOMER TAG CUST_ID ALTER TABLE 'INV_DTL' ADD FOREIGN KEY TAG
34
INV_NO REFERENCES INV_HEAD TAG INV_NO ALTER TABLE 'INV_DTL' ADD FOREIGN KEY TAG PROD_ID REFERENCES PRODUCT TAG PROD_IDเมอปอนเสรจใหทำาการ Save โดยกด Ctrl+W แลวพมพคำาสง DO GenStru ท Command Windows โปรแกรมกจะทำาการสรางฐานขอมลชอ myDatabase ขนมาใหอตโนมต จากนนใหพมพคำาสง CLOSE DATABASE MODIFY DATABASE myDatabase แลวดวามอะไรเกดขนบาง
เคลดไมลบ ถาคณมแฟม Database อยแลวคณสามารถแปลงกลบมาเปน .PRG ไดโดยใชคำาสง DO HOME()+'\TOOLS\GENDBC\GENDBC.PRG'จรงๆแลวในการสรางฐานขอมลใน Visual FoxPro นนมวธการสรางหลายวธ ทผมอธบายมานกเปน อกวธหนงในการสราง แตทผมสรางเปนโปรแกรมไวนตอๆไปเราจะนำาไปใชงานกนอก คงมหลายทานสงสยวาเมอสรางเสรจแลวกแลวกนทำาไมตองเขยนเปนโปรแกรมใหยงยาก เหตผลของผมหรอวธการของผมนนมเอาไวเพอ ถาแฟมขอมลของคณบงเอญถกลบหมดแลวคณจำาโครงสรางของแฟมขอมลไมได คณสามารถนำามนไปสรางฐานขอมลขนมาใหมได เมอคณนำาโปรแกรมไปแจกจาย (Compile เปน .exe แลวคณไมจำาเปนตอง Copy แฟมขอมลไปดวยเพยงแตคณทำาการเขยนโปรแกรมใหมนไปเรยก โปรแกรม GenStru ขนมามนกจะทำาการสรางฐานขอมลใหคณ สวนวธการนำาไปใชนนตอนสราง ระบบงานผมจะอธบายอกครง ขอยำานเปนเพยงแนวความคดสวนตวมไดหามเลยนแบบ ตอนนเรามาดรายละเอยดและคำาสงตางๆเกยวกบ ฐานขอมล และ แฟมขอมล กนกอน ใน Visual FoxPro ไดแยกแฟมขอมลออกเปน 2 ชนด คอ Free
35
Table กบ Database Table จรงๆแลวมนกคอแฟมตวเดยวกนมนามสกลเปน .DBF แลวมนตางกนอยางไร? Free Table คอแฟมขอมล .DBF ทไมผกอยกบ แฟม Database คณสามารถทำาการเปดแฟมนหรอเพมแฟมนเขาไปใน แฟม Database ใดกได Database Table คอแฟมขอมล .DBF ทไปผกอยกบ แฟม Database เมอนำาไปใชงานจะตองเปดพรอมกบ Database File
แลวทำาไมตองสราง Database file เพอมาผกกบ Database Table ดวย เหตผลหลกเลยกคอทำาใหคณสามารถเหนความสมพนธระหวางแฟมขอมลซงกเขาหลกของระบบฐานขอมล และคณสามารถตงชอ Database Table ตงชอ Field ไดยาวขน ถง 128 ตวอกษร ซง แฟม .DBF เดมตงชอ แฟมได 8 ตว ชอ Field ได 10 ตวอกษร คำาสงตางเกยวกบฐานขอมล สรางฐานขอมล (แฟม .DBC) CREATE DATABASE [DatabaseName | ?]เชน CREATE DATABASE myDatabase สราง Table (แฟม .DBF) CREATE TABLE | DBF TableName1 [NAME LongTableName] [FREE] (FieldName1 FieldType [(nFieldWidth [, nPrecision])] [NULL | NOT NULL] [CHECK lExpression1 [ERROR cMessageText1]] [DEFAULT eExpression1] [PRIMARY KEY | UNIQUE] [REFERENCES TableName2 [TAG TagName1]] [NOCPTRANS] [, FieldName2 ...] [, PRIMARY KEY eExpression2 TAG TagName2
36
|, UNIQUE eExpression3 TAG TagName3] [, FOREIGN KEY eExpression4 TAG TagName4 [NODUP] REFERENCES TableName3 [TAG TagName5]] [, CHECK lExpression2 [ERROR cMessageText2]]) | FROM ARRAY ArrayNameเชน CREATE TABLE Customer (Cust_ID c(5) PRIMARY KEY,; Name c(60),Address c(120),Creditlmt n(3,0), ; Term_day n(3,0), Sales_ID c(5), ; FOREIGN KEY Sales_ID TAG Sales_ID REFERENCE Salesman)จากตวอยางขางตนจะเปนการสราง database table พรอมๆกบ สรางแฟมดชน (ถามการเปด database file อยกอนแลวเมอเราทำาการสราง table โปรแกรมจะถอวาเปนการสราง database table โดยอตโนมต)** ขอยำาตอนนคณสามารถกำาหนดชอฟลดไดยาวถง 128 ตวนะจะบอกให ใน Visual FoxPro จะมแฟมดชนอย 2 ประเภทคอ Structure Compound Compact Index (.CDX) และ Single-key (.IDX) ทงสองประเภทมความแตกตางกนอยางไรและเราควรใชแฟมดชนแบบไหน
Single-key IndexStructural Compound Compact Index
จำานวนดชนตอ 1 แฟมขอมล
1 ดชน มากกวา 1 ดชน
ความยาวของดชน 100 ตวอษร 240 ตวอษรการเปดแฟมดชน ตองทำาการเปดเอง
โดยใชคำาสง set จะทำาการเปดใหอตโนมตพรอมกบการ
37
index to file.idx เปด tableการเรยกใชดชน เรยกจากแฟมดชน เรยกจาก tag nameจากตารางขางตนคงจะสรปไดวาเราควรใชแฟมดชนแบบไหน ถาเปนผมจะขอใช .CDX มวธอนอกหรอไมทจะทำาการสรางแฟมดชน ? เราสามารถสราแฟมดชนไดโดยใชคำาสง INDEX ON eExpression TO IDXFileName | TAG TagName [OF CDXFileName] [FOR lExpression] [COMPACT] [ASCENDING | DESCENDING] [UNIQUE | CANDIDATE] [ADDITIVE]จากคำาสงขางตนถาเราใส key word IDXFileName โปรแกรมจะทำาการสรางแฟมดชนเปนแบบ Single-key index ให แตถาเราไมใส กจะเปน Structural Compound Compact Index แทนเชน INDEX ON CUST_ID TAG CUST_ID INDEX ON SUBST(NAME,1,1) TAG NAME
เคลดไมลบ คณสามารถ ขอด tag name ไดโดยใชคำาสง ?tag(1)ถาตองการดวาดชนทเราทำาการจดเรยงมการเขยนประโยควาอยางไรใหใช ?sys(14,1)(1 คอลำาดบในการทำา index ถามหลาย tag tag ตวตอไปกจะเปนเลข 2,3 .. ไปเรอยๆ) การเรยกดชนมาใชงานนนถาเปนแบบ compound index เราตองบอกใหโปรแกรมทราบวาเราจะนำา tag ใดมาใชงานเพราะวาการเปด table มาใชงานนนโปรแกรมจะทำาการเปด แฟมดชนขนมาใหอตโนมตอยแลว แตการจะเลอกใชวาจะใช tag ตวใหนเราตองเปนผกำาหนด โดยใชคำาสง
38
SET ORDER TO [nIndexNumber | IDXIndexFileName | [TAG] TagName [OF CDXFileName] [IN nWorkArea | cTableAlias] [ASCENDING | DESCENDING]]เชน SET ORDER TO 1 SET ORDER TO TAG NAME SET ORDER TO TAG SALES_ID หรอเราสามารถเรยกดชนมาพรอมกบการเปดแฟมขอมลขนมากได โดยใชคำาสง USE USE SALESMAN ORDER 1 USE SALESMAN TAG SALES_IDถงตอนนเราลองมาดตวอยางโปรแกรมปอนขอมลกนเลนๆซกตวอยางแกเซงกนกอนแลวคอยวากนตอ ใหคณสรางโปรแกรมชอ program4.prg ทำาการปอนตามตวอยางดานลางแลวลองเรยกโปรแกรมนดวาเปนอยางไรอะๆ จะเรยกโปรแกรมใชคำาสง do program4 ท command window นะจะ* program4.prg PUBLIC oform1ON SHUTDOWN DO PRGERR && When program error click X (close foxpro) botton SET DELETE ONIF !USED('SALESMAN')select 0use SalesmanENDIFSET ORDER TO TAG SALES_IDGO TOPSCATTER MEMVARoform1=CREATEOBJECT("form1")oform1.Show()oform1.cmdGroup.oTop.Enabled=.F.oform1.cmdGroup.oPrev.Enabled=.F.
39
if reccount() = 0oform1.cmdGroup.oNext.Enabled=.F.oform1.cmdGroup.oBott.Enabled=.F.endifREAD EVENTRETURN
DEFINE CLASS form1 AS formHeight = 261Width = 633DoCreate = .T.AutoCenter = .T.Caption = "Salesman"ControlBox = .F.LockScreen = .F.Name = "Form1"
ADD OBJECT osales_id AS textbox WITH ;ControlSource = "m.sales_id", ;Enabled = .F., ;Height = 24, ;Left = 132, ;Top = 24, ;Width = 73, ;Name = "oSales_id"
ADD OBJECT oname AS textbox WITH ;ControlSource = "m.name", ;Enabled = .F., ;Height = 24, ;Left = 132, ;Top = 60, ;Width = 265, ;Name = "oName"
ADD OBJECT oaddress AS textbox WITH ;ControlSource = "m.address", ;
40
Enabled = .F., ;Height = 24, ;Left = 132, ;Top = 96, ;Width = 456, ;Name = "oAddress"
ADD OBJECT ocommrate AS textbox WITH ;Alignment = 3, ;Value = 0, ;ControlSource = "m.commrate", ;Enabled = .F., ;Format = "R", ;Height = 24, ;InputMask = "999.99", ;Left = 132, ;Top = 132, ;Width = 61, ;Name = "oCommrate"
ADD OBJECT cmdgroup AS commandgroup WITH ;ButtonCount = 8, ;Value = 1, ;Height = 39, ;Left = 12, ;Top = 192, ;Width = 615, ;Name = "cmdGroup", ;Command1.Top = 5, ;Command1.Left = 5, ;Command1.Height = 29, ;Command1.Width = 73, ;Command1.Caption = "Top", ;Command1.Name = "oTop", ;Command2.AutoSize = .F., ;Command2.Top = 5, ;Command2.Left = 81, ;
41
Command2.Height = 29, ;Command2.Width = 73, ;Command2.Caption = "Previous", ;Command2.Name = "oPrev", ;Command3.Top = 5, ;Command3.Left = 157, ;Command3.Height = 29, ;Command3.Width = 73, ;Command3.Caption = "Next", ;Command3.Name = "oNext", ;Command4.Top = 5, ;Command4.Left = 233, ;Command4.Height = 29, ;Command4.Width = 73, ;Command4.Caption = "Bottom", ;Command4.Name = "oBott", ;Command5.AutoSize = .F., ;Command5.Top = 5, ;Command5.Left = 309, ;Command5.Height = 29, ;Command5.Width = 73, ;Command5.Caption = "New", ;Command5.Name = "oNew", ;Command6.Top = 5, ;Command6.Left = 385, ;Command6.Height = 29, ;Command6.Width = 73, ;Command6.Caption = "Change", ;Command6.Name = "oChge", ;Command7.Top = 5, ;Command7.Left = 461, ;Command7.Height = 29, ;Command7.Width = 73, ;Command7.Caption = "Delete", ;Command7.Name = "oDele", ;Command8.Top = 5, ;Command8.Left = 537, ;
42
Command8.Height = 29, ;Command8.Width = 73, ;Command8.Caption = "Exit", ;Command8.Name = "oExit"
ADD OBJECT label1 AS label WITH ;Caption = "Salesman No.", ;Height = 18, ;Left = 24, ;Top = 24, ;Width = 88, ;Name = "Label1"
ADD OBJECT label2 AS label WITH ;Caption = "Name", ;Height = 18, ;Left = 75, ;Top = 60, ;Width = 37, ;Name = "Label2"
ADD OBJECT label3 AS label WITH ;Caption = "Address", ;Height = 18, ;Left = 62, ;Top = 96, ;Width = 50, ;Name = "Label3"
ADD OBJECT label4 AS label WITH ;Caption = "Commission", ;Height = 18, ;Left = 35, ;Top = 132, ;Width = 77, ;Name = "Label4"
43
PROCEDURE cmdgroup.oTop.Clickif !bof()go topscatt memvarthis.enabled=.F.this.parent.oPrev.enabled=.F.this.parent.oNext.enabled=.T.this.parent.oBott.enabled=.T.endifthisform.refreshENDPROC
PROCEDURE cmdgroup.oPrev.Clickif !bof()skip -1if bof()go topthis.parent.oTop.enabled=.f.this.enabled=.f.endifscatt memvarthis.parent.oNext.enabled=.T.this.parent.oBott.enabled=.T.endifthisform.refreshENDPROC
PROCEDURE cmdgroup.oNext.Clickif !eof()skip if eof()go bottthis.enabled=.F.this.parent.oBott.enabled=.F.endifscatt memvarthis.parent.oTop.enabled=.T.
44
this.parent.oPrev.enabled=.T.endifthisform.refreshENDPROC
PROCEDURE cmdgroup.oBott.Clickif !eof()go bottscatt memvarthis.enabled=.F.this.parent.oNext.enabled=.F.this.parent.oTop.enabled=.T.this.parent.oPrev.enabled=.T.endifthisform.refreshENDPROC
PROCEDURE cmdgroup.oNew.Clickif this.caption = 'New'scat memvar blankthisform.oSales_id.Enabled = .T.thisform.oName.Enabled = .T.thisform.oAddress.Enabled = .T.thisform.oCommrate.Enabled = .T.this.caption = 'Save'this.parent.oChge.caption = 'Cancel'this.parent.oTop.Enabled = .F.this.parent.oPrev.Enabled = .F.this.parent.oBott.Enabled = .F.this.parent.oNext.Enabled = .F.this.parent.oDele.Enabled = .F.this.parent.oExit.Enabled = .F. elsedo casecase this.caption = 'Save' .and. this.parent.oChge.caption = 'Cancel'if !empty(thisform.oSales_id.value)
45
INSERT INTO Salesman FROM MEMVARelsewait window 'Sales_id must be Entry! Program not save'endifcase this.caption = 'Save' .and. this.parent.oChge.caption = 'Reverse'GATHER MEMVARendcasethisform.oSales_id.Enabled = .F.thisform.oName.Enabled = .F.thisform.oAddress.Enabled = .F.thisform.oCommrate.Enabled = .F.this.caption = 'New'this.parent.oChge.caption = 'Change'this.parent.oTop.Enabled = .T.this.parent.oPrev.Enabled = .T.this.parent.oBott.Enabled = .T.this.parent.oNext.Enabled = .T.this.parent.oDele.Enabled = .T. this.parent.oExit.Enabled = .T.endifthisform.refreshENDPROC
PROCEDURE cmdgroup.oChge.Clickif recc() = 0 .and. this.parent.oChge.caption = 'Change'wait wind 'No data cannot change this record' elseif this.caption = 'Change'thisform.oSales_id.Enabled = .T.thisform.oName.Enabled = .T.thisform.oAddress.Enabled = .T.thisform.oCommrate.Enabled = .T.this.caption = 'Reverse'this.parent.oNew.caption = 'Save'
46
this.parent.oTop.Enabled = .F.this.parent.oPrev.Enabled = .F.this.parent.oBott.Enabled = .F.this.parent.oNext.Enabled = .F.this.parent.oDele.Enabled = .F.this.parent.oExit.Enabled = .F. elsedo casecase this.caption = 'Reverse'scatter memvarcase this.caption = 'Cancel' && for addnew recordgo bottscatter memvarendcasethisform.oSales_id.Enabled = .F.thisform.oName.Enabled = .F.thisform.oAddress.Enabled = .F.thisform.oCommrate.Enabled = .F.this.caption = 'Change'this.parent.oNew.caption = 'New'this.parent.oTop.Enabled = .T.this.parent.oPrev.Enabled = .T.this.parent.oBott.Enabled = .T.this.parent.oNext.Enabled = .T.this.parent.oDele.Enabled = .T. this.parent.oExit.Enabled = .T.endifendifthisform.refreshENDPROC
PROCEDURE cmdgroup.oDele.Clickif recc() = 0wait wind 'No data cannot delete this record' elsenAnswer = MESSAGEBOX('Confirm Delete', 4 + 32 + 256,'Delete Record')
47
DO CASECASE nAnswer = 6Deletego bottscatt memvarCASE nAnswer = 7* not DeleteENDCASEendifThisform.refreshENDPROC
PROCEDURE cmdgroup.oExit.ClickUSESET DELETE OFFthisform.releaseCLEAR EVENTon shutdownENDPROCENDDEFINE
PROCEDURE PRGERRCLEAR EVENTclose allclear allon shutdownENDPROCตวอยางทใหมานเปนตวอยางการปอนขอมลของ Salesman กลองทำาการปอนขอมลเลนๆไปสก 4-5 คนกอน แลวเราจะมาตอกนในบทตอไปเรองจดการขอมลภาคสองจดการขอมล(ตอ) บททแลวคณไดทราบวธการสรางฐานขอมล และแฟมดชน ตางๆแลว มาในบทน คณจะไดเรยนรถงการใชงานขอมล การกระทำากบขอมลวามวธการอยางไรบาง
48
จากตวอยาง program4 คณคงไดเหนคำาสงทเกยวกบการจดการขอมลมาบางแลว ทนเราจะมาทำาความเขาใจกบคำาสงตางๆเหลานนกน คำาสงแรกทจะทำาการพดถงกคอการเปดแฟมขอมล (table) ขนมาใชงาน เราใชคำาสง USE ซงมรปแบบดงนUSE [TableName | SQLViewName | ?] [IN nWorkArea | cTableAlias] [AGAIN] [NOREQUERY [nDataSessionNumber]] [NODATA] [INDEX IndexFileList | ? [ORDER [nIndexNumber | IDXFileName | [TAG] TagName [OF CDXFileName] [ASCENDING | DESCENDING]]]] [ALIAS cTableAlias] [EXCLUSIVE] [SHARED] [NOUPDATE]การเขยนโปรแกรมตางๆ นนการทำางานกบ table เราอาจจำาเปนตองทำาการเปด table หลายๆ table พรอมๆกนในโปรแกรมฉะนนเราจำาเปนตองกำาหนดตำาแหนง(Work Area) ใหกบ table นนๆดวยโดยใชคำาสง SELECT nWorkArea | cTableAliasคณลองปอนคำาสงตามตวอยางดานลาง ท command windows แลวลองสงเกตการทำางานของแตละคำาสงด (คณตองสราง database MYDATABASE กอน ตวอยางอยทบททแลว)CLOSE ALL OPEN DATABASE MYDATABASE SELECT 1USE SALESMANBROWSE SELECT 2 USE CUSTOMER
49
BROWSE SELECT SALESMAN BROWSE SELECT 0 USE PRODUCTBROWSE จากตวอยางเปนการกำาหนดตำาแหนงใหกบ table SALESMAN ใหอย ณ.ตำาแหนงท 1 และ table CUSTOMER อย ณ.ตำาแหนงท 2 และ table PRODUCT คณทราบหรอไมวาอยตำาแหนงทเทาไหร คำาตอบอยตำาแหนงท 3 เรารไดอยางไรละ ถาเราใชคำาสง SELECT 0 ในการกำาหนดตำาแหนง โปรแกรมจะทำาการหาตำาแหนงลางสดทยงวางอยมาใหซงกคอตำาแหนงท 3ในการเขยนโปรแกรมรบคาจากผใชแลวนำาคานนๆเพมเขาส table (ไมใชปอน) ใน Visual FoxPro กมคำาสงทสามารถทำาไดโดยใชคำาสงดงน INSERT INTO Salesman (SALES_ID,NAME,ADDRESS,COMMRATE), ; VALUE("10099","MR.SOMCHAI","175 SATHORN RD.",0.50)BROWSEหรอSELECT Salesman <APPEND BLANKREPLACE SALES_ID WITH "10099", NAME WITH "MR.SOMCHAI", ; ADDRESS WITH "175 SATHORN RD.", COMMRATE WITH 0.50BROWSEจากทงสองตวอยางเปนการเพมขอมลเขาส table SALESMAN เหมอนกนแตวธการเขยนคำาสงตางกน การใชงานนนขนอยกบความเหมาะสม ณ.ขณะนนวาจะเลอกใชงานแบบไหน ทนเรามาดรปแบบคำาสงของ INSERT INTO วาเปนอยางไร
50
INSERT INTO dbf_name [(fname1 [, fname2, ...])] VALUES (eExpression1 [, eExpression2, ...])- Or -INSERT INTO dbf_name FROM ARRAY ArrayName | FROM MEMVARคยเวรด MEMVAR มนหมายถงอะไร? การทำางานใน Visual FoxPro ทเกยวกบฐานขอมลถาเปนนกเขยนโปรแกรมจรงๆนะไมใชเลนๆ สวนใหญเขาจะใชตวแปรเมมโมร (memory variables) แทนการใชชอ ฟลด(field) ในการอางถงขอมลใน table ชอของตวแปรนจะเปนชอเดยวกนกบชอ ฟลด ใน table เพยงแตจะมตวสญลกษณบอกวาเปนตวแปรเมมโมร โดยนำา m.มาใสไวหนาชอฟลด เชน m.sales_id , m.name เปนตน แลวมนจะเกวยกบ คยเวรด MEMVAR ยงไง... คยเวรด MEMVAR เปนตวแทนของ ตวแปรเมมโมรทงหมดใน table เมอเราอางถง table นนๆทนเรามาดคำาสงเกยวกบการแกไขขอมล การนำาขอมลจาก table เกบไวในตวแปรเมมโมร และการนำาตวแปรเมมโมรกลบไป update ขอมลใน table จากตวอยาง program4 คณจะไดพบกบนพจนคำาสง scatter memvar, gather memvar สองตำาสงนเปนสวนหนงของการนำาขอมลจาก table มาเกบไวทตวแปรเมมโมร เรามาตววธใชกนดกวา ใหทำาการปอนคำาสงตามตวอยางดานลางท command windows แลวลองสงเกตวาเกดอะไรขนบางCLOSE ALL OPEN DATABASE MYDATABASE USE SALESMAN IN 1BROWSE && คณจะเหนขอมลเกาทปอนไวกอนหนาน กด ปม Esc เพอออกจาก browseGO TOPSCATTER MEMVAR ? m.sales_id + m.name + m.address + TRANSFORM(m.commrate, '@z 999.99')m.name = 'MR.ARKIRA SUPERMAN'm.commrate = 7.80
51
GATHER MEMVARBROWSE m.name='MRS.SOMSRI' REPLACE NAME WITH m.name BROWSE คำาสง SCATTER เปนการนำาขอมลจาก เรคคอรดปจจบนของ table มาเกบไวในตวแปรเมมโมร คำาสง GATHER เปนการ update ขอมลจากตวแปรเขาส table ณ.เรคคอรปจจบน สวนคำาสง REPLACE คลายกบ GATHER แตถาในกรณทตองการ update ทงเรคคอรด คำาสง gatter จะสะดวกกวาทนเรามาดรปแบบคำาสงของทง 3 คำาสงกนSCATTER [FIELDS FieldNameList | FIELDS LIKE Skeleton | FIELDS EXCEPT Skeleton] [MEMO] TO ArrayName | TO ArrayName BLANK | MEMVAR | MEMVAR BLANK | NAME ObjectNameถาในกรณทเราตองการตวแปรเมมโมรโดยไมตองการใหมขอมลจากเรคคอรเลย เราสามารถใช คยเวรด MEMVAR BLANK เราใชในกรณทตองการจะเพมขอมลใหมเขาไป เราจำาเปนตองทำาใหตวแปรนนๆวางเปลากอน เชน SCATTER MEMVAR BLANKGATHER FROM ArrayName | MEMVAR | NAME ObjectName [FIELDS FieldList | FIELDS LIKE Skeleton | FIELDS EXCEPT Skeleton] [MEMO]REPLACE FieldName1 WITH eExpression1 [ADDITIVE] [, FieldName2 WITH eExpression2 [ADDITIVE]] ...
[Scope] [FOR lExpression1] [WHILE lExpression2]
52
[IN nWorkArea | cTableAlias] [NOOPTIMIZE]ตอมากมาถงคำาสง ลบขอมล จรงๆไปหาอานไดทวไป เพราะคำาสงทใชคอคำาสงDELETE [Scope] [FOR lExpression1] [WHILE lExpression2] [IN nWorkArea | cTableAlias] [NOOPTIMIZE]หรอคำาสงDELETE FROM [DatabaseName!]TableName [WHERE FilterCondition1 [AND | OR FilterCondition2 ...]]สองคำาสงขางตนการทำางานเหมอนกนคอลบไดเหมอนกนแตตางกนตรงท คำาสงทสองทำาการลบไดโดยไมตองเปด table กอนกดเอาแลวกนวาทานสะดวกแบบใหนเลอกไดตามสบายสองตวบาทเดยวตงแตสมย dBASE เรอยมาการลบขอมลของ table นนเปนการลบหลอกๆ คอ จะทำาการทำาตำาหนไววาไดถกลบไปแลวแตจรงๆยงไมไดลบดงนนเราสามารถเรยกขอมลเกากลบมาไดโดยใชคำาสงRECALL [Scope] [FOR lExpression1] [WHILE lExpression2] [NOOPTIMIZE]แตถาเราตองการลบขอมลทถกลบไปแลวจรงๆ เพราะเหตวารกเหลอกเกน เปลองเนอท กใชคำาสง PACK ครบทาน ยงไปกวานนถาตองการลบทง table โดยไมสนใจเลยวาจะมเรคคอรใดถกลบหรอไม เอางายๆกคอลางทงทงหมดไฟล เหลอแตโครงราง(structure) ไวกใชคำาสง ZAP เรยบรอยโรงเรยนไทยทกลาวมายดยาวถงขนาดนถาผใดทเขยน FoxPro หรอโปรแกรมทำานองนอยแลวกขออภยไวดวยทหลงเขามาอาน ตอนนทำาไวใหมอใหมจะไดรวามขอมลอยจะทำากบมนอยางไร แลวจะตองใชคำาสงอะไรบางกเทานนเองการเขยนฟงกชน(Function)
53
อะไรเอยเขยนครงเดยวแตใชบอย?ฟงกชนคออะไร? ถาถามผม ผมบอกไดเลยวามนกคอคำาสงประเภทหนงเทานนเอง ใครทราบความหมายยาวๆบอกดวย รแตใชเทานนเองแตทแนนๆมนทำาใหผใชทำางานงายขน แตคนเขยนฟงกชนบางทกไมงายนะครบใน Visual FoxPro มประเภทของฟงกชนอย 2 ชนดดวยกน 1. ฟงกชนทมากบโปรแกรม (Visual FoxPro function) 2. ฟงกชนทผใชกำาหนดเอง (user-defined function (UDF))ฟงกชนทมากบโปรแกรมนนมอยมากพอสมควรแตยงไมพอหรอกครบ เพราะนสยของมนษยมนไมรจกพออยแลว เขากเลยอนญาตใหคณๆทงหลายทำามนขนมาไดเองจะทำาเปนอะไรกไดไมวากนตามสบาย แตกมขอแมในการทำาบางเลกๆนอยๆ หลกการทำาฟงกชนขนใชเองกไมไดยากเยนเขนใจอะไรมขอแมงายๆดงน 1. เวลาสรางตองเรมตนดวยคำาวา FUNCTION แลวกตามดวยชอของฟงกชน 2. ชอของฟงกชนยาวไดไมเกน 254 ตวอกษร ถาคณใชโปรแกรมทตำากวา Visual FoxPro ใชไดแค 10 ตว 3. ชอของฟงกชนตองไมไปซำากบชอของฟงกชน และคำาสงใน Visual FoxPro 4. คาสงผาน (parameter) จะมหรอไมมกได เทาทเหนเคาทำากนมทงนนแหละ 5. คาสงผานมไดสงสดใน 1 ฟงกชนไมเกน 24 คา 6. เมอเปนฟงกชนเวลาออกตองมคากลบมาเสมอ ไมวาจะเปนตวเลข ตวอกษร ตรรกะ วนท หรอคาทไมมคา(NULL) เปนตน 7. เขยนไดไมจำากดจำานวน ขยนกเขยนไปมแรงกทำาไป เขยนจนตายกไมจบ....ถายงไมรจกพอรหลกการทำาไปแลวมาดหลกการใชงานบาง 1. เราสามารถใชฟงกชนไดทกททเขยนเปนนพจนคำาสงได
54
และฟงกชนของ Visual FoxPro กสามารถเขยนได 2. สามารถเรยกฟงกชนซอนฟงกชนไดถง 32 ระดบ (ขอมลยงไมแนนอนตอนนอาจเยอะกวานกได แตยงไมเคยเหนใครเขยนเยอะขนาน 32 ระดบเลย)ทนเรามาดตวอยางการใชกนกอน (ขอยมของ ฟงกชนใน Visual FoxPro ใชกอนกแลวกน) myVAR = DATE() STOR MONTH(DATE()) TO thisMonth =CAPSLOCK(.T.) && กำาหนดใหปอนขอมลเปนตวอกษรใหญ DO WHILE !EOF() INSERT INTO Salesman(LASTUPDATE) VALUE(DATE())จากตวอยางขางตนเราจะสงเกตไดอยางไรวาอะไรเปนฟงกชน งายๆกคอหลงคำาสงนนๆจะมวงเลบ() อย แตอยางงละวา Salesman เปนฟงกชนเพราะมวงเลบ มนคนละเรองกนอนนนมนเปน คยเวรดของคำาสง INSERT INTO เรามาเรมเขยนฟงกชนใชกนดกวา เรมงายๆลองปอนโปรแกรมตามตวอยางขางลางกอนเปนการนำา ฟงกชนของ Visual FoxPro มาดดแปลงใหเปนตามแบบทเราตองการเพอความสะดวกของเราเองใหสรางโปรแกรมชอ UTILITY.PRG จาก command windows ปอน modify command UTILITY แลวพมพคำาสงตามตวอยางดานลางลงไปFUNCTION MyMessagePARAMETER cMessageText,cMessageTitle * 4 = Yes and No buttons * 32 = Question mark icon * 256 = Secound buttons is default * return value 6 for click YES * return value 7 for click NO
55
RETURN MESSAGEBOX(cMessageText,4+32+256,cMessageTitle)เวลาเราทำาการเรยกใชฟงกชน ใหคณทำาการปอนคำาสง SET PROCEDURE TO UTILITY เพอบอกใหโปรแกรมทำาการหาฟงกชนจาก โปรแกรมทเรากำาหนดไวกคอโปรแกรม UTILITY หลงจากนนเราลองทำาการทดสอบฟงกชนของเราด ใหปอนคำาสงตอไปนท command windows ดวาเกดอะไรขนบาง? MyMessage('ตองการบนทกขอมล','บนทกขอมล')nAnswer = MyMessage('ตองการบนทกขอมล','บนทกขอมล')?nAnswer ทานทราบหรอไมวาเมอเราทำาการเรยกใชงานฟงกชนใน Visual FoxPro มลำาดบการคนหาวาฟงกชนทเราเรยกใชงานนนอยางไร ลำาดบแรกเลยถาเรามการเรยกใชงานฟงกชนใดๆกตามโปรแกรมจะทำาการหาทฟงกชนของ Visual FoxPro กอน ลำาดบถดมาโปรแกรมจะทำาการหาท โพซเยอร(Procedure) ทเราทำาการเปดอย เราเปดโดยใชคำาสง set procedure to .... สดทายถาหาทงสองทไมเจอกจะทำาการหาท โปรแกรม .prg เชน เรยกใชฟงกชน MyMessage กจะทำาการหาวามโปรแกรมชอ MyMessage.prg หรอไม ถามกเรยกใชงานให ถายงหาไมเจออกกจะขน Error วา File '????????.prg' does not existในการเขยนฟงกชนขนมานน เมอเราเขยนเสรจเรยบรอยแลวเราควรจะทำาการเกบเปนหมวดหมหรอ Library ไว เวลาเรยกใชงานหรอนำาไปใชงานจะไดสะดวก แลวจะทำาอยางไรละ? จากตวอยางขางตนผมใหสรางโปรแกรมชอ utility.prg ขนมาเพอทำาการเกบ ฟงกชนทเราไดทำาการเขยนขนมา ใน 1 โปรแกรมเราสามารถใสฟงกชนทเราเขยนขน
56
มาไดเรอยๆขนอยกบ memory ของเครองคณวาจะรบไดแคไหน โดยการเขยนตอๆกนไปเรอยๆ ดงน* utility.prgFUNCTION MyMessage......RETURN <value>FUNCTION tCDOWPARAMETER dDATE nDay=DOW(dDATE) DO CASE CASE nDAY=1RETRUN 'อาทตย' CASE nDAY=2RETRUN 'จนทร' CASE nDAY=3RETRUN 'องคาร' CASE nDAY=4RETRUN 'พธ' CASE nDAY=5RETRUN 'พฤหสบด' CASE nDAY=6RETRUN 'ศกร' CASE nDAY=7RETRUN 'เสาร' ENDCASERETURN ''FUNCTION myFunction......RETURN.....เมอเราทำาการเขยนโปรแกรมททำาการเกบฟงกชนตางๆแลว เวลาจะนำามาใชงานเราตองประกาศให Visual FoxPro ทราบกอน โดยใช
57
คำาสง set procedure to ซงเคยยกตวอยางไวใหดแลวในตอนตนทนเรามาดรปแบบคำาสงวาเปนอยางไรSET PROCEDURE TO [FileName1 [, FileName2, ...]] [ADDITIVE]เชน SET PROCEDURE TO UTILITY,MYFUNCTION,STATFUNCTION SET PROCEDURE TO FORMFUNCTION ADDITIVEสวนใหญการประกาศใชฟงกชนเราจะกระทำากนท main program ประกาศไวครงแรกครงเดยวกพอตอไปนเปนตวอยางฟงกชน ถาคณมฟงกชนทดๆแลวตองการเผยแพรกรณาสงมาหาเราเราจะเปนสอกลางใหDownload NUM2CH.PRG* ---FUNCTION NUM2CH* ---โปรแกรม...... เปลยนตวเลขเปนตวอกษร (9,999,999,999.99)* ---ผเขยน........ Kasem K.* ---วนแกไข....... 12.08.92*-- นำาไปใช...... cSTRING=NUM2CH(9999.22)***************************************************************FUNCTION NUM2CHPARA mNUM && เลขไมเกน 10.2 หลกPUBL mTCH(9),mTDEC(10)mTCH(1)='หนง'mTCH(2)='สอง'mTCH(3)='สาม'mTCH(4)='ส'mTCH(5)='หา'mTCH(6)='หก'
58
mTCH(7)='เจด'mTCH(8)='แปด'mTCH(9)='เกา'mTDEC(1) ='พน'mTDEC(2) ='รอย'mTDEC(3) ='สบ'mTDEC(4) ='ลาน'mTDEC(5) ='แสน'mTDEC(6) ='หมน'mTDEC(7) ='พน'mTDEC(8) ='รอย'mTDEC(9) ='สบ'mTDEC(10)=''mSTNUM=STR(mNUM*100,12)mSTTHAI=''mCNT=1DO WHIL mCNT<=10 mCHNUM=SUBSTR(mSTNUM,mCNT,1) IF mCHNUM=' ' mSTTHAI=mSTTHAI+'' ELSE IF mCHNUM='0' mSTTHAI=IIF(mCNT=4,mSTTHAI+'ลาน',mSTTHAI+'') ELSE IF mCHNUM='1' IF (mCNT=4.AND.LEN(LTRIM(mSTNUM))#9).OR.(mCNT=10.AND.LEN(LTRIM(mSTNUM))#3) mSTTHAI=mSTTHAI+'เอด' ELSE IF .NOT.(mCNT=3.OR.mCNT=9)
59
mSTTHAI=mSTTHAI+mTCH(VAL(mCHNUM)) ENDIF ENDIF ELSE IF mCHNUM='2'.AND.(mCNT=3.OR.mCNT=9) mSTTHAI=mSTTHAI+'ย' ELSE mSTTHAI=mSTTHAI+mTCH(VAL(mCHNUM)) ENDIF ENDIF mSTTHAI=mSTTHAI+mTDEC(mCNT) ENDIF ENDIF mCNT=mCNT+1ENDDOmSTTHAI=mSTTHAI+'บาท'IF SUBSTR(mSTNUM,11,2)='00' mSTTHAI=mSTTHAI+'ถวน'ELSE mCHNUM=SUBSTR(mSTNUM,11,1) IF mCHNUM#'0' IF mCHNUM#'1' IF mCHNUM='2' mSTTHAI=mSTTHAI+'ย' ELSE mSTTHAI=mSTTHAI+mTCH(VAL(mCHNUM)) ENDIF ENDIF mSTTHAI=mSTTHAI+mTDEC(9) ENDIF mCHNUM=SUBSTR(mSTNUM,12,1) IF mCHNUM#'0'
60
IF mCHNUM='1'.AND.SUBSTR(mSTNUM,11,1)#'0' mSTTHAI=mSTTHAI+'เอด' ELSE mSTTHAI=mSTTHAI+mTCH(VAL(mCHNUM)) ENDIF ENDIF mSTTHAI=mSTTHAI+'สตางค'ENDIFRETU mSTTHAI* ---TSCDOW.PRG* ---ผเขยน........ Kasem K.* ---วนแกไข....... 12.08.92*-- นำาไปใช...... cDayofWeek=TSCDOW(DATE())* ---โปรแกรม.... ROUTINE ใหคาชอวนไทยแบบยอFUNCTION TSCDOWPARA mdtmmdtnm=DOW(mdtm)mcdm=SUBST('อาจ.อ.พ.พฤศ.ส.',2*mdtnm-1,2)RETU (mcdm)*----------------------------------------* โปรแกรม : MLOGIC.PRG* เขยโดย : พณฯ เกษม* สราง : 01/09/92* มนคอ : GAME ใชฝกสมอง มนษยเหลก 2022* สญลกษณ : C=ถกส , P = ถกตำาแหนง*----------------------------------------PROCEDURE MLOGICDECL S(5),X(5)DEFI WIND MLOGIC FROM 1,10 TO 21,45;TITLE "MASTER LOGIC" FOOT "ESC - EXIT";GROW SYSTEM ZOOM COLO N/BG,N/BR,B+/WACTI WIND MLOGIC
61
DO WHIL .T.CLEASTOR .F. TO FLAGSTOR 0 TO S(1),S(2),S(3),S(4),S(5)STOR 0 TO L,POSI,COLFSTOR 0 TO SCORESTOR '' TO Q_A@0,1 SAY 'SELECT : ' COLO 5+/3@2,0 SAY 'C P' COLO 2+/3@2,4 TO 2,22@0,24 TO 9,32@1,25 SAY 'LEGENT' COLO 6+/3@2,25 SAY '1'@2,28 SAY ' ' COLO /1@3,25 SAY '2'@3,28 SAY ' ' COLO /2@4,25 SAY '3'@4,28 SAY ' ' COLO /3@5,25 SAY '4'@5,28 SAY ' ' COLO /4@6,25 SAY '5'@6,28 SAY ' ' COLO /5@7,25 SAY '6'@7,28 SAY ' ' COLO /6@8,25 SAY '7'@8,28 SAY ' ' COLO /7@10,24 TO 13,32@11,25 SAY 'SCORE'DO WHIL SCORE < 15IF SCORE=0FOR I = 1 TO 5STOR STR(INT(RAN(1,8)),1) TO X(I)Q_A=Q_A+X(I)NEXT@ 3,0 SAY '=>' COLO 0/3ELSE@ 3+SCORE-1,1 SAY ' '
62
@ 3+SCORE,0 SAY '=>' COLO 0/3ENDIF@1, 6 GET S(1) PICT'@Z 9' RANG 1,7 COLO ,7+;VALID(SAYCOL(S(1),1,6) .AND.SAYCOL(S(1),3+L,6 ))@1,10 GET S(2) PICT'@Z 9' RANG 1,7 COLO ,7+;VALID(SAYCOL(S(2),1,10).AND.SAYCOL(S(2),3+L,10))@1,14 GET S(3) PICT'@Z 9' RANG 1,7 COLO ,7+;VALID(SAYCOL(S(3),1,14).AND.SAYCOL(S(3),3+L,14))@1,18 GET S(4) PICT'@Z 9' RANG 1,7 COLO ,7+;VALID(SAYCOL(S(4),1,18).AND.SAYCOL(S(4),3+L,18))@1,22 GET S(5) PICT'@Z 9' RANG 1,7 COLO ,7+;VALID(SAYCOL(S(5),1,22).AND.SAYCOL(S(5),3+L,22))READmKEY=READK()DO CASECASE mKEY=12.OR.mKEY=268FLAG=.T.EXITENDCASE* PROCESSSTOR 0 TO POSI,COLFFOR I = 1 TO 5IF STR(S(I),1)=X(I)POSI=POSI+1ENDIFIF STR(S(I),1)$Q_ACOLF=COLF+1ENDIFNEXTIF POSI=5SCORE=SCORE+1@ 12,27 SAY SCORE PICT '@Z 99'
63
TEMP=WARNN(' YOU HAVE A WINNER ! ',10)EXITENDIF* END PROCESSSCORE = SCORE+1@ 3+L,0 SAY COLF PICT '9' &&COLO 7+/3@ 3+L,2 SAY POSI PICT '9' &&COLO 7+/3@ 12,27 SAY SCORE PICT '@Z 99'L = L +1ENDDOIF FLAGEXITENDIFIF POSI#5DEFI WIND IWIN FROM 7,1 TO 12,29;TITLE "o REPLY BOX o" GROW SYSTEM ZOOM COLO N/N,N/BR,B+/WACTI WIND IWIN@0,1 TO 4,25@1, 4 SAY ' '+X(1)+' ' COLO 7+/&X(1)@1, 8 SAY ' '+X(2)+' ' COLO 7+/&X(2)@1,12 SAY ' '+X(3)+' ' COLO 7+/&X(3)@1,16 SAY ' '+X(4)+' ' COLO 7+/&X(4)@1,20 SAY ' '+X(5)+' ' COLO 7+/&X(5)@2, 4 SAY ' ' COLO /&X(1)@2, 8 SAY ' ' COLO /&X(2)@2,12 SAY ' ' COLO /&X(3)@2,16 SAY ' ' COLO /&X(4)@2,20 SAY ' ' COLO /&X(5)TEMP=WARNN(' I WINNER !!! ',10)RELE WIND IWINENDIFENDDORELE WIND MLOGICRETU
FUNCTION SAYCOL
64
PARA SEL,ROW,COLXCSEL=STR(SEL,1) @ROW,COLX-2 SAY ' '+CSEL COLO &CSEL+/&CSEL,/&CSELRETU .T.
* ---RAN.PRG* ---ผเขยน...... Kasem K.* ---แกไขลาสด... 17/09/92* ---โปรแกรม.... รทนสรางตวเลขสมระหวางชวงFUNCTION RANPARA RA,RBRETU (RB-RA)*RAND()+RA
*!**********************************************************************!*! Procedure: WARNN*!*!*********************************************************************PROCEDURE warnnPARA mmsg,mtime*SET COLO OF SCHE 9 TO N/BG,N/RB,RG/Wmlen=lcut(mmsg)mmsg=' '+REPL(' ',LEN(mmsg)-mlen)+mmsg+' 'DEFI WIND warnn FROM 19,4 TO 21,LEN(mmsg)+5 SYST ;SHAD FLOAT NOZOOM COLO SCHE 9ACTI WIND warnn*@23,40-(mLEN/2) SAY mMSG@0,0 SAY mmsg??CHR(7)i=INKEY(mtime)
65
*@23,40-(mLEN/2) SAY SPAC(LEN(mMSG))RELE WIND warnnRETU&& ถาคณมปญหาเกยวกบการจดเรยงขอมลภาษาไทยตองอนนDownload ITHAI.PRG* ---ITHAI.PRG* ---แกไขลาสด... 06/02/35* ---โปรแกรม.... ROUTINE FUNCTION INDEX THAI LANGUAGE* การใชงานนนใชตอน index on ithai(name) tag sortthai && ถาขอมลเยอะๆชาครบ* ขอแนะนำาใหทำาการสราง filed เพมอก 1 ฟลดสมมตชอ sortname ตอนปรบปรงฟลดนนใหเพมคำาสง * REPLACE SORTNAME WITH ITHAI(NAME) วธนคณสามารถนำาฟลดไปใชในคำาสง SQL ไดดวยFUNCTION ithaiPARA str0mstr=TRIM(str0)+' 'mlen=LEN(mstr)IF mlen<=1RETU mstrENDIFmcnt=1DO WHIL mcnt<=mlenmchr=SUBSTR(mstr,mcnt,1)IF mchr$'เแโไใ'mstr=LEFT(mstr,mcnt-1)+SUBSTR(mstr,mcnt+1,1)+SUBSTR(mstr,mcnt,1)+RIGHT(mstr,mlen-(mcnt+1))mcnt=mcnt+1ENDIFmcnt=mcnt+1ENDDOmcnt=1
66
DO WHIL mcnt<=mlenmchr=SUBSTR(mstr,mcnt,1)IF mchr$'
'
mstr=LEFT(mstr,mcnt-1)+SUBSTR(mstr,mcnt+1,1)+SUBSTR(mstr,mcnt,1)+RIGHT(mstr,mlen-(mcnt+1))mcnt=mcnt+1ENDIFmcnt=mcnt+1ENDDORETU mstr
* ---LCUT.PRG* ---แกไขลาสด... 02/09/34* ---โปรแกรม.... ROUTINE นบความยาวโดยตดอกขระบนลาง*!**********************************************************************!*! Procedure: LCUT*!*!*********************************************************************FUNCTION lcutPARA mstrcnt0 = 1cnt00 = 0DO WHIL cnt0 <= LEN(mstr)IF SUBS(mstr,cnt0,1) $ '
'cnt00 = cnt00 + 1ENDIFcnt0 = cnt0 + 1ENDDORETU (LEN(mstr) - cnt00)
*!
67
**********************************************************************!*! Procedure: STIFF*!*!*********************************************************************FUNCTION stiffPARA ma,mbmb=TRIM(LTRIM(mb))mt=LEFT(ma,LEN(ma)-LEN(mb))+mbRETU mt Visual Class Library Visual Class Library(.VCX) มไวทำาอะไร? คณคงเคยทำาการสรางฟอรมใน Visual FoxPro มาบางแลว ถาคณทำาการสรางโดยใช base class ลวนๆ คณจะพบกบความยงยากในการกำาหนด รปแบบตวอษร(font) ทใชในการแสดงภาษาไทยในคลาสตางๆ เชน Textbox,Label,CommandButton เปนตน ซงคณตองกำาหนดทกๆครง ทคณทำาการเพมมนเขามาในฟอรมของคณ หรอในกรณทเราสรางฟอรมแลวตองการใหฟอรของเราขยายใหญเตมจอ มปมคอนโทรเมนแทนทจะเปนรปไอคอนสนกจงจอกเรากเปลยนเปนแบบของเราเอง หรอถาเราตองใชชด ของปมคำาสงรปแบบใดรปแบบหนง แตเปนลกษณะคลายๆกนในเกอบทกๆฟอรมททำาการสราง หรอ เราตองการแสดงฟอรมรปแบบนในอกหลายๆครงเชน ฟอรมการออกรายงานเปนตน โดยทเราไมอยางมาสรางใหมหรอมากำาหนด properties ,event ,method ใหมทกครง หรออนอกมากมายบรรยายไมหมด ดงนน Visual FoxPro จงอนญาตใหเราสามารถสราง คลาสขนมาใหมไดโดยการใชคำาสง CREATE CLASS เพอสนองความตองการของเราๆทงหลาย โดยมรปแบบคำาสงดงน
68
CREATE CLASS ClassName | ? [OF ClassLibraryName1 | ?] [AS cBaseClassName [FROM ClassLibraryName2]] [NOWAIT]ลองมาสรางคลาสดสงตวกอน โดยใหคณทำาการพมพคำาสงท command window ดงน CREATE CLASS MyTextBoxจากนนคณจะไดพบกบหนาจอดงภาพดานลาง
Class Name คอชอ คลาสทเรากำาหนดขนคอ MyTextBoxBased On เปนการกำาหนดใหคลาสทเราสรางเปน sub-class ของคลาสใด ใหคณเปลยนเปน TextBoxStore In กำาหนดใหเกบไวทแฟมขอมลชออะไร แฟมนจะมนามสกลเปน .VCX พมพชอวา MyClass จากนนก คลกท OKหรอคณอาจใชคำาสง CREATE CLASS MyTextBox OF MyClass AS TextBox กไดจากนนกจะไดคลาสใหมเปน MyTextBox ดงรป
ใหคณกำาหนด Properties ดงน(โดยคลกขวาท mouse แลว
69
เลอก properties)FontName เปน CordiaUPCFontSize ขนาด 14 FontBold เปน .F.จากนนกกด Ctrl+W เพอทำาการบนทก คณกจะไดคลาสใหมขนมาเปนของคณเองเราเรยกมนวาคลาสยอย(sub-class)จรงๆแลวคณควรจะทำาการสราง ใหครบทก control ของ base class เพอเกบไวใชงานแทน base class เดมของ Visual FoxPro จะเปนการดมากเลยนะจะบอกใหหลงจากคณทำาการสรางมนเรยบรอยแลวเวลาคณจะนำาไปใชคณตองประกาศโดยใชคำาสงSET CLASSLIB TO ClassLibraryName [ADDITIVE] [ALIAS AliasName]เชน SET CLASSLIB TO MyClass ADDITIVEหรอ ถาคณอยใน form designer ใหเลอก จาก form controls แลวเลอก Add เลอกชอไฟล .VCX ทตองการในการสรางคลาสยอย(sub-class)ขนมานน จรงๆมอยหลายวธดวยกนทผมกลาวมากเปนวธสรางวธหนงเทานนแลวถาคณจะทำาการปรบปรงแกไข ทำาการลบคลาสบางคลาสทสรางขนมา หรอแมแตจะด properties,event,method ของคลาสนนๆ หรอพมพ Code program ออกมาด ถาผมบอกคำาสงไปเรอยๆกคงจบยากเพราะคำาสงมนเยอะ สรปงายๆผมมคำาสงหนงในการจดการเกยวกบ Visual Class Libary(VCX) ทจะบอกใหคณทราบ ใหคณพมพคำาสงท command window ดงน DO (_BROWSER) && พมพใหเหมอนนะครบไมงนไมออกไมรดวย แตอาจเปนตวเลกกได หรอ เลอกท เมน Tools แลวเลอก Class Browser แลวทำาการเลอกแฟมขอมลทตองการ ใหเลอก MyClass.VCX หรอถาพมพเปนชอใหมกจะถอวาเปนการสราง
70
VCX ขนมาใหม
เปนคำาสงสรางคลาสใหม เหมอนกบคำาสง CREATE CLASS
ถาตองการแกไขคลาสเดมให Double Click ทชอคลาสไดเลยสวนตวนเอาไวด soruce code คณสามารถใช class
browser ตวนในการด source code ของ ฟอรมทคณสรางขนมากได โดยตอนเรยก class browser ขนมาแลวตอนเลอกชอไฟลทตองการใหไปเปลยนท file of type เปน form แลวกเลอกชอ ฟอรมทตองการทนเรามาลองสราง Visual Class Library งายๆดสกตวสองตวกอนตวแรกเปนนาฬกาบอกเวลากแลวกนใหคณทำาการเรยก คำาสง DO (_BROWSE) ท command window แลวปอนชอไฟลวา clockกดปม เพอสรางคลาสใหม ในชอง Class Name ใหตงชอวา digitalclockชอง Based On เลอก Container กดปม OK
71
คณจะไดพบกบ Class Designer ซงจะมลกษณะเหมอนกบ Form Designer ใหคณเลอก คอนโทรล Label จาก Form Control แลวเลอก คอนโทรล Timer แลวกำาหนด Properties ดงนdigitalclock กำาหนด properties เปน Width = 145 Height = 30 BorderWidth = 0 Name = "digitalclock"label กำาหนด properties เปน AutoSize = .F. FontSize = 15 Alignment = 2 Caption = "" Height = 27 Left = 0 Top = 0 Width = 145 Name = "Label1" แลวกำาหนดในสวนของ init event ดงน this.caption=time()timer กำาหนด properties เปน Interval = 1000 Name = "Timer1" แลวกำาหนด ในสวนของ timer event ดงน this.parent.label1.caption = time()จากนนใหสราง ฟอรม หรอ โปรแกรมขนมาลองทดสอบดวาไดผลอยางไร ถาคณสะดวกสราง ฟอรมกทำาไดเลย แตตอนนผมขอทำาการสรางโปรแกรมใหดกอน ใหพมพ คำาสง MODIFY COMMAND PROGRAM5 ท command window แลวปอนคำาสงตามตวอยางดานลาง แลวลอง do program5 ด....
72
* PROGRAM5.PRGPUBLIC oform1SET CLASSLIB TO HOME() + 'clock.vcx' ADDITIVEoform1=CREATEOBJECT("form1")oform1.Show()RETURN
**************************************************DEFINE CLASS form1 AS form Top = 0 Left = 0 Height = 81 Width = 193 DoCreate = .T. Caption = "ทดสอบนาฬกา" Name = "Form1"
ADD OBJECT digitalclock1 AS digitalclock WITH ; Top = 24, Left = 24, Width = 145, Height = 30, ; Name = "Digitalclock1", ; Label1.Name = "Label1", ; Timer1.Name = "Timer1"
ENDDEFINE*-- EndDefine: form1**************************************************ตอนนผมจะขออธบาย properties บางตวใหทานทราบสกหนอยObject.Name[ = cName] เชน Timer1.Name="Timer1" เปนการตงชอ object เวลาใชงานเราจะใชชอนในการอางถง object ตวนนๆTimer.Interval[ = nTime] เชน INTERVAL = 1000 เปนการตงลป(loop) หนวงเวลา 1000 จะเทากบ 1 วนาท เมอทำางาน
73
ครบแลวจะใหทำาอะไรเรากทำาการกำาหนดใน timer event ถาคณกลบไปดใน timer event จะเปนการใหแสดงเวลาขนมาใน label1
เคลดไมลบ เมอคณทำางานกบแฟม .VCX (Visual Class Library) แลวคณรสกวาไฟลของคณใหญผดปรกต ใหคณทำาดงนทำาการเปดแฟม .VCX โดยใชคำาสง USE <ชอแฟม.VCX> เมอเปดเสรจแลวใหใชคำาสง PACK แลวทำาการปดแฟมโดยใชคำาสง USE เทานแฟม .VCX ของคณกจะมขนาดเลกลงอยางนาใจหาย ทนเรามาทำาการสราง Visual Class Library ซงเปนเครองคด
เลขกนดกวาDOWNLOAD ตวอยางโปรแกรมเครองคดเลข ใหคณลองทำาตามตวอยางดานลางอนนจะยงหนอยเพราะจะมการสราง properties และ event(method) ขนมาใชงาน
ท command window ใหคณพมพคำาสง do (_browser) จากนนใหพมพชอ แฟมวา CALCULATOR แฟมนจะมนามสกลวา .VCX
ใหทำาการสรางคลาสแรกขนมา โดยใชทลบาร เพอทำาการสรางคลาสใหม แลวทำาการตงชอดงนClass Name = calacBased On = commandbutton แลวคลกทปม OK ตอมาทำาการกำาหนด properties ดงนHeight = 27 , Width = 30 , Caption = "AC" , Name = "calac" ในสวนของ Event Click ใหพมพคำาสงดงนWITH This.parent.r_LCalculate = .F. .r_LNewValue = .T. .r_LNewMath = .T. .calText.Value = ""
74
.calmath.Value = "" .r_NCaltxt = 0 .r_ColdMath = "+" .r_LDot = .T.ENDWITHในสวนของ Event Keypress ใหพมพคำาสงดงนwith this.parent =.m_keypress(nKeyCode)endwithตอมาทำาการสรางคลาสทสอง Class Name = calmathBased On = textboxกำาหนด properties ดงนAlignment = 2 , Enabled = .F. , Height = 24 , Width = 20 , Name = "calmath"ทำาการสรางคลาสทสามClass Name = caltextBased On = textboxกำาหนด properties ดงนAlignment = 1 , Enabled = .F. , Height = 24 , Width = 192 , Name = "caltext" , ControlSource = ""ทำาการสรางคลาสทสClass Name = calnumberBased On = commandbuttonกำาหนด properties ดงนHeight = 27 , Width = 30 , Caption = "" , Name = "calnumber" ในสวนของ Event Click ใหพมพคำาสงดงนWITH This.parent IF this.caption="." .and. !.r_ldot RETURN ENDIF IF this.caption="." .r_ldot = .f. ENDIF
75
IF .r_LNewValue .calText.value = This.Caption ELSE .calText.value = ALLTRIM(.calText.value) + This.Caption ENDIF .r_LNewValue = .F. .r_LCalculate = .T. .r_LNewMath = .T.ENDWITHในสวนของ Event Keypress ใหพมพคำาสงดงนwith this.parent =.m_keypress(nKeyCode)endwithทำาการสรางคลาสทหาClass Name = calsign && สงเกตวาในคลาสนผมไมไดกำาหนด event keypress ไวแตมนจะอางจาก calnumberBased On = calnumber && สวนของ properties กเชนเดยวกนมนกจะไปอางจาก calnumber ใหอตโนมตกำาหนด properties ดงนName = "calsign" ในสวนของ Event Click ใหพมพคำาสงดงนwith this.parent if .r_lnewmath .cmdenter.click .r_coldmath = this.caption .calmath.value = this.caption .r_lnewvalue = .t. .r_ldot = .t. endifendwith ทำาการสรางคลาสทหกคลาสนสำาคญคณควรทำาความเขาใจไวใหมากๆ ในคลาสนจะมการสราง properties และ event(method) ขนมาใชงานในคลาส
76
เอง เนองจากวา คอนโทรลของ Visual FoxPro นนแตละคอนโทรลจะม properties และ event(method) ไมเหมอนกน แตเรามความตองการใชงาน event(method) บางอยางทอยใน คอนโทรลอน เรากตองทำาการสรางมนขนมาแลวกเรยกมนใชงานโดยทำาการเรยกผานจากคอนโทรลตวอนๆอกท งงหรอยงถายง มาทำากนตอ ทำาการตงชอคลาสนวาClass Name = calculatorBased On = containerกำาหนด properties ดงนHeight = 220 , Width = 160 , BorderWith = 0 , Name = "calculator"จากนนใหทำาการสราง properties ขนมาใชงานเองดงน ใหไปคลกทเมน Class เลอก New Property จากนนใหพมพชอ property ทตองการจะสราง ใหทำาการสราง property ขนมา 6 ตวตามรายชอดงตอไปนr_LCalculate r_LNewValue r_LNewMathr_NCalTxtr_COldMathr_LDotเมอสรางเสรจเรยบรอยแลวใหเขาไปกำาหนด properties ของคลาส calculator ซง properties นจะอยในสวนของ Other ซงจะเปนทเกบ properties ทเราทำาการสรางขนมาใหม แลวเขาไปทำาการกำาหนดคาตางๆดงนr_LCalculate = .F.r_LNewValue = .T.r_LNewMath = .T.r_NCalTxt = 0r_COldMath = "+"r_LDot = .T.จากนนใหทำาการสราง method ขนมา ใหไปคลกทเมน Class
77
เลอก New Method จากนนใหพมพชอ Method ทตองการจะสราง ใหทำาการสรางขนมา 2 method ดงน m_str && เปนการแปลงคาตวเลขใหเปนตวอกษรทเปนตวเลข เชน 123 เปน "123"m_keypress && เปนการกำาหนดให container สามารถรจกการกดปม โดยการอางจากคอนโทรลตวอนแลวใหไปทำาการกำาหนด event ของ method m_str โดยการคลกขวาเลอก properties metohd ทสรางขนมาใหมจะอยในสวนของ methods ใหทำาการพมพคำาสง ของ method m_str ดงนLPARAMETERS pnValueLOCAL lcValuelcValue = ALLTRIM(STR(pnValue, 20, 8))* Now remove all zeros after the decimal pointDO WHILE RIGHT(lcValue, 1) = '0' lcValue = LEFT(lcValue, LEN(lcValue)-1)ENDDO* Remove the decimal point if it is the last characterIF RIGHT(lcValue, 1) = '.' lcValue = LEFT(lcValue, LEN(lcValue)-1)ENDIFRETURN (lcValue)
ใหกำาหนด method m_keypress ดงนLPARAMETERS nKeyCodeLOCAL c_Chr,c_Click,c_Setfocusdo casecase nKeyCode = 27 && Esc = close calculator thisform.release()case nKeyCode = 13 && Enter this.cmdenter.click this.cmdenter.setfocuscase BETWEEN(chr(nKeyCode),"0","9") c_chr=chr(nKeyCode)
78
c_Click="this.cmd"+c_chr+".click" c_Setfocus="this.cmd"+c_chr+".setfocus" &c_click &c_Setfocus case chr(nKeyCode) = "." this.cmddecimal.click this.cmddecimal.setfocuscase INLIST(chr(nKeyCode),"C","c") this.calac10.click this.calac10.setfocuscase chr(nKeyCode) = "+" this.calplus.click this.calplus.setfocuscase chr(nKeyCode) = "-" this.calminus.click this.calminus.setfocuscase chr(nKeyCode) = "*" this.calmult.click this.calmult.setfocuscase chr(nKeyCode) = "/" this.caldiv.click this.caldiv.setfocusendcase
เมอเราทำาการกำาหนด properties และ methods ตางๆเรยบรอยแลวตอไปนเราจะทำาการนำาคอนโทรลคลาสทงทเราทำาการสรางไวกอนหนานแลวใสไวใน container calculatorกอนอนเราตองทำาการเพม Visual Class Library(.VCX) ของเราเขาไปไวใน form control กอนเพราะไมเชนนนเรากไมสามารถนำาคลาสทเราทำาไวกอนหนานมาใสไวใน container calculator นได ใหเลอก จาก form controls แลวเลอก Add ใหเลอกชอไฟล CALCULATOR.VCX จากนนเรากจะไดเหนคอนโทรลคลาสทเราไดสรางไว
79
ใหทำาปม Enter กอนอนดบแรกโดยทำาการคลกท ปม calsign ใน form control จากนนกทำาการคลก ท container calculator เรากจะไดปม commandbutton ขนมา 1 ปม ใหทำาการกำาหนด properties ของปมดงนTop = 192 , Left = 37 , Height = 24 , Width = 84 Caption = "Enter" , TabIndex = 1 , Name = "CmdEnter"จากนนใหทำาการกำาหนดในสวนของ Click Event ดงนWITH This.parentif .r_lcalculate if !empty(.r_ColdMath) do case case .r_ColdMath = "+" .r_Ncaltxt = .r_Ncaltxt + VAL(.calText.Value) case .r_ColdMath = "-" .r_Ncaltxt = .r_Ncaltxt - VAL(.calText.Value) case .r_ColdMath = "*" .r_Ncaltxt = .r_Ncaltxt * VAL(.calText.Value) case .r_ColdMath = "/" .r_Ncaltxt = .r_Ncaltxt / VAL(.calText.Value) endcase endif .r_LNewValue = .T. .r_LDot = .T. .calText.value = .m_str(.r_NcalTxt) .r_lcalculate = .F.endif ENDWITHเมอเราไดทำาการสรางปม enter ขนมาเรยบรอยแลวตอไปใหทำาการสรางปมหมาเลข 0 ถง เลข 9 ตอดงน
ปมเลข 1 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties ของปมดงน
80
Top = 120 , Left = 11 , Caption = "1" , TabIndex = 2 , Name = "cmd1"
ปมเลข 2 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 120 , Left = 47 , Caption = "2" , TabIndex = 3 , Name = "cmd2"
ปมเลข 3 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 120 , Left = 83 , Caption = "3" , TabIndex = 4 , Name = "cmd3"
ปมเลข 4 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 84 , Left = 11 , Caption = "4" , TabIndex = 5 , Name = "cmd4"
ปมเลข 5 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 84 , Left = 47 , Caption = "5" , TabIndex = 6 , Name = "cmd5"
ปมเลข 6 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 84 , Left = 83 , Caption = "6" , TabIndex = 7 , Name = "cmd6"
ปมเลข 7 ทำาการคลกท ปม calnumber ใน form control จาก
81
นนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 48 , Left = 11 , Caption = "7" , TabIndex = 8 , Name = "cmd7"
ปมเลข 8 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 48 , Left = 47 , Caption = "8" , TabIndex = 9 , Name = "cmd8"
ปมเลข 9 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 48 , Left = 83 , Caption = "9" , TabIndex = 10 , Name = "cmd9"
ปมเลข 0 ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 155 , Left = 11 , Caption = "0" , TabIndex = 11 , Name = "cmd0"
ปม . (จดทศนยม) ทำาการคลกท ปม calnumber ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 155 , Left = 47 , Caption = "." , TabIndex = 12 , Name = "cmddecimal"
ปม + (บวก) ทำาการคลกท ปม calsign ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 155 , Left = 83 , Caption = "+" , TabIndex =
82
13 , Name = "calplus"
ปม - (ลบ) ทำาการคลกท ปม calsign ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 155 , Left = 119 , Caption = "-" , TabIndex = 14 , Name = "calminus"
ปม * (คณ) ทำาการคลกท ปม calsign ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 120 , Left = 119 , Caption = "*" , TabIndex = 15 , Name = "calmult"
ปม / (หาร) ทำาการคลกท ปม calsign ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 84 , Left = 119 , Caption = "/" , TabIndex = 16 , Name = "caldiv"
ปม AC ทำาการคลกท ปม calac ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 48 , Left = 119 , Caption = "AC" , TabIndex = 17 , Name = "calac10"
ทำาหนาจอแสดงผลลพธ ทำาการคลกท ปม caltext ใน form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 12 , Left = 12 , Height = 24 , Width = 119 , TabIndex = 0 , Name = "caltext"
ทำาหนาจอแสดงเครองหมายคำานวณ ทำาการคลกท ปม caltext ใน
83
form control จากนนกทำาการคลก ท container calculator แลวทำาการกำาหนด properties Top = 12 , Left = 130 , TabIndex = 0 , Name = "calmath"
เอาละมาถงตรงนคณกทำาการบนทกสงทคณไดทำามาทงหมดไดเลย คณไดทำา Visual Class Library ของ Calculator เสรจเรยบรอยแลว ตอไปกใหคณทำาการสราง ฟอรมขนมาทดสอบวาไดผลเปนอยางไรใหทำาการสรางฟอรมโดยปอนคำาสง create form calcform ท command window แลว Enter เมอเขาส form designer เรยบรอยแลว ใหไปท form control เลอก แลวเลอก Add ใหเลอกชอไฟล CALCULATOR.VCX เพอทจะนำาเอา Visual Class ทเราสรางไวมาใชงาน จากนนเรากจะไดเหนคอนโทรลคลาสทเราไดสรางไวใหทำาการคลกท calculator container แลวกลบมาคลกทฟอรมอกครงเทานเครองคดเลขกจะปรากฎขนมาคณกทำาการ save แลวปอนคำาสง do form calcform ท command window เพอสงใหฟอรมทำางาน ถงตอนนกเชญกดตามสบายวธสรางทลบาร(Toolbar) และนำาไปใชงานDOWNLOAD ตวอยางโปรแกรมทลบาร การสรางโปรแกรมแลวมทลบารอยในโปรแกรมนนๆดวยจะทำาใหโปรแกรมของคณดดขนมาอกมากเลย ยงถาเปดฟอรมแลวม ทลบารของฟอรมนนๆตดสอยหอยตามออกมาดวยกยงดไปใหญใชหรอไมครบ การทเราจะทำาการสราง ทลบารขนมาสกอนหนงมนไมไดยากเยนเขนใจอะไรหรอกครบเพราะใน Visual Class ทเราเคยทำาการสรางมากอนหนานกจะมคลาสในสวนของ toolbar เตรยมไวใหเราอยแลว ทนเราลองมาทำาการสรางกนเลยดกวาขนแรกคณตองการการสราง Visual Class Library ทเปน toolbar ขนมากอนดงน
84
ใหคณทำาการเรยก คำาสง DO (_BROWSE) ท command window แลวปอนชอไฟลวา MyToolbarกดปม เพอสรางคลาสใหม ในชอง Class Name ใหตงชอวา toolbar1ชอง Based On เลอก Toolbar กดปม OKคณจะไดพบกบ Class Designer ซงจะมลกษณะเหมอนกบ Form Designer ใหคณคลกขวาเพอเขาไปกำาหนด properties ของ toolbar1 แลวกำาหนด properties ดงนCaption ใหทำาการลบออกใหหมด (หามใช Spacebar ลบออก)ControlBox = .F.ทำาการปอนคำาสง ตอไปนลงในสวนของ Init EventThis.Dock(0)
คำาสง dock เปนการกำาหนดตำาแหนงของ toolbar วาจะใหอย ณ. จดใดของ Main Visual FoxPro Window มรปแบบดงน ToolBar.Dock [nLocation [, X, Y]]nLoction เปนการกำาหนดจดของ toolbar คาของ nLocation มดงนคอ -1 ยกเลกการกำาหนด 0 กำาหนดใหอยสวนบนของ Main Visual FoxPro Window 1 กำาหนดใหอยดานซายของ Main Visual FoxPro Window 2 กำาหนดใหอยดานขวาของ Main Visual FoxPro Window 3 กำาหนดใหอยสวนลางของ Main Visual FoxPro Window X,Y กำาหนดตำาแหนงของ toolbar ตามแนวตง แลวแนวนอน
85
จากนนใหคณเลอก คอนโทรล Command button จาก Form Control โดยทำาการคลก 1 ครง แลวกลบมาคลกท toobar1 คณกจะไดเปน command button หนงตวอยใน toobar1 ใหคณทำาสก 4 ตว หรอคณจะใช Command Group กไดแลวแตสะดวกใหกำาหนด properties ของ command button แตละตวดงนตวแรกCaption = |<Name = cmdTopClick Event พมพคำาสงดงนGO TOPTHIS.Enabled = .F.THIS.Parent.cmdPrior.Enabled = .T.THIS.Parent.cmdBottom.Enabled = .T.THIS.Parent.cmdNext.Enabled = .T.THISFORMSET.RefreshตวทสองCaption = <Name = cmdPriorClick Event พมพคำาสงดงนSKIP -1IF BOF() GO TOP THIS.Enabled = .F. THIS.Parent.cmdTop.Enabled = .F.ELSE THIS.Parent.SetAll("Enabled", .T. , "Commandbutton")ENDIFTHISFORMSET.RefreshตวทสามCaption = >Name = cmdNextClick Event พมพคำาสงดงนSKIP
86
IF EOF() GO BOTTOM THIS.Enabled = .F. THIS.Parent.cmdBottom.Enabled = .F.ELSE THIS.Parent.SetAll("Enabled", .T. , "Commandbutton")ENDIFTHISFORMSET.RefreshตวทสCaption = >|Name = cmdTopClick Event พมพคำาสงดงนGO BOTTOMTHIS.Enabled = .F.THIS.Parent.cmdTop.Enabled = .T.THIS.Parent.cmdPrior.Enabled = .T.THIS.Parent.cmdNext.Enabled = .F.THISFORMSET.Refreshเมอทำาเสรจ คลาสทลบารทคณสรางขนมากจะมรปรางหนาตาดงน ใหทำาการ Save เกบไว
มาถงตอนนกเปนการนำา ทลบารทสรางไวไปใชงานในฟอรม ใหทำาการสราง ฟอรมขนมา โดยพมพคำาสง CREATE FORM CUSTFORM ท command windowใหทำาการ คลกขวาท CUSTFORM เลอก Data Environment ทำาการคลกขวาท data environment แลวเลอก Addจากนนใหคลกทปม Other ของหนาตาง Add Table or View ทำาการ double click ท Samples ตอมาใหทำาการ double click ท data แลวทำาการ double click ทตาราง CUSTOMER.DBF ใหทำาการคลกทฟลด cust_id แลวลากไปวางไวทฟอรม
87
CUSTFORM ใหทำาการคลกทฟลด company แลวลากไปวางไวทฟอรม CUSTFORM ใหทำาการคลกทฟลด contact แลวลากไปวางไวทฟอรม CUSTFORM ถาตองการอกกทำาการลากแลววางตามชอบใจจากนนใหไปท form control เลอกปม command button นำามาใสไวใน CUSTFORM แลวกำาหนด Caption = ExitClick Event พมพคำาสง THISFORM.Releaseใหไปท form control เลอก แลวเลอก Add ใหเลอกชอไฟล myToolbar.VCX เพอทจะนำาเอา Visual Class ทเราสรางไวมาใชงาน จากนนเรากจะไดเหนคอนโทรลคลาสทเราไดสรางไวใหทำาการคลกท toolbar1 แลวกลบมาคลกทฟอรมอกครงเทานคณกจะไดปม toolbar มาอยท ฟอรมของคณทำาการ save ฟอรม แลวปอนคำาสง do form custformเปนอยางไรบางครบ การทำา Visual Class Library นนไมไดยากอะไรเลยใชไหมครบ สำาหรบบทนกเอาไวเทานกแลวกน หมนฝกฝนมากๆ แลวคณกจะชำานาญยงๆขน แถมยงได class เพมขนเอาไวอำานวยความสะดวกในการสรางฟอรมอกตางหากEvent , Methods และ Properties อเวนต (Events)เกรนนำา...ในการเขยนโปรแกรมเชงวตถ(Object Oriented Program) สงทจำาเปนอยางยงทจะตองรกคอการทำางานของ event ตางๆทเกดขนกบ object นนๆ ยงถาทานเคยทำาการเขยนโปรแกรมแบบโครงสรางมากอนแลว พอมาเจอกบ event งงเปนไกตาแตก บางทานถงกบเลกทจะเรยนรไปเลย ผมกเปนคนหนงในจำานวนนนเหมอนกน แตชวตนยงมหวงเลยไปรายการฝนทเปนจรง คณไตรภพใหรถเขนขายกวยเตยวมาคนหนง กเลยคดไดตงหนาตง
88
ตากลบมาศกษาใหมหมด เลยไดสจจะธรรมของเหตการณ(event) ตางๆใน Visual FoxPro วาระหวางทเราทำางานกบวตถหนงๆมนเกดเหตการณขนมากบ วตถนนหลายอยางดวยกน แตพอเกดแลวเราไมรสกวามนเกดอะไรขนหรอกเพราะเนองจากเรายงไมไดทำาการนำามนไปใชงาน แตกอนทคณจะนำามนไปใชงานนนคณตองทำาความเขาใจกบลำาดบการทำางานของ event ตางๆกนกอนวาไกกบไขอะไรเกดกอน ใหคณทำาการ download ฟอรม EVENTEST แลวลองทำาการรนฟอรมขนมาด คณไดเหนลำาดบของการทำางานของ event ทเกดขนกบฟอรมนตงแต load ฟอรม จนถง unload ฟอรมเปน event สดทายทเกดขนใหคณทำาการ เรยกฟอรมโดยใชคำาสง DO FORM EVENTEST NAME FORMOBJ
event Load จะเกดเปนอนดบแรก เมอเราทำาการเรยกฟอรมขนมาใชงานevent Init จะเกดเปนอนดบถดมา event นจะเกดกบ object ทกๆ object สวนใหญจะใชในการกำาหนดคาเรมตนตางๆของ object หรอกำาหนดใหทำางานอยางใดอยางหนงซงจะทำาเพยงครงเดยวเมอเรยกฟอรมนนมาใชงานevent Activate จะเกดเมอฟอรมนแสดงขนมา หรอเมอฟอรม
89
นนถกกระทำา ใหคณลองคลกเมาสไปท command window แลวกลบมาคลกท ฟอรม eventest อกครง event นกจะทำางาน หรอถาคณพมพคำาสง FORMOBJ.HIDE ท command windows เพอทำาการซอนฟอรม แลวใชคำาสง FORMOBJ.SHOW เพอทำาการแสดงฟอรม event นกจะทำางานเหมอนกนevent When จะเกดขนกบ object ท cursor นนจะไปปรากฏอยซงตอนน event When จะอยท object Text1 (ถาเพงทำาการรนฟอรมขนมา) สวนใหญเราจะใช event นในการเชควาจะใหสามารถเขามาท object นไดหรอไม ใหคณลองเขาไปแกไขฟอรม EVENTEST แลวเขาไปท object text2 เขยนคำาสงใน event When ดงน RETURN !EMPTY(THIS.PARENT.TEXT1.VALUE)คำาสงขางตนเปนการเชควาถา object text1 มขอมลถงเขามาทำางานท object text2 ไดevent GotFocus จะเกดเมอเราทำาการ focus ไปท objcet นนสงเกตใหดวา event นจะเกดหลงจาก event When ถาผานจาก event When มาไดถงจะมาทำางานท GotFocus คำาสงประเภท focus นมประโยชนมาใน Visual FoxPro ตอๆไปคณจะไดใชมนอยางแนนนอน event KeyPress จะเกดขนเมอคณทำาการกดคยใดๆกตามบน keyboard คณไดพบกบการใชไปแลวในการสรางเครองคดเลขevent InteractiveChange จะเกดขนเมอ object นนๆเกดการเปลยนแปลงevent Valid event นสวนใหญจะใชในการตรวจสอบขอมลของ object นนวาปอนขอมลถกตองหรอไม ใหคณลองเขาไปแกไขฟอรม EVENTEST แลวเขาไปท object text1 เขยนคำาสงใน event Valid ดงน
90
RETURN !EMPTY(THIS.PARENT.TEXT1.VALUE)คำาสงขางตนเปนการเชควาถา object text1 ไมไดมการปอนขอมลกไมสามารถออกจาก object นไดevent LostFocus จะเกดขนเมอเราจะทำาการละออกจาก object นนๆ วธการใชงานจะอธบายตออกทในตอนหนา event Click จะเกดขนเมอเราทำาการคลกเมาส 1 ครง หรอกดปม enter ท object นนๆ event นคณกเคยเหนบอยๆevent DoubleClick จะเกดขนเมอเราทำาการ double click เมาส 2 ครงเมอเราทำาการออกจากฟอรม(ปดฟอรม) จะเกด event อะไรขนบางevent Destroy จะเกดกบ object ทกๆ object กอน ซงสวนใหญเราจะใชในการ clear คาตางๆทเกดขน event Unload จะเกดเปนตอนสดทาย หรอทายสด ACTIVATE SCREEN เปนคำาสงทใหทำาการแสดงผลบน Main Visual FoxPro Windowเปนอยางไรบางครบสำาหรบ event พนฐานทเราควรร ซง event ทผมากลาวมานเปนเพยงสวนหนงเทานน สวน event อนๆ อกมากมายจะเกดขนมาไดอยางไรนน เราตองยอนกลบไปด ท control class ของแตละตว ซงแตละตวนนจะม event แตกตางกนออกไป ถาผมจะนำามากลาวทงหมดกจนปญญา เพราะผมเองกยงรไมหมดเหมอนกน ตวใหนทถกเรยกใชงานผมพยายามอธบายรายละเอยดอกทกแลวกน
คณเคยสงสยบางหรอไมวาเวลาตอนคณเรยก event ขนมาเพอจะทำาการเขยนโปรแกรมเขาไปนน บาง event กม พารามเตอร(Parameter) โผลออกมาดวย บางอนกผลบหายเขาไปไมมขนมา ผมบอกไดคำาเดยววาคณควรจะตองรไวบางวา คาทแตละ event สงผานมาใหนนสงคาอะไรมาใหเรา
91
เชน เราเรยก Keypress Event ขนมา กจะปรากฎพารามเตอรสงผานคามาใหดงน LPARAMETERS nKeyCode, nShiftAltCtrlเรมจาก สญลกษณ n ตวเลกขางหนาตวแปรกอน หมายถงคาทสงมาเปนแบบ ตวเลข (numeric) สญลกษณ a หมายถงคาทสงมาเปน อะเรย (array) สญลกษณ c หมายถงคาทสงมาเปน ตวอกษร (charecter) สญลกษณ l หมายถงคาทสงมาเปน ตรรกะ .T. , .F. (logical) สญลกษณ d หมายถงคาทสงมาเปน วนท (date) สญลกษณ f หมายถงคาทสงมาเปน ตวเลข float สญลกษณ o หมายถงคาทสงมาเปน ออปเจก (object) สญลกษณ t หมายถงคาทสงมาเปน วนเวลา (datetime) สญลกษณ y หมายถงคาทสงมาเปน เคเรนซ (currency) สญลกษณ u หมายถงคาทสงมาเปน unknowสญลกษณทผมกลาวมาทงหมดน ครอบคมไปถงตวแปรตางๆของ Visual FoxPro ทแสดงออกมา nKeyCode หมายถง คาของปมทเราไดทำาการกด เชน กดปม a (เลก) จะไดคา 97 คาพวกนไดมาจากไหน เปนคาในตาราง ANSI Code เราสามารถแปลงคาตวเลขนกลบมาเปนตวอกษรไดโดยใชฟงกชน CHR(nKeyCode) nShiftAltCtrl หมายถง คาทสงออกมาเมอเรากดปม Shift, Ctrl หรอ Alt จะไดคา 1,2 และ 4 ตามลำาดบ ถาไมไดกดสามปมดงกลาวจะไดคา 0 ในกรณทเรากดปม Alt กบ Ctrl จะไดคาอะไร คณกนำาคาทมนมมาบวกกน 2+4=6 หรอ ActivateCell Event ใน คอนโทรกรด (grid control) สงผานคา nRow,nCol คอลำาดบของ แถวใน และคอลมน ใน grid ณ.ตำาแหนงของ cursor อย เปนตน
92
สวนทเหลอคณจะไดพบกบมนอก แนนอน เนองจากอธบายตอนนกไมหมดเยอะจรงๆ เทานกอนเพอเปนแนวทางในการศกษาตอไปเมธอต (Methods)ในแตละ object นนจะมเมธอตใหเราทำาการเรยกใช หรอให object ทำาตามคำาสงทเราสงใหทำา ถาคณสงเกตใหดๆ คณกจะทราบวา เมธอตกคอคำาสงธรรมดาคำาสงหนงเทานนเองซงกเหมอนกบคำาสงทวๆไป เพยงแต เมธอตสวนใหญจะกระทำากบ object เชนCircle Method เปนคำาสงใชวาดรปวงกลม เชน _SCREEN.Circle(100,100,100) รปแบบคำาสง Object.Circle (nRadius, nXCoord, nYCoord [, nAspect])CloneObject Method เปนคำาสงทใชสำาเนา object ซงจะทำาการสำาเนาทง properites,event และ method ไปดวย รปแบบคำาสง Object.CloneObject(NewName)Refresh Method เปนคำาสงทเราใชใหทำาการแสดงใหม เพอทำาการแสดงคาใหมทเกดขน คำาสงนเราใชบอยมาก รปแบบคำาสง [[FormSet.]Object.]Refresh Object.RefreshRequery Method เปนคำาสงทใชใหทำาการเรยกใชงาน SQL อกครงใชกบคอนโทร ComboBox และ ListBox ซงเราจะใชในกรณทตองการใหแสดงขอมลใหมเพอทำาการ update ขอมลเขามาใน ComboBox หรอ ListBox (เมธอตนกใชบอย) รปแบบคำาสง Control.RequeryRelease Method เปนคำาสงทใหทำาการลาง ฟอรม, ฟอรมเซตออกจากหนวยความจำา หรอกคอการทำาใหออกจากฟอรมนนเอง เราจะใชกบทกๆฟอรมเสมอ รปแบบคำาสง Object.ReleaseShow Method เปนคำาสงใหทำาการแสดง ฟอรม, ฟอรมเซต, ทลบาร ขนมา
93
รปแบบคำาสง [FormSet.]Object.Show([nStyle])สำาหรบในสวนของเมธอตของ Visual FoxPro เอาเทานกอน กแลว
ในบางครงเมอคณตองการใชงาน methods แตใน object นนไมมใหคณจะทำาอยางไร? คณตองทำาการสราง เมธอต (methods) ขนมาในบททแลวคณไดเหนการสราง method m_keypress ในการทำาเครองคดเลขมาบางแลวทนผมจะนำามาอธบายในรายละเอยดอกครง เกยวกบวธการสราง วธการใชงานซงเราสามารถนำามนไปใชงานไดอยางไรบาง และรปแบบการสราง การสงผานคา การสรางนนกมวธการงายๆ แตควรคำานงถงดวยวาเราจะสรางเมอไหร และจะตองอยท object ในตวไหน เพอทจะใหการทำางานเกดประสทธภาพสงสด 1. ถากรณทำาการสรางฟอรม ใหทำาการคลกทเมน Form หรอ ถากำาลงทำาการสราง Visual Class Library อยใหคลกทเมน Class 2. เลอก New Method 3. จากนนใหพมพชอ Method ทตองการจะสราง ในชอง Name คณสามารถใสหมายเหตตางๆไดโดยใสไวในชอง Description
94
เมอคณทำาการสรางเสรจแลวคณสามารถเขาไปเขยนคำาสงในเมธอตซงจะเกบอยในสวนของ properties ในหวขอ methodsการเขยนโคดคำาสง ของ เมธอตนนจะเหมอนกบการเขยน ฟงกชน การใชงานกจะคลายกบการเรยกใชฟงกชนอกเหมอนกน เมอคณจะทำาการเรยกใชงาน เมธอตนนมรปแบบการเรยกใชงานดงน objcetName.MethodNameหรอ ถาคณตองการสงผานคาใหกบเมธอตแลวใหทำาการสงคากลบมายงตวแปรกทำาการเรยกใชงานดงน cVarible = ObjectName.MethodName(cParameter,nParameter..)หรอ เรยกใชงานแบบนกได = ObjectName.MethodNameมาถงตรงนในสวนของกาสรางและการเรยกใช เมธอตคงพอจะไดอะไรบางไมมากกนอย จรงๆถาคณเคยใชงาน FoxPro รนเกาหรอใหม เมธอตมนกเหมอนกบ โพซเยอรยอยๆ(Procedure) นนเองคณสมบต (Properties)Properties เปนการกำาหนดคณสมบตใหกบวตถนนๆ ตวอยางงายๆเลยทคณทำาการกำาหนดกคอการกำาหนดประเภทของฟอนต ขนาดของฟอนต หรอกำาหนดใหวตถนนสามารถทำาอะไรบางอยางเชน สามารถเคลอนยายได หรอเปลยนขนาดกตาม ซงการกำาหนดคณสมบตใดๆไดนนมนจะขนอยกบคอนโทรลทคณนำามาทำาเปน object วาจะเปดโอกาศใหมากแคไหน ผมจะขอยกตวอยาง properties บางตวใหดกอนกแลวกนAlwaysOnTop เปนการสงใหแสดงฟอรมนนอยบน windows เสมอ รปแบบคำาสง Object.AlwaysOnTop[ = lExpr]AutoCenter เปนการสงใหแสดงฟอรมนนอยตรงกลาง windows รปแบบคำาสง Object.AutoCenter [ = lExpr]
95
Closeable เปนการกำาหนดใหแสดงปม ปดฟอรมหรอไม รปแบบคำาสง Object.Closable[ = lExpr]WindowState กำาหนดขนาดของฟอรมตอนเรมตนใหมขนาด 0 ปรกต, 1 ขยายใหญ, 2 ยอเลก รปแบบคำาสง [Object.]WindowState[ = nState]WindowType กำาหนดลกษณะของการเปดฟอรม ถาเปน 0 สามารถทจะเปดฟอรมตอไปได , 1 จะตองปดฟอรมปจจบนกอนถงจะทำาการเปดฟอรมใหมได รปแบบคำาสง Object.WindowType[ = nType]เปนตนคณสามารถกำาหนดคณสมบตของ object ทงหมดพรอมๆกนไดโดยใชคำาสง SetAllรแบบคำาสง Container.SetAll(cProperty, Value [, cClass])เชน myForm.myOptionGroup.SetAll("Enabled",.F.)
คณเคยสงสยบางหรอไมในบางครงเราตองการใชงานตวแปรซกตวบนฟอรม หรอใน object ตวอนๆ เชน เราอยากไดตวแปรสกตวทเปนตวเลข หรอเปนแบบตรรกะ เปนวนท เราจะทำาอยางไร ในเรองของ properties น Visual FoxPro กเปดโอกาสใหเราสามารถสราง properties ของเราขนมาเองได ซงสวนใหญทผมสรางขนมาจะเปนในลกษณะของตวแปรเสยมากกวา ถาใครเคยนำาไปทำาอยางอนไดกรณาชวยบอกดวยกแลวกน ในบททแลวมาเรองการสรางเครองคดเลข คณจะไดเหนการสราง properties ขนมาบางแลว ซงวธการมดงนคอ1. ถากรณทำาการสรางฟอรม ใหทำาการคลกทเมน Form หรอ ถากำาลงทำาการสราง Visual Class Library อยใหคลกทเมน Class
96
2. เลอก New Property 3. จากนนใหพมพชอ property ทตองการจะสราง ในชอง Name คณสามารถใสหมายเหตตางๆไดโดยใสไวในชอง Description
คณสามารถดตวอยางการใชงาน properties ทสรางขนมาใหมไดจาก เรองของการสราง เครองคดเลข เชนทผมทำาการสรางไวนนจะอยในสวนของ คลาส container calculator ซงกไดแก r_lnewvalue = .T. r_ncaltxt = 0 r_coldmath = "+"หรอ author = "Program by Kasem K." เปนตนเปนอยางไรบางครบ เรยนรมาจนถง ณ. ขณะน ถงคณยงเขยนฟอรมปอนขอมลยงไมเปนกอยาเพงทอนะครบ ทผมอธบายมาหลายบทหลายตอน เปนเพยงแคปถนน เพอเปนทางกาวเดนไปดวยความเขาใจตางหาก ตอนหนาจะเปนการสรางระบบงานแลวครบ งายๆแตไดใจความ โปรแกรมหลก(Main Program)สำาหรบโปรแกรมหลกทผมจะนำาเสนอนเปนเพยงแนวทางหนงในหลายๆแนวทาง คณอาจประยกตไปเปนอยางอนกได ใน Visual FoxPro ไดจดเตรยมเครองมอไวสำาหรบใหเราสรางระบบงานใหเราซงกคอ โปรแกรม Project Manager หลายๆทานคงคนกบมนด เพราะเมอเรา ตดตงระบบแลวทำาการเรยกโปรแกรม
97
Visual FoxPro เปนครงแรกโปรแกรมตวนกจะโผลออกมา แตตอนนผมจะใหคณทำาการสรางมนใหม และเพอใหการเรยนรและการสรางเปนไปในแนวทางเดยวกน ใหคณทำาการสราง sub-directory ขนมาเกบระบบงานของเรากอนโดยพมพคำาสงท command window ดงน! MD C:\MYAPP SET DEFAULT TO C:\MYAPPCREATE PROJECT MyProject ตอนนเรามาทำาความรจกกบลษณะทวๆไปของ main Visual FoxPro window กนกอน การอางถง main windows นนเราจะใชคำาสง _SCREEN ซงคณกเคยเหนมาบางแลว ผมจะขอยกตวอยางใหลองทำาตามโดยปอนคำาสงท commnd window ดงน_SCREEN.Caption = 'โปรแกรมของฉน' && เปนการเปลยนขอความไตเตล_SCREEN.Backcolor = rgb(192,192,192) && เปลยนสฉากหลงเปนสเทา_SCREEN.Controlbox = .F. && ไมแสดง control box ทงหมด_SCREEN.Controlbox = .T._SCREEN.Closeable = .F. && ปดปม close box_SCREEN.MaxButton = .F. && ปดปมขยาย windows_SCREEN.MinButton = .F. && ปดปมยอ windows_SCREEN.Height = SYSMETRIC(2) && เปนการกำาหนดความสงของ Main Visual FoxPro Window สวนฟงกชน SYSMETRIC(2) จะเปนการสงคาความสงของ จอภาพทไดทำาการ set ไวในโปรแกรม Windows ถาคณ set จอภาพเปน 640 x 480 คาทสงมากจะเปน 480 เปนตน หรองายๆกเปนการกำาหนดขนาดใหสงเตมหนา โปรแกรม Windows ไมวาจะทำาการ set ความละเอยดเปนเทาไหรกตาม
98
_SCREEN.Width = SYSMETRIC(1) && เปนการกำาหนดความกวางของ Main Visual FoxPro Windows_SCREEN.Visible = .F. && เปนคำาสงใหทำาการซอน Main Visual FoxPro Window*หมายเหต ถาคำาสงไหนเปน .F. ถาเปลยนเปน .T. กจะเปนการทำางานตรงกนขามคณไดทราบถงคำาสงในการควบคม Main Visual FoxPro Window บางพอสมควร แตมอกสงหนงทจะอธบายใหทราบเปนเรองเกยวกบการกำาหนดสภาพแวดลอม (environment) ของ Visual FoxPro ซงผมคดวาทานทงหลายควรอยางยงทจะตองรไว ซงแฟมขอมลทจะกำาหนดสภาพแวดลอมของ Visual FoxPro กคอ แฟม CONFIG.FPW การสรางแฟมนคณสามารถสรางไดโดยใช text editor ใดๆกได หรอใช คำาสง modify command ถงตอนนเรามาดกนกอนวาเราจะทำาอะไรกบแฟม CONFIG.FPW ไดบางเชนการทเราจดการกบ Main Visual FoxPro Window โดยใชคำาสง _SCREEN นนเราตองทำาในขณะอยใน Main Visual FoxPro Windows แตถาเราตองการทำาในขณะทเรยกโปรแกรมเรากตองใช แฟม CONFIG.FPW เขาชวย หรอถาเราตองการ SET คาตางๆ เปนตน เรามาดกนวา CONFIG.FPW นนทำาอะไรไดบาง ใหทำาการพมพคำาสง modify commmand CONFIG.FPWพมพคำาสงตามนTITLE = โปรแกรมของฉน && กำาหนด title DEFAULT = C:\MYAPP && กำาหนด default directoryDATE = ANSI && กำาหนดรปแบบวนทเปนแบบ yy.mm.ddCENTURY = ON && กำาหนด ปเปน 4 หลก yyyy
99
ESCAPE = OFF && ยกเลกการใช ปม Esc DELETE = ON && กำาหนดไมใหแสดงเรคคอรดทถกลบไปแลวHELP = OFF && ยกเลก helpTALK = OFF && ไมใหแสดงผลขณะทำางานTMPFILE = C:\TEMP && กำาหนด directory ของ tempolary file (คณตองสราง directory TEMP ขนมาเองดวย)COMMAND = DO ใสชอโปรแกรม && ใหทำาการเรยกโปรแกรมขนมาทำางานเลย คณสามารถใชคำาสง _STARTUP แทนคำาสง COMMAND กไดเคลดไมลบ ถาคณไมตองการให Main Visual FoxPro Window ปรากฏขนมาขณะทำาการเรยก Application ของคณใหใสคำาสง SCREEN = OFF ใน CONFIG.FPWการกำาหนดสภาพแวดลอมของ Visual FoxPro นนเราสามารถทจะทำาใหโปรแกรมเราทำางานไดดขนและเรวขน เมอคณไดทำาการสราง แฟม CONFIG.FPW เรยบรอยแลวคณตองนำามนไปใสไวใน Project Manager ทเราไดสรางเตรยมไว คอ MyProject โดยทำาดงน1. ท Project Manager ให คลกท Other2. ใหเลอก Text File แลวคลกปม Add3. ใหพมพไฟล CONFIG.FPW ท Select file แลว คลกปม OK เราสามารถเรยก config ไฟลจากทอนไดหรอไม แลวสามารถสรางเปนชออนไดดวยหรอไม ?ถาเราจะทำาการเรยกไฟล config จากทอน แลวเปนชออนดวยเราสามารถทำาได โดยใช พารามเตอร(parameter) -cเชน เราไดทำาการสรางระบบงานของเราแลว build เปน .exe ชอวา myproject.exe เวลาเรยกใชใหพมพดงน
100
MYPROJECT.EXE -CC:\MYAPP\MyConfig.FPWหรอถาเรยกจาก Visual FoxPro กได โดยพมพ VFP.EXE -CC:\MYAPP\MyConfig.FPWการสรางเมนโปรแกรมในระบบงานหนงๆ จะตองมโปรแกรมตวหนงเปนตวหลกทจะนำาผใชผานไปสสวนตางๆของโปรแกรมซงกคอ เมนโปรแกรม(main program) การสรางเมนโปรแกรมนนกแลวแตทานจะสรางไมไดมกฏเกณฑอะไรตายตว แตผมจะขอแนะนำาเพอเปนแนวทางในการสรางตอๆไป กอนอนเรามาดความตองการของเรากอนวาจะใหโปรแกรมเปนไปอยางไร (มนขนอยทความอยากของแตละบคคล)นเปนความตองการสวนตว หามลอกเลยนใหกอปป ไปเลยแลวกน1. ตองการใหแสดง โลโกขณะทำาการเปดระบบงาน (แสดงยหอวางนเหอะ)2. จากนนใหผใชปอนรหสผานเพอเขาสโปรแกรม (มใหผประสงคดเขามาทำางาน)3. เรยกเมนขนมา แลวแสดงโลโก ดวยระบบงานแตละระบบงานนนจะตองมคำาสง READ EVENTS อยดวยเสมอ ซงสวนใหญเราจะเอาไวทเมนโปรแกรม คณคงสงสยวาใสไวทำาไม ถาคณเคยลอง build application เปน .EXE โดยไมใสคำาสง READ EVENTS แลวลองเรยกโปรแกรมดถาเปนมอใหม รอยละรอยหาสบขนมาแวบเดยวแลวกหายไปเหมอนสายลม ใน help ของ Visual FoxPro บอกไววาเปนการ start event processing ในความคดของผมนนมนกเปนคำาสงใหรอรบคาจากผใชงานเหมอนเปน ลปไมรจบ จนกวาเราจะใชคำาสงยกเลก ซงคำาสงทใชในการยกเลก READ EVENTS กคอ CLEAR EVENTS หลงจากทเราทำาการใชคำาสงนแลวโปรแกรมกจะหลดจาก READ EVENTS มาทำางานในบรรทดตอมา สวนใหญเราจะใสคำาสง READ
101
EVENTS ไวท main program แลวใสคำาสง CLEAR EVENT ไวทเมน ททำาการ ออกจากโปรแกรม (quit) คณสามารถใช READ EVENTS กครงกได แตกอนใชกควรจะ CLEAR EVENT ของเกากอน เรามาดตวอยางการใชกนกอน 1.ใหทำาการ คลกท Code ใน Project Manager 2.ตอมาใหคลกขวาท Programs เลอก รายการ New แลวทำาการปอนคำาสงดงนSET PROCEDURE TO UTILITYON SHUTDOWN DO SHUT_DOWNON ERROR DO errhand WITH ;ERROR( ), MESSAGE( ), MESSAGE(1),;PROGRAM( ), LINENO( )SET CURSOR OFFDO FORM License NAME LicenseINKEY(5) SET CURSOR ONDO StartupLicense.ReleaseDO FORM Login READ EVENTDO Cleanup*** End of Program *** 3. ทำาการ save โปรแกรม โดยการคลกท เมน File เลอก Save As ใสชอ โปรแกรมวา MAINคณกไดทำาความรจกกบคำาสง READ EVENTS และ CLEAR EVENTS ไปบางแลว ยงมคำาสงทผมจะขอกลาวถงอก 2 คำาสง เปนคำาสงทควบคมการเกดขอผดผลาดของโปรแกรม ซงในการเขยนโปรแกรมนนบางครงสงทเราคาดไมถงกสามารถเกดขนได เรากควรจะทำาการควบคมการเกดขอผดพลาดเหลานนเสยกอนทมนจะเกดขน เมอมนเกดขนแลวใหมนแสดงขอผดพลาดขนมาแจงใหเราทราบ เราจะไดหาทางแกไขขอผดพลาดเหลานนอกทคำา สงทจะกลาวถงกคอ
102
คำาสง ON ERROR รปแบบคำาสง ON ERROR [Command]เมอเกด ขอผดพลาดแลวใหทำาตามคำาสงทตองการ เชนON ERROR DO errhand WITH ERROR( ), MESSAGE( ), MESSAGE(1),PROGRAM( ), LINENO( )สวนโปรแกรม errhand นนใหทำาการสรางโปรแกรมชอวา utility เพอทำาการเกบ โพซเยอร(procedure) errhand โดยทำาการสรางดงน 1.ใหทำาการ คลกท Code ใน Project Manager 2.ตอมาใหคลกขวาท Programs เลอกรายการ New แลวทำาการปอนคำาสงดงน******************************************************************** Procedure OnError *******************************************************************PROCEDURE errhandPARAMETER merror, mess, mess1, mprog, mlinenoON SHUTDOWNmessagebox('หมายเลขขอผดพลาด: ' + LTRIM(STR(merror)) + CHR(13) + ;'ขอผดพลาด: ' + mess + CHR(13) + ;'บรรทดขอผดพลาด: ' + mess1 + CHR(13) + ;'บรรทดทผดพลาด: ' + LTRIM(STR(mlineno)) + CHR(13) + ;'โปรแกรม: ' + mprog + CHR(13) + ;'Please contact your Vendor '+ CHR(13) + ;'ถาคณเปด Visual FoxPro อยกอนแลวใหปดแลวเรยกโปรแกรมอกครง' , 288,"")QUITENDPROC
103
3. ทำาการ save โปรแกรม โดยการคลกท เมน File เลอก Save As ใสชอ โปรแกรมวา UTILITYคำาสง ON SHUTDOWN รปแบบคำาสง ON ERROR [Command]เปคำาสงเมอเราทำาการคลกทปม close box แลวใหทำาตามคำาสงทตองการ เชนON SHUTDOWN DO SHUT_DOWNโพซเยอร SHUT_DOWN กใหทำาการสรางเกบไวท โปรแกรม UTILITY เหมอนกนโดยพมพคำาสงดงน ******************************************************************** Procedure ShutDown *******************************************************************PROCEDURE Shut_DownLOCAL nAnswernAnswer = messagebox("ตองการออกจากโปรแกรม",292,"")IF nAnswer = 6 QUITENDIF ENDPROCสำาสรบสงตางๆในโปรแกรมหลกทจะตองมนนขนอยกบทานวาจะเขยนโปรแกรมพศดาลพรรลกขนาดไหน แตอยางนอยควรจะมตามสงทผมไดกลาวไวขางตน เมน (MENU)ผใชงานสามารถเขาถงงานตางในระบบงานทเราทำาการสรางไดกโดยการเลอกรายการจากเมน ฉะนนการทำาเมนกมความสำาคญไมยงหยอนไปกวาการสรางโปรแกรมประเภทอน เพราะระบบงานของเราจะใชงานไดสะดวกหรอไม กขนอยทเราทำาการออกแบบและสรางเมนขนมา
104
Visual FoxPro ไดจดทำาเครองมอในการสรางเมนมาใหเราเรยบรอยแลว ถาเปนเมอกอนคณตองมาการการเขยนโปรแกรมคำาสงกนเอง วธการสรางเมน ท Project Manager ใหเลอกแทป Other แลวเลอก Menus คลกปม New หรอ ปอนคำาสงท command window ดงน CREATE MENU กดปม Enter
* หมายเหต ถาใช Visual FoxPro ตำากวา Version 5.0 จะสามารถทำาไดเฉพาะ Menu อยางเดยวใน Visual FoxPro ไดเตรยมเครองมอในการสรางเมนมาให 2 ชนด คอMenu เปนการสรางเมนธรรมดาตามปรกตShortcut เปนการสรางเมนทเปน Shortcut Menu ถานกภาพไมออก มนกคอเมนทเกดขนตอนคณคลกเมาสดานขวาแลวจะมเมนโผลออกมานนแหละใชเลย ของไท ธนาวฒMENU วธการสราง เมน ใหคณ คลกทปม Menu ใน dialog box New Menu หลงจากนนกจะเขาสในสวนของ Menu Designer ถาคณตองการสรางเมนในรปแบบท Visual FoxPro มมาใหสามารถทำาไดโดย เลอกเมน Menu แลวเลอก Quick Menu โปรแกรมกจะทำาการสรางเมนสำาเรจรปใหคณในบดดล แตในบทเรยนนไมขอแนะนำาใหคณทำาตามแบบ เราจะทำาการสรางเมนดวยตวของเราเอง
105
ใหคณปอนเมนตามตวอยางขางบนทนเรามาดวาแตละสวนใชทำาอะไรบาง Prompt เปนการกำาหนดเมน title และรายการเมน Result ใชบอกวาคำาสงในรายการเมนนนๆทำางานอยางไร Command กำาหนดใหเปนการปอนคำาสง สามารถปอนไดเพยง 1 บรรทด Pad Name กำาหนดชอ pad ในการอางถง Bar# กำาหนดใหใช system menu bar ซงมมากบ Visual FoxPro Submenu กำาหนดใหม submenu ยอย Procedure กำาหนดใหมการปอนคำาสงเปน โพซเยอรยอย Create/Edit ใชสำาหรบสรางแกไข submenu หรอ โพซเยอร Option เปนการกำาหนดลกษณะของรายการเมนของคณ Move Control เปนปมคำาสงอยดานหนา Prompt ใชสำาหรบยายตำาแหนงในรายการเมน Menu Level ใชแสดงระดบของเมนททำางานขณะนน และคณสามรถทจะยายระดบเมนของคณไดโดยใช menu level
106
Insert เปนปมคำาสงในการเพมรายการในเมน Insert Bar... เปนปมคำาสงในการเพมรายการเมนของ Visual FoxPro (sysyem menu bar) เขามาในเมนของเรา Delete เปนปมสำาหรบลบรายการในเมน Preview เปนปมสำาหรบทดสอบเมนทเราสรางขนมาทนเรากลบมาดเมนทเราทำาการสรางกนตอใน prompt File ใหทำาการคลกท ปม Create แลวทำาการปอนรายการตางๆดงนPrompt Result Customer Comman
d DO FORM CUSTOMER
Salesman Command
WAIT WINDOWS 'NO PROGRAM'
ใน prompt Other ใหทำาการคลกท ปม Create แลวทำาการปอนรายการตางๆดงนPrompt Result Assign User
Command DO FORM USERPRF
ใน prompt Exit ใหทำาการคลกท ปม Create แลวทำาการปอนรายการตางๆดงนPrompt Result Quit Comman
d CLEAR EVENT
จากนนใหคณคลกทปม Preview คณกจะไดเหนรายการเมนทคณไดทำาการสรางขนมา ผกอนทคณจะนำาเมนทคณสรางไปใชงานคณตองทำาการ Generate เมนของคณเสยกอน โดยทำาการ คลกท เมน Menu แลวเลอก Generate... เมอทำาการ generate เสรจเรยบรอย Visual FoxPro กจะสรางโปรแกรมขนมาใหคณ มนามสกลเปน .MPR
107
เวลาคณจะนำาเมนไปใชงานคณตองใชคำาสง DO ในการเรยกเมนนนๆขนมา เชนDO MENU.MPR
เมอคณตองการกลบไปใช เมนของ Visual FoxPro คณสามารถทำาไดโดยปอนคำาสงดงน SET SYSMENU TO DEFAULTแนะนำา โปรแกรมทเราใชสรางเมนขนมานเปนเพยงแคเครองมอทนแรงในการสราง โดยทความสามารถบางอยางทมอยในคำาสงของเมนนน เครองมอตวนไมสามารถทำาไดทงหมด คณยงตองการพงคำาสงในการโปรแกรมอยด ดงนงจงขอแนะนำา ใหคณเขาไปดการเขยนโปรแกรมทเราสรางจากเมนและ generate ออกมาเปนไฟล .MPR วามคำาสงอะไรบางใชอยางไร เกรดเลกเกลดนอยการกำาหนด Keyboard Shortcut เมอเราตองการใหมการเขาถงเมนของเราอยางรวดเรวเราสามารถทำาไดโดยการกำาหนด shortcut ในรายการเมนของเรา ซงมวธการดงนใหคลทปม Option ทชอง Key Label ใหทำาการกดปมบนแปนพมพทตองการทำาเปน shortcut เชน กดปม Ctrl กบ F, Alt กบ F เปนตนในชองของ Key Text จะเปนการกำาหนด ขอความทตองการใหแสดงหลงรายการเมน ในชองนสามารถแสดงไดในสวนของ รายการเมน(menu item) เทานน ในสวนของเมนไตเตล(menu title)ไมสามารถแสดงไดการกำาหนดฟอนตในรายการเมน(menu item)คณสามารถทจะเปลยนแปลง font ใน menu item ไดโดยอาศยเทคนคเลกนอย โดยทำาดงนใหคลทปม Option ทชอง Skip For ใหปอนคำาสงตามตวอยางน .F. FONT "AngsanaUPC",16 STYLE "BI"
108
AngsanaUPC เปนชอฟอนตทตองการใหแสดง 16 เปนขนาดของฟอนต B,I เปนการกำาหนดใหแสดงเปนตวหนาและเอยง * การใชวธกำาหนด font แบบนจะไมแสดงใหคณเหนตอนใชปม Preview คณตองทำาการ generate กอนแลวคอยใชคำาสง DO ชอเมน.MPR ถงจะสามารถแสดงใหเหนไดในชอง Skip For ถาผลลพธทไดมคาเปน จรง(.T.) จะเปนการทำาใหรายการนนไมสามารถทำาการคลกได กาวตอไปอกขนการกำาหนดเมนใหอยบนฟอรมคณสามารถทำาใหเมนใหไปปรากฎอยบนฟอรมแทนทจะไปอยบน main visual foxpro window ไดโดยทำาตามตวอยางตอไปน 1. ท command window ใหพมพคำาสง CREATE MENU MENUFORM 2. ใหเลอก Menu จากนนคณทำาการสรางเมน เพอความรวดเรวใหคลกทเมน Menu แลวเลอก Quick Menu โปรแกรมกจะสรางเมนสำาเรจรปใหคณ 3. จากนนใหไปท เมน View เลอก General Option ใหทำาการคลกท Top-Level Form 4. ทำาการ generate เมน โดยคลกทเมน Menu แลวเลอก Generate... เสรจขนตอนในการสรางเมนแลวครบ 5. ทำาการสรางฟอรม ท command window ใหพมพคำาสง CREATE FORM FORMMENU 6. ใหสรางฟอรมดงรป
109
ท form properties กำาหนด ShowWindows เปน 2 - As Top-Level Form Init Event ปอน DO menuform.mpr WITH THIS,.T. Destroy Event ปอน RELEASE MENUทปม Command1 กำาหนด properties Caption ปอน Cancel Click Event ปอน Thisform.Releaseทำาการ save ฟอรม แลวลองรนโปรแกรมด โดยพมพคำาสงท command window ดงน DO FORM FORMMENUSHORTCUTการสราง shortcut กคลายๆกบการสรางเมนปรกต เรามาดวาเราจะทำา shortcut ไดอยางไรกนกอน ใหคณสราง shortcut โดยปอนคำาสงท command window ดงน CREATE MENU MYSHORTใหเลอก Shortcut หลงจากนนใหสรางเมนดงนทำาการคลกทปม Insert Bar แลวเลอก Clear แลวคลทปม Insertเลอก Paste แลวคลทปม Insertเลอก Cut แลวคลทปม Insert
110
เลอก Copy แลวคลทปม Insertเมอคณทำาเสรจใหทำาการคลกทปม Close จะไดรายการเมนดงรป
ใหคณทำาการ generate เมน โดยคลทเมน Menu เลอก Generate...จากนนใหคณนำาฟอรมทเราไดสรางไวกอนหนานขนมำาทำาการแกไข โดยพมพคำาสงท command windows ดงน MODIFY FORM FORMMENUท Text1 ทำาการปอนคำาสงในสวนของ RightClick Event เปน DO MYSHORT.MPRท Text2 ทำาการปอนคำาสงในสวนของ RightClick Event เปน DO MYSHORT.MPRจากนนกทำาการ save ฟอรม แลวลองเรยกฟอรมมาด เวลาจะทดสอบ shortcut menu ใหคณปอนขอความท text1 แลว darg ขอความนน แลวคลกเมาสขวา กจะปรากฏ short menu ขนมาคณจะทำาอะไรตอไปกแลวแตคณ..
แนะนำา คณสามารถนำา shortcut menu ไปใสไวใน Control Textbox แลวเกบเปน Visual Class Library เพอจะไดลดเวลาในการปอนคำาสง
111
ทำาความเขาใจกบเมน คณทราบหรอไมวาเมนทเราทำาการสรางขนมาแตละสวนถกเรยกวาอะไรบาง?ในเมนนนจะประกอบไปดวยสวนตางๆดงน MENU PAD POPUP BARMENU เมนเปนสวนทใชแสดงรายการตางทเรากำาหนดไว เชน File Edit View .... ทงหมดนเรารวมเรยกวาเมน (menu bar)
ถาเราทำาการสรางเมนดวย Menu Designer เมนทไดจะมชอวา _MSYSMENU ซงกคอชอเมนของ Visual FoxPro นนเอง ถาเราทำาการเขยนโปรแกรมขนมาเองเราสามารถจะตงชอเองไดคำาสงทเราใชทำาการสราง MENUDEFINE MENU MenuBarName [BAR [AT LINE nRow]] [IN [WINDOW] WindowName | IN SCREEN] [FONT cFontName [, nFontSize]] [STYLE cFontStyle] [KEY KeyLabel] [MARK cMarkCharacter] [MESSAGE cMessageText] [NOMARGIN] [COLOR SCHEME nSchemeNumber | COLOR ColorPairList]เชน DEFINE MENU example BAR AT LINE 1ตวอยางขางตนเปนการสราง MENU ชอ example PAD เปนรายการตางๆทอยในเมนซงเราเรยกแตละรายการวา menu title เชนเมนไตเตล File เมนไตเตง Edit เปนตนคำาสงทเราใชทำาการสราง PADDEFINE PAD MenuTitle1 OF MenuBarName PROMPT
112
cMenuTitleText [AT nRow, nColumn] [BEFORE MenuName2 | AFTER MenuName3] [NEGOTIATE LEFT | NEGOTIATE MIDDLE | NEGOTIATE RIGHT] [FONT cFontName [, nFontSize]] [STYLE cFontStyle] [KEY KeyLabel [, cKeyText]] [MARK cMarkCharacter] [SKIP [FOR lExpression]] [MESSAGE cMessageText] [COLOR SCHEME nSchemeNumber | COLOR ColorPairList]เชน DEFINE PAD syspad OF _MSYSMENU PROMPT '\<System' COLOR SCHEME3 KEY ALT+S, ''ตวอยางขางตนเปนการสราง PAD ชอ syspad ภายใตเมน _MSYSMENU POPUP รายการตางๆของเมน (menu item) ทอยภายใต PAD เรารวมเรยกวา popup
คำาสงทเราใชทำาการสราง POPUPDEFINE POPUP MenuName
113
[FROM nRow1, nColumn1] [TO nRow2, nColumn2] [IN [WINDOW] WindowName | IN SCREEN] [FONT cFontName [, nFontSize]] [STYLE cFontStyle] [FOOTER cFooterText] [KEY KeyLabel] [MARGIN] [MARK cMarkCharacter] [MESSAGE cMessageText] [MOVER] [MULTISELECT] [PROMPT FIELD FieldName | PROMPT FILES [LIKE FileSkeleton] | PROMPT STRUCTURE] [RELATIVE] [SCROLL] [SHORTCUT] [TITLE cMenuTitleText] [COLOR SCHEME nSchemeNumber | COLOR ColorPairList]เชน ON PAD convpad OF _MSYSMENU ACTIVATE POPUP conversion DEFINE POPUP conversion MARGIN RELATIVE COLOR SCHEME 4จากตวอยาง เปนการกำาหนดให popup convesion อยภายใต convpad ของเมน _MSYSMENU BAR จะเปนสวนรายการ (menu item) ของเมน เชน รายการ New รายการ Open เปนตน คำาสงทเราใชทำาการสราง BAR DEFINE BAR nMenuItemNumber1 | SystemItemNameOF MenuName PROMPT cMenuItemText [BEFORE nMenuItemNumber2 | AFTER nMenuItemNumber3]
114
[FONT cFontName [, nFontSize]] [STYLE cFontStyle] [KEY KeyLabel [, cKeyText]] [MARK cMarkCharacter] [MESSAGE cMessageText] [SKIP [FOR lExpression]] [COLOR SCHEME nSchemeNumber | COLOR ColorPairList] เชน DEFINE BAR 1 OF conversion PROMPT '\<New' KEY CTRL+E, '^N'จากตวอยาง เปนการสราง รายการ New ภายใต popup conversion กำาหนดหมายเลข 1 ในการอางถงรายการนเราไดทราบวาในเมนทเราสรางขนมานนประกอบไปดวยสวนตางๆอะไรบาง แลวคำาสงนนๆเปนอยางไร คณลองสำารวจและทำาความเขาใจกบเมน MENU.MPR ในโปรแกรมตวอยางทให download ดวาคณเขาใจมากแคไหนการ Skip รายการของเมน ถาคณทำาการสรางฟอรมหรอรายงาน แลวนำาฟอรมหรอรายงาน ของคณไปใสไวในเมนเมอผใช(user)ทำาการเรยกรายการในเมน ขนมาใชงาน คณตองทำาใหรายการในเมนนนไมสามารถเรยกใชงานไดอกจนกวาผใชจะทำางานนนๆเสรจสน หรอทำาการปดฟอรมซงเราสามารถทำาไดหลายวธการดวยกน วธแรก เปนการกำาหนด skip รายการของเมนไวในฟอรม เราจะใช คำาสง SET SKIP OF โดยนำาไปใสไวท form properties ในสวนของ Init Event และ Destroy Event วธการนถาตอนททำาการสรางเมนโดยใช Menu Designer และไดมการกำาหนดเงอนไข Skip for ใน Prompt Option คำาสงทจะกลาวถงนจะไมมผลอะไรเกดขน สวนวธการกำาหนดเงอนไข Skip for จะเปนวธตอไปทจะกลาวถง เรากลบมาดวธแรกกนตอ ผมจะใหคณทำาตามตวอยางดงตอไปน
115
1. ใหคณทำาการสรางเมนขนมาโดยพมพคำาสงท command window ดงน CREATE MENU MENUS1 2. ทำาการคลกท Menu แลวปอนรายการดงนPrompt Result File Submen
u
Exit Command SET SYSMENU TO DEFALUT
จากนนใหทำาการคลกทปม option ของ prompt File เพอเขาส Prompt Option ใหทำาการปอนชอ pad ในชอง Pad Name วา PADFILE แลวคลกปม OK 3. ในสวนของ prompt File ใหคลกปม Create แลวปอนรายการดงนPrompt Result Form1 Comman
d DO FORM FORMS1
Form2 Command WAIT WINDOW 'TEST MENU'
ใหคลกทเมน View แลวเลอก Menu Options... ในชอง Name พมพ POPFILE (เดมเปน FILE) แลวคลกปม OK จากนนใหทำาการคลกทปม option ของ prompt Form1 เพอเขาส Prompt Option ใหทำาการปอนชอของรายการ ในชอง Bar# เปน 1หมายเหต คณอาจไมจำาเปนตองปอน Bar# กได ถาไมไดปอน Visual FoxPro จะกำาหนดใหเปน 1 ในรายการแรก และเลข 2,3... ตอไปเรอยๆในรายการตอๆไป 4. ทำาการ generate เมน โดยไปทเมน Menu เลอก Generate... หลงจากททำาการ generate เมนเรยบรอยแลวเราจะมาสำารวจ
116
โปรแกรมเมนทเราไดทำาการ generate ขนมา ใหคณพมพคำาสงดงน MODIFY COMMAND MENUS1.MPRใหคณสงเกตบรรทดคำาสงดานลางนดDEFINE PAD PADFILE OF _MSYSMENU PROMPT "File" COLOR SCHEME 3 KEY ALT+F, ""DEFINE PAD _s1r0u94fd OF _MSYSMENU PROMPT "Exit" COLOR SCHEME 3 KEY ALT+E, ""ถาเราไมไดทำาการตงชอใหกบ Pad Name ทาง Visual FoxPro จะทำาการตงชอใหเอง เปน _s1r0u94fd บางทานอาจไดเปนชออนกได ผมขอแนะนำาวาคณควรจะทำาการตงชอใหกบ pad ทสรางขนมาทกๆครง เชน ชอ PADFILE เปนตน เพอความสะดวกในการอางถงตอไปในสวนของ เมน View แลว Menu Options... เปนการกำาหนดชอใหกบ Popup ของเมนตามตวอยางขางลาง DEFINE POPUP popfile MARGIN RELATIVE SHADOW COLOR SCHEME 4สวนของ Bar# ทเรากำาหนดไวใหคณสงเกตทบรรทดตอไปนดDEFINE BAR 1 OF POPFILE PROMPT "Form1"ON SELECTION BAR 1 OF POPFILE DO FORMS1หมายเลขหลงคำาสง BAR เราสามารถเปลยนเปนหมายเลขอะไรกไดแลวแตเราจะกำาหนดเพอความสะดวกในการอางถงอกเหมอนกน 5. ใหทำาการสรางฟอรมขนมา โดยพมพคำาสงท command window ดงน CREATE FORM FORMS1ใหสรางฟอรมดงรป
117
ท form properties กำาหนด Init Event ปอน SET SKIP OF BAR 1 OF POPFILE .T. Destroy Event ปอน SET SKIP OF BAR 1 OF POPFILE .F.ทปม Command1 กำาหนด properties Caption ปอน Cancel Click Event ปอน Thisform.Releaseทำาการ save ฟอรมเมอคณทำาเรยบรอยแลว เราลองมาทำาการทดสอบดวาไดผลอยางไร ใหปอนคำาสงท command window DO MENUS1.MPRมาถงตรงนจะสงเกตไดวาคำาสงทใชในการ skip รายการของเมนเราจะใชคำาสง SET SKIP OF... เรามาดกนตอวาคำาสงนสามารถทำาอะไรไดอกจากทกลาวไวขางตนวาเมนประกอบไปดวย 4 สวนดงนนคำาสง SET SKIP OF... กสามารถทำาไดทง 4 สวนเหมอนกน ซงมรปแบบคำาสงดงนคำาสงทใชทำาการ skip เมน SET SKIP OF MENU MenuBarName1 lExpression1เชน SET SKIP OF MENU _MSYSMENU .T. && เมอตองการ skip เมน SET SKIP OF MENU _MSYSMENU .F. && เมอตองการยกเลกการ skip เมนคำาสงทใชทำาการ skip pad SET SKIP OF PAD MenuTitleName OF MenuBarName2 lExpression2เชน SET SKIP OF PAD PADFILE OF _MSYSMENU .T. && เมอตองการ skip PAD SET SKIP OF PAD PADFILE OF _MSYSMENU .F.&& เมอตองการยกเลกการ skip PAD
118
คำาสงทใชทำาการ skip popup SET SKIP OF POPUP MenuName1 lExpression3เชน SET SKIP OF POPUP POPFILE .T. && เมอตองการ skip POPUP SET SKIP OF POPUP POPFILE .F. && เมอตองการยกเลกการ skip POPUPคำาสงทใชทำาการ skip รายการ SET SKIP OF BAR nMenuItemNumber | SystemItemName OF MenuName2 lExpression4เชน SET SKIP OF BAR 1 OF POPFILE .T. && เมอตองการ skip รายการ SET SKIP OF BAR 1 OF POPFILE .F. && เมอตองการยกเลกการ skip รายการขอสงเกต การ SKIP เมนคา Expression จะมคาเปน .T. หรอ .F.
คา .T. จะเปนการ Skip รายการของเมนนนๆ คา .F. จะเปนการยกเลกการ Skip รายการของเมนนนๆ วธทสอง เปนการกำาหนด skip รายการไวท Skip for ในสวนของ OPTION ในเมน การกำาหนดโดยวธนเราตองเขยนฟงกชน(function) ขนมาแลวใหเกดเปน คา .T. หรอ .F. เรามาลองดฟงกชนสำาหรบการเชคเมน Exit กนกอน เพราะเมนรายการนจะตองตรวจสอบวามการเปดฟอรมอยหรอไม ถามการเปดฟอรมใดๆอยกตามกใหทำาการ skip เมน Exit ใหคณทำาการแกไขเมน MENUS1 โดยการปอนคำาสงดงน MODIFY MENU MENUS1ทำาการคลกทปม prompt ของรายการเมน Exit แลวทำาการปอนคำาสงในชอง Skip For ดงน _SCREEN.FORMCOUNT > 0
119
คลกทปม OK แลวทำาการ generate เมน โดยคลกทเมน Menu เลอก Generate..._SCREEN.FORMCOUNT เปนคำาสงนบจำานวนฟอรมททำาการเปดใชงานอย ณ. ขณะนน ถาไมมจะมคาเปน .F. ถามเปดอยจะใหคาเปน .T.ลองทำาการทดสอบเมนดโดยปอนคำาสง DO MENUS1.MPRแลวมวธอนทใชในการตรวจสอบการ skip รายการอกหรอไม?วธการตางๆมอกเยอะขนอยกบการประยกตใชและการนำามนมาใช เปนความสามารถพเศษหามเลยนแบบ เดกเลกควรอยในความดแลของผปกครอง คำาเตอนไมควรดมเกนวนละ 2 ขวด กอนดมควรอานคำาเตอนกอนทกครงลองมาดวธนอกวธหนง เปนการเขยนฟงกชนขนมาใชเองใหทำาการปอนคำาสงท command window ดงน MODIFY COMMAND CHKSKIPกดปม Enter จากนนทำาการปอนคำาสงตามตวอยางดานลาง******************************************************************** Function Check Skip Menu Item *******************************************************************Function chkskipPara cFormnamewith _Screen nScreen= .Formcount for i = 1 to nScreen if upper(allt(.Forms(i).Name)) = upper(allt(cFormname)) return .T. endif endforendwithreturn .F.
120
เมอปอนเสรจเรยบรอยใหทำาการ save โดยการกดปม Ctrl+Wใหทำาการสรางฟอรมขนมา โดยพมพคำาสงท command window ดงน CREATE FORM FORMS2ใหสรางฟอรมดงรป
ท form properties กำาหนด Caption = ทดสอบการ skip Name = Forms2 && เราตงชอเพอใชสำาหรบใชกบ ฟงกชน chkskipทปม Command1 กำาหนด properties Caption ปอน Cancel Click Event ปอน Thisform.Releaseทำาการ save ฟอรมขนตอมาใหคณทำาการแกไขเมน MENUS1 โดยการปอนคำาสงดงน MODIFY MENU MENUS1ทำาการคลกทปม Edit ทรายการ File ทรายการ Form2 แกคำาสง WAIT WINDOW 'TEST MENU' ใหเปน DO FORM FORMS2แลวทำาการคลกทปม prompt ทำาการปอนคำาสงในชอง Skip For ดงน CHKSKIP("Forms2") && Forms2 เปนชอฟอรมทเราตงขนมาคลกทปม OK แลวทำาการ generate เมน โดยคลกทเมน Menu
121
เลอก Generate...ลองทำาการทดสอบเมนดโดยปอนคำาสง DO MENUS1.MPRเปนอยางไรบางครบสำาหรบเรองของเมนเอาแบบพอหอมปากหอมคอ ถาอานมาถงขนนแลวยงไมเขาใจกปรกษาไดครบ เพราะการเขยนโปรแกรมมนไหลไปไดเรอยๆ มนไมตายตวแตละทานกเขยนตางกนไป กขอจบบทนเพยงเทานละครบ.การสรางฟอรมฟอรมเปนตวกลางทสำาคญตวหนงทจะทำาการตดตอระหวางผใชงานกบขอมลตางๆ ไมวาจะเปนการปอนขอมล การแสดงขอมล หรอการแสดงขาวสารตางๆทเกดขนในระบบงาน การทเราจะทำาการสรางฟอรมขนมาสกฟอรมหนงนนมนไมไดยากอะไรหรอก แตการทจะควบคมการทำางานของฟอรมนนมนไมไดงายสกเทาใด คณจะคมการทำางานของฟอรมไดอยางไรนนกขนอยกบการออกแบบ และการจตนาการของทานทงหลาย ถาคณเขาใจหลกการและวธการทผมจะแนะนำาในบทนแลว กคดวาจะเปนแนวทางในการออกแบบและสรางฟอรมของคณตอๆไป ลกษณะของฟอรมในการปอนขอมลโดยทวๆไปแลวจะมอย 2 แบบคอ 1.ฟอรมการปอนขอมลทละเรคคอรด เชน ฟอรมทใชปอนขอมล ลกคา, สนคา , พนกงานขาย เปนตน 2.ฟอรมการปอนขอมลทมความสมพนธแบบหนงตอหลายๆเรคคอรด เชน ฟอรมทใชปอนขอมลใบสงสนคา เปนตนการสรางฟอรมปอนขอมลทละเรคคอรอยางทกลาวไวขางตนวา การสรางฟอรมนนไมยากแตการควบคมการทำางานนนไมไดงายเหมอนกบการสรางฟอรม กอนอนเราตองนกกอนวาฟอรมทเราจะสรางตองการใหมลษณะเปนอยางไร และตองคำานงถงขอผดพลาดทจะเกดจากการปอนขอมล เพอทจะไดทำาการควบคมขอผดพลาดเหลานน ซงสงหลงนแหละจะบงบอกถงความ
122
สามารถในการเขยนโปรแกรมของคณ เรามาลองทำาฟอรมปอนขอมล สนคากนกอนหลกการทำาฟอรมปอนขอมลจะประกอบไปดวย 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
123
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_idBufferModeOveried จะเปนการกำาหนดการปองกนการปอนขอมลในตาราง(table) ซงการกระทำานนจะทำาการโอนขอมลของคณเกบไวทหนวยความจำาของคอมพวเตอรกอน เมอไดกระทำากบขอมลใน บฟเฟอรเรยบรอยแลวเราจะใชคำาสง TABLEUPDATE() ในการ update ขอมลลงสตารางอกท หรอถาตองการยกเลกการเปลยนแปลงใหใชคำาสง TABLEREVERT() ในการกำาหนด บฟเฟอรนนเราจำาเปนตองคำานงถงฟอรมทใชในการปอนขอมลดวยวาควรจะกำาหนดบบเฟอรเปนแบบใด ดงตอไปน 1 ไมมการกำาหนดบฟเฟอร 2 เปนการกำาหนดบฟเฟอรเพอปองกนเรคคอรททำางานอย ณ.ขณะนนไมใหผอนเขามาใชงานไดอก(lock record)
124
จนกวาเรคคอรนนจะถกปลอยออกมา(unlock record) 3 เปนการกำาหนดบฟเฟอรเพอปองกนเรคคอร ททำางานอยไมใหผอนเขามาใชงานเฉพาะตอนทจะ update ขอมล 4 เปนการกำาหนดบฟเฟอรเพอปองกนตาราง จนกวาตารางนนจะถกปลอยออกมา(unlock record) 5 เปนการกำาหนดบฟเฟอรเพอปองกนตาราง เฉพาะตอนทจะ updateสวนของปมควบคม 5. ท Form Control คลกทคอนโทล View Class ( ) เพอนำา Sub-Class MyControl ทผมไดสรางเตรยมไวใหนำามาไวใน ฟอรมแลวคลกท Add จากนนใหเลอก ไฟล mycontrol แลวคลกทปม Open แลวทำาการสรางฟอรมตามภาพดานลาง
กำาหนด Properties ของ คอนโทรแตละตวดงนMtextbox1ControlSource = Product.Prod_idInputMark = XXXXXMtextbox2ControlSource = Product.NameMtextbox3
125
ControlSource = Product.UmInputMark = XXXXXXXXXXMtextbox4Alignment = 1ControlSource = Product.UnitPriceInputMark = 9,999,999.99Mtextbox5Alignment = 1ControlSource = Product.On_HandInputMark = 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"
126
) 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.clickendifActivate Event ทำาการปอนคำาสงthisformset.toolbar1.Visible = .T.thisformset.form1.closable = .T.thisformset.toolbar1.Dock(0)select productthisformset.form1.refreshDeactivate Event ทำาการปอนคำาสงthisformset.toolbar1.Visible = .F.สวนของการตรวจสอบขอผดพลาดเมอคณไดทำาการสรางฟอรมมาถง ณ. จดนคณกสามารถทจะ run ฟอรมไดแลว แตฟอรมของคณนนกยงขาดสวนทสำาคญทสดไปอก
127
สวนหนงกคอการตรวจสอบขอผดพลาด กอนทเราจะทำาการทำาในสวนนผมขออธบายวธการซกหนอยกอนในการเชคขอผดพลาดนนสามารถทำาไดหลายแบบหลายวธ แตทผมจะกลาวถงนจะกจะเปนอกวธการหนงในการตรวจสอบขอผดพลาดทเกดขน ซงจะแบงเปน 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,"")
128
return .f. endif endif if empty(.mTextBox2.Value) .mTextBox2.setfocus messagebox("กรณาปอนชอสนคา",288,"") return .f. endifEndwithreturn .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 แลวลองเรยกฟอรมขนมาด
129
เคลดไมลบ ใน 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 จะกำาหนดใหการปดแฟมขอมล
130
แยกออกจากกนเปนเอกเทศแตละฟอรมกจะแยกออกจากกน แลวเราจะกำาหนดเปนแบบใหนด? ขอแนะนำาวาใหกำาหนดเปนแบบ 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
131
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) && ยายตวแปรอะเรยทสงผานเขามาไปไวทตวแปรอะเรยในฟอรม
132
เทคนคเกยวกบ 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
133
เทคนกเกยวกบ 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 เพอทำาการเกบขอมล
134
เคลดไมลบ แกปญหาจดเรยงลำาดบตามภาษาไทยดวยการเขาไปกำาหนดท เมน 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
135
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 พมพ
136
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 กใหเอาออกเพราะเราไมไดใช เอาออกไดโดยคลกเมาสทเสนโยงความสมพนธระหวางแฟม
137
แลวกดปม 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
138
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
139
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 โดยการคลก
140
เมาสขวาทคอลมน รหสลกคา แลวจะมเมนใหเลอกวาจะ เพม หรอ ลบขอมล สวนการแกไขขอมลนนคณกสามารถแกไขไดตลอดเวลา แตโปรแกรมจะทำาการตรวจสอบวา ในรายการ(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, "")
141
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 เพอ
142
ทำาการ 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 ปอนคำาสงดงน
143
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 nColIndexIF ThisForm.lAppendThisForm.nWhatRow = This.ActiveRowThisForm.lAppend = .F.ELSElMov = .F.IF ThisForm.nWhatRow # This.ActiveRowThisForm.nWhatRow = This.ActiveRownHold= RECNO()GO ThisForm.nRecNumcChange = GetFldState(-1,'Customer')IF AT('2', cChange)>0 .or. AT('4',cChange) > 0This.RefreshlMov = .T.IF MessageBox("Update Record",4)= 6=TableUpdate(.T.)ELSE=TableRevert(.T.)ENDIFThisForm.lSkip = .F.ELSEIF AT('4',cChange) = 0 .and. AT('1',cChange) = 0= TableRevert(.T.)
144
ThisForm.nRecNum = nHold ThisForm.lSkip = .F. ENDIF ENDIFGO nHoldIF lMovlMov =.F.ENDIFENDIFENDIFThis.Refresh
แนะนำาคำาสง ในการกระทำากบ record ทเรากำาหนดตารางเปนแบบบบเฟอร(table buffer) นนเราจะทราบไดอยางไรวามการเพมเรคคอรด ลบเรคอรด แกไขฟลด ใดๆบาง เพอทเราจะไดทำาการปรบปรงขอมลทถกตองเขาสตาราง (TABLEUPDATE) Visual FoxPro ไดมคำาสงเตรยมไวใหเราเรยบรอยแลวซงกคอ GETFLDSTATE() รปแบการใชงาน GETFLDSTATE(cFieldName | nFieldNumber [, cTableAlias | nWorkArea]) หลงจากททำาการเรยกใชงานคำาสงแลวจะสงคากลบมาเปนตวเลข ซงมาคาอยระหวาง 1 ถง 4 1 = บอกใหรวาฟลดนยงไมมการแกไข 2 = บอกใหรวาฟลดนไดมการแกไขขอมล หรอ ลบเรคคอรด 3 = จะเปนสถานะของการเพมขอมล และยงไมมการปอนขอมลเขาไป 4 = จะเปนสถานะของการเพมขอมล และไดมการปอนขอมลเขา หรอ ลบเรคคอรด nFieldNumber ถามคา -1 จะเปนการแสดงสถานะของทงเรคคอรด เชนคาทไดจะเปน 121121 โดยทคาตวแรกจะหมายถงวาเรคคอรดนนๆไดถกลบออกไปหรอไม สวนคาถดไปแสดงถง
145
ฟลดตางวาเปลยนแปลงหรอไมตวอยาง ใหคณทำาการเรยกแฟมขอมล ลกคาขนมา โดยพมพคำาสงท 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 ปอนคำาสง
146
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...
147
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
148
ขอควรจำา ในการกำาหนดความสมพนธใหกบตารางใดๆนน เราตองกำาการสรางแฟมดชน(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
สรางฟอรมตามตวอยาง
149
6. ทำาการสราง Command Button ตวแรกแลวกำาหนด property ดงน Caption = เพมใบสงสนคา Name = CmdAppend Click Event ปอนคำาสงดงนthisform.lNew = .T.sele inv_headgo bottnInv_No = inv_head.inv_no + 1INSERT 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.
150
.Grid1.Column1.Text1.Enabled = .F. .Grid1.Column5.Text1.Enabled = .F. .cmdAppendItem.Enabled = .T. .cmdDeleteItem.Enabled = .T. .refreshendwith 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..refreshendwith 8. ทำาการสราง Command Button ตวทสามแลวกำาหนด property ดงน Caption = บนทกใบสงสนคา Name = CmdSave Enabled = .F. Click Event ปอนคำาสงดงนsele inv_head=tableupdate(.F.)sele inv_dtl
151
=tableupdate(.T.)sele inv_headwith 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. .refreshendwith 9. ทำาการสราง Command Button ตวทสแลวกำาหนด property ดงน Caption = ยกเลก Name = CmdCancel Enabled = .F. Click Event ปอนคำาสงดงนsele inv_head=tablerevert(.T.)sele inv_dtl=tablerevert(.T.)sele inv_headif eof() .and. Thisform.lNewGO BOTTendif with thisform .txtDate.Enabled = .F. .txtCust_id.Enabled = .F. .combo1.setfocus .cmdAppend.setfocus .cmdAppend.Enabled = .T.
152
.cmdChange.Enabled = .T. .cmdSave.Enabled = .F. .cmdCancel.Enabled = .F. .cmdAppendItem.Enabled = .F. .cmdDeleteItem.Enabled = .F. .refreshendwith 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 ของ กรดดงน
153
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)
154
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
155
ตวทสอง กำาหนด 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 * หมายเหต ในสวนของ เมธอตนคณจะเพมคำาสงในการคำานวณอนๆกไดแลวแตความตองการ
156
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 อกตวหนง ดงน
157
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) เปนตวกำาหนด Structure Query Language (SQL)โปรแกรม Visual FoxPro ไดมการพฒนามาอยางตอเนอง ซงไมวาจะเปนรนใดกตามจะบรรจชดคำาสง Structure Query
158
Language (SQL) ไวดวยเสมอ อนทจรงแลวคำาสง SQL เรมมมาตงแต FoxPro ซงเปนรนบน ดอส(DOS) ซงกขอยกประโยชนใหกบ IBM ทไดคดคนภาษานขนมาเมอชวงกลากทศวรรษท 1970 ทหองวจยของไอบเอทเมอ San Jose รฐ แคลฟอรเนย ตอนนนใชคำาวา SEQUEL ตอมาในป 1980 ไดเปลยนมาเปนคำาวา SQL และกใชกนมาจนถงปจจบนน คำาสง SQL เปนคำาสงทงายตอการทำาความเขาใจ เพราะเปนภาษาเขยนทคลายๆกบภาษาองกฤษทวๆไป ชวยลดการเขยนโปรแกรมจากเดมลงไปไดอยางมากซงถาเราเขยนคำาสงดวย Visual FoxPro กตองเขยนกนหลายบรรทดหลายคำาสงซงอาจจะเกดขอผดพลาดขนไดงาย ดงตวอยางตอไปน ใชคำาสง SQLSELECT * FROM CUSTOMER WHERE SALES_ID = '10001' ใชคำาสงทไมใช SQLUSE CUSTOMERSET FILTER TO SALES_ID = '10001'BROWSEจะเหนไดวาการใชคำาสง SQL จะเปนการชวยใหเกดความสะดวกสบายในการเขยนคำาสงมากยงขน แตมไดหมายความวาจะใหทานเลกใชคำาสงปรกตนะครบใน Visual FoxPro ไดทำาการบรรจคำาสง SQL ไวดงนSELECT - SQL เปนคำาสงทใชในการสอบถามขอมล (query)ALTER TABLE - SQL เปนคำาสงทใชในการแกไขโครงสรางของแฟมขอมล(table)CREATE CURSOR - SQL เปนคำาสงทใชในการสรางแฟมขอมลชวคราว(temporary table) ตามทเรากำาหนดCREATE TABLE - SQL เปนคำาสงทใชในการสรางแฟมขอมล(create table)DELETE - SQL เปนคำาสงทใชลบขอมลตามเงอนไข
159
INSERT - SQL เปนคำาสงทใชในการเพมขอมลเขาสตาราง (append a new record)UPDATE - SQL เปนคำาสงทใชในการแกไขขอมลในตาราง ตามเงอนไขจะสงเกตวาคำาสงตางๆดงทกลาวมานเรากไดเคยใชกนมาบางแลว ตอไปนผมจะอธบายคำาสงตางๆและเทคนควธการใชงาน ซงหลงจากททานไดทำาความเขาใจกบคำาสงเหลานแลวเชอไดเลยวาทานจะเปนนกจดการฐานขอมลตวยงอกทานหนงเลยทเดยวคำาสง SELECT - SQLคำาสง SELECT - SQL เปนคำาสงทใชในการสอบถามขอมล ซงสามารถดงขอมลจากตาราง หรอหลายตาราง ตามเงอนไขทกำาหนด แลวใหแสดงผล ทาง จอภาพ เครองพมพ อะเรย หรอใหออกมาในรปของ ตารางขอมล กได ซงมรปแบบคำาสงดงนSELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] [Alias.] Select_Item [AS Column_Name] [, [Alias.] Select_Item [AS Column_Name] ...]FROM [FORCE][DatabaseName!]Table [Local_Alias] [[INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] JOIN DatabaseName!]Table [Local_Alias] [ON JoinCondition …][[INTO Destination] | [TO FILE FileName [ADDITIVE] | TO PRINTER [PROMPT] | TO SCREEN]][PREFERENCE PreferenceName][NOCONSOLE][PLAIN][NOWAIT][WHERE JoinCondition [AND JoinCondition ...] [AND | OR FilterCondition [AND | OR FilterCondition ...]]]
160
[GROUP BY GroupColumn [, GroupColumn ...]][HAVING FilterCondition][UNION [ALL] SELECTCommand][ORDER BY Order_Item [ASC | DESC] [, Order_Item [ASC | DESC] ...]]เมอเหนคำาสงแลวรสกวาทำาไมมนชางยาวอะไรอยางน แต Visual FoxPro ไดมคำาสงทชวยในการเขยนคำาสง SELECT - SQL ไวใหซงกคอคำาสง CREATE QUERY [FileName | ?] [NOWAIT]ซงเปนเครองมอตวหนงทมาชวยใหเราในการเขยนคำาสงทำาใหผใชสะดวกสบายยงขน แตถงอยางไรคณกตองเรยนรคำาสงอยด เพราะความสามารถบางอยางนน Query ไมสามารถทำาได ทนเรามาดวธใชงานกนกอนใหทำาการสราง Query โดยปอนคำาสงดงนCLOSE ALLOPEN DATABASE MYDATABASECREATE QUERY MYQUERYจากนนคณกจะเขาส Query Designer โปรแกรมกจะแสดงชอตารางทเกบอยใน MYDATABASE ขนมาใหเราเลอก ตอนใหคณทำาการเลอกตาราง customer โดยการ คลกเมาส 2 ครงทตาราง customer แลวทำาการคลกทปม Close คณกจะไดหนาตาตามรปดานลาง
161
ใน Query Designer จะประกอบไปดวยแทปทงหมด 6 แทปประกอบดวยแทป Field สวนนใชกำาหนดฟลดจากตาราง หรอ วว (View) เพอใชแสดงผลลพธ คณสามารถกำาหนดฟงกชน(Function) นพจน(Expression) เพอใชในการแสดงผลไดAvailable Field เปนสวนทใชแสดงชอฟลดทงหมดของตารางหรอวว ทเราทำาการเลอกมาใชงาน Function and Expression เปนสวนทใชในการกำาหนดฟงกชน หรอนพจนใหกบฟลดทตองการ เชน เราตองการนบจำานวนลกคา กใสวา COUNT(CUSTOMER.CUST_ID) เสรจแลวคลกทปม Add
แทป Join สวนนใชในเชอมตารางหรอววตงแต 2 ตารางหรอวว เขาดวยกนตามเงอนไขทกำาหนด จะประกอบดวยสวนตางๆดงน
162
Type กำาหนดประเภทของการเชอมขอมล มอย 4 ชนด คอ Inner จะเลอกขอมลเฉพาะทมเงอนไขตรงกนเทานน Left Outer จะถอเอาตรางดานขวาเปนหลก(Field Name)โดยจะเอาขอมลมาทงหมด สวนฝงซาย(Value)จะนำามาเฉพาะทมเงอนไขตรงกนเทานน Right Outer จะถอเอาตรางดานซายเปนหลก(Value)โดยจะเอาขอมลมาทงหมด สวนฝงซาย(Field Name)จะนำามาเฉพาะทมเงอนไขตรงกนเทานน Full จะนำาขอมลทงหมดของสองตารางมาแสดงField Name กำาหนดฟลดทจะเปนเงอนไขในการเชอม Criteria กำาหนดเงอนไขในการเชอมValue กำาหนดฟลดจากตารางอนทจะมาทำาการเชอม
แทป Filter สวนนเปนสวนทใชในการกำาหนดเงอนไขในการเลอกเรคคอรดจากตารางหรอวว ซงในสวนนจะตรงกบ วล WHERE ของคำาสง SELECT - SQL
แทป GroupBy เปนสวนทใชรวมกลมขอมลตามฟลดทกำาหนด ในสวนนจะตรงกบ วล GROUP BY ของคำาสง SELECT - SQL ปรกตจะใชในการคำานวณผลสรป ตางๆ เชน SUM , COUNT เปนตน ในสวนของปม Having จะเปนการกำาหนดเงอนไขในการเลอกขอมล ลกษณะจะเหมอนกบ แทป Filter แตจะทำากบผลลพธของกลมขอมล
แทป Miscellaneous ใชกำาหนดเงอนไขในการเลอกขอมล No Duplicates กำาหนดใหเลอกขอมลทซำากนมาเพยงเรคคอรเดยว
163
Cross-Tabulate กำาหนดใหสรางตารางแบบ คลอสแทป(ไขวตาราง) ไวจะกลาวถงอกท
ทกลาวมาขางตนเพอแนะนำาใหทานรจกกบ Query Desinger เทานนเพราะ Query Designer จะเปนเครองมอทชวยในการเขยนคำาสง SELECT - SQL ใหแกเรา และตอไปนผมจะยกตวอยางการเขยนประโยคคำาสง SELECT - SQL ในแบบตางๆ เพอใหทานสามารถนำาไปประยกตใชงานตอไป
การเขยนประโยคคำาสง SELECT - SQLคำาสง SELECT - SQL เปนคำาสงในการสอบถามขอมล ดงทกลาวไวขางตน คำาสงนคำาสงเดยวสามารถอธบายวธใชงานไดเยอะมาก มวธใชท พศดาลพนลกยงกวาตำานานสามกกอก ทนเรามาดกนทละฉากๆกแลวกน
ตวอยางแรก จะเปนการทดสอบเงอนไข จากการรบขอมลใน TextBox ของฟอรม ถามการปอนขอมลจะมการตรวจสอบเงอนไขเพอเลอกขอมลมาแสดง แตถาไมไดปอนขอมล(Empty) จะนำาขอมลมาแสดงทงหมด ใหทำาการสรางฟอรม ดงน CREATE FORM MYSQL1 ท Data Environment ใหกำาหนดแฟมชอ CUSTOMER ท ฟอรม ใหสราง TextBox ชอ Text1 สราง CommandButton ชอ Command1 แลวปอนคำาสงท Click Event ดงนSELECT * FROM CUSTOMER C ; WHERE (ALLTRIM(C.CUST_ID) == ALLTRIM(THISFORM.TEXT1.VALUE)) ; OR (EMPTY(THISFORM.TEXT1.VALUE) = .T.) ; ORDER BY C.CUST_ID ;
164
INTO CURSOR MYQUERYCREATE REPORT MYREPORT FROM MYQUERYREPORT FORM MYREPORT PREVIEWDELETE FILE MYREPORT.* จากนนทำาการ Save แลวลองเรยกฟอรมขนมาดเรามาแกะคำาสงขางในดกนกอน SELECT * (ดอกจนทน) หมายถงวาใหเลอกฟลดทแสดงมาทกฟลด แตถาตองการเฉพาะฟลด กกำาหนดชอฟลดเขาไปเชน C.NAME, C.ADDRESS ถามหลายฟลดเราจะใชเครองหมายคอมมา(,)เปนตวคนกลางระหวางฟลดCUSTOMER คอชอตาราง แฟมขอมลลกคา สวนอกษร C เปนชอ Alias ทเราตงขนเพอใชแทนชอตาราง CUSTOMER ใชเพอความสะดวกในการอางถงชอตารางWHERE ประโยคคำาสงหลง WHERE จะเปนนพจนทใชในการเลอกขอมลมาแสดงตามเงอนไขทกำาหนด จากตวอยางขางตนจะเปนการเลอก รหสลกคา สวนเครองหมาย == จะเปนโอเปเรเตอร(operator) ทใชในการเปรยบเทยบซงหมายถงตองเทากนทงหมด (Exactly Like) ซงจะตางกบเครองหมาย = (Equal) สวนนพจนทอยหลง OR คอ EMPTY(THISFORM.TEXT1.VALUE) = .T. อนนเปนเทคนค ในการเลอกขอมลอยางหนงดงทกลาวไวขางตนวา ถาไมมการปอนขอมลจะทำาการเลอขอมลมาทงหมด ลองพนจพเคราะหแลวคณกจะวงศกระจาง ( ศรญญ ) ORDER BY C.CUST_ID ใหเรยงลำาดงตามรหสลกคาINTO เปนการกำาหนดวาใหผลลพธทไดไปไวทไหน ในทนใหเกบไวทตารางชวคราวซงเราใชวลวา CURSOR โดยตงชอตารางวา MYQUERY
เคลดไมลบ _TALLY เปนตวแปรหนวยความจำา(System memory variable) ทบอกใหคณทราบถงจำานวนผลลพธของ
165
query เชน SELECT * FROM CUSTOMER INTO CURSOR MYCURSOR ? _TALLY* หมายเหต สำาหรบผมจะใชตรวจสอบวาการ query นนมขอมลหรอไมถาไมมจะมคาเทากบ 0ตวอยางการใชเงอนไขในการกรองขอมล (filter condition) ในการสอบถามขอมลเราสามารถใช wild card _ , % เพอชวยในการกรองขอมลได เชนcText = "a"cFilter = "%" + ALLTRIM(cTEXT) + "%"SELECT * FROM CUSTOMER C WHERE C.NAME LIKE cFilterจากตวอยางขางบนจะเปนการสอบถามชอบรษททมอกษร a อย ณ. ตำาแหนงใดๆกได cText = "a"cFilter = "___" + ALLTRIM(cTEXT) + "%"SELECT * FROM CUSTOMER C WHERE C.NAME LIKE cFilterจากตวอยางขางบนจะเปนการสอบถามชอบรษททมอกษร a อย ณ.ทส ตำาแหนงใดๆกได จะสงเกตไดวา % จะเหมอนกบ * สวน _ จะเหมอนกบ ? ใน DOSตวอยางการ เชอมตาราง (join table) จากบททแลวเราไดทำาการสรางฟอรมปอนขอมลใบสงของ(invoice) เรากไดทราบถงการสรางความสมพนธระหวางตารางหลายๆตาราง เมอทำาฟอรมแลวกจะตองมการสรางรายงานใบสงของ แตกอนจะเปนรายงานไดนนตองผานขนตอนหนงกคอการเลอกขอมลขนมา ซงเราจะใชคำาสง SELECT-SQL ทำาการเลอก ซงจะเปนการสราง SQL แบบ เชอมตารางเพอใหไดขอมลตามทตองการ ใหคณลองปอนคำาสงดงตอไปนท COMMAND WINDOW แลวลองดผลลพธทได
166
STOR 1 TO MYINVOICE && กำาหนดใหเลอกใบสงสนคาหมายเลข 1SELECT H.*, C.name AS Customer , D.prod_id ,P.name AS Product , ;D.quantity , D.unitprice , D.quantity * D.unitprice AS Amount ;FROM mydatabase!inv_head H ;LEFT OUTER JOIN mydatabase!customer C ;ON H.cust_id = C.cust_id;LEFT OUTER JOIN mydatabase!inv_dtl D ;ON H.Inv_no = D.Inv_no ;LEFT OUTER JOIN mydatabase!product P ;ON D.prod_id = P.prod_id ;WHERE H.inv_no = MYINVOICE ;ORDER BY H.inv_noจากตวอยางขางตนจะแสดงรายการของใบสงสนคาเลขท 1 ขนมา เรามาดวธการเชอมตารางวาทำากนอยางไร ทคำาสง SELECT H.*, C.name AS Customer , D.prod_id ,P.name AS Product , D.quantity , D.unitprice , D.quantity * D.unitprice AS Amount จะเปนการเลอกฟลดทตองการ ใหคณสงเกตทวล AS จะใชสำาหรบตงชอใหกบชอฟลดจะแสดงออกมา เชน ฟลด C.name ใหแสดงเปน Customer เปนตนในการเชอมตารางหลายๆตารางเราตองคำานงถงวาจะใหตารางอะไรเปนหลก ในตวอยางนจะใหตาราง INV_HEAD เปนหลก เพราะสงทเราสนใจกคอใบสงของ เราจะใสไวหลงวล FORM สวนตารางทเราจะนำามาเชอมนนกตองดดวยวาจะนำามาเชอมในลกษณะใด มอย 4 แบบดวยกนคอ INNER เปนการเชอมตารางโดยจะนำาขอมลของตารางทเชอมมาแสดงเฉพาะทมเงอนไขตรงกนเทานน LEFT OUTER เปนการเชอมตารางโดยจะนำาขอมลของตารางดานซายมาเปนหลกในการแสดง สวนดานขวาจะมขอมลตรง
167
กนหรอไมกได RIGHT OUTER เปนการเชอมตารางโดยจะนำาขอมลของตารางดานขวามาเปนหลกในการแสดง สวนดานซายจะมขอมลตรงกนหรอไมกได FULL OUTER เปนการเชอมโดยนำาของทงสองตารางมาเปนหลกในการแสดงสำาหรบในตวอยางจะเปนการเชอมในแบบ LEFT OUTER เนองจากวาบางครงขอมลในตารางดานขวาทเชอมอยอาจถกลบออกไป ถาเราใช INNER หรอ RIGHT OUTER ขอมลอาจจะไดมาไมหมด หรอไมถกตอง ในสวนนตองดความเหมาะสมของแตละกรณวาจะใชแบบไหน แลวจะรไดอยางไรวาอนไหนเปน LEFT หรอ RIGHT ? ใหคณดทวล ON เชน ON H.cust_id = C.cust_id หมายถง INV_HEAD เปน LEFT สวน CUSTOMER เปน RIGHTเราจะนำาตารางใดมาเชอมเรากใสวธการเชอมวา เปน INNER, LEFT, RIGHT, FULL แลวกใสชอตารางหลงวล JOIN แลวกตามดวยเงอนไขในการเชอมหลงวล ON
ขอควรระวง หามใชคำาสงแบบน select * from INV_HEAD,CUSTOMER โดยไมมเงอนไขในการ join ถาทำาคณไดไดขอมลเทากบขอมลของตารางสองตารางมาคณกน เชน ตาราง INV_HEAD = 20 เรคคอรด ตาราง CUSTOMER = 5 เรคคอรด ของมลทไดหลงจากคณ query แลวจะเทากบ 20 * 5 = 100 เรคคอรดการใชฟงกชนของในคำาสง SELECT มฟงกชน SUM,COUNT,AVG,MAX,MIN เราสามารถนำาฟงกชนเหลานไปใชงานไดทนท โดยมรปแบบการใชงานดงนSELECT ชอฟงกชน(ชอฟลดหรอชอคอลมน) FROM ตาราง ......
168
เชนเราตองการรวมยอดขายทงหมดเรากพมพคำาสงวา SELECT SUM(INV_DTL.QUANTITY * INV_DTL.UNITPRICE) FROM INV_DTLถาเราไมไดทำาการแบงกลมของขอมลคำาสงขางตนจะเปนการหายอดรวมของทงตาราง ดงนนถาเราตองการจะหาผลรวมแยกตามเลขทใบสงของ เราเขยนคำาสงดงน SELECT INV_DTL.INV_NO, SUM(INV_DTL.QUANTITY * INV_DTL.UNITPRICE) ; FROM INV_DTL GROUP BY INV_DTL.INV_NO ORDER BY INV_DTL.INV_NOการใช GROUP BY, HAVING และ ORDER BY GROUP BY เปนการจดกลมของขอมลเพอทจะใชฟงกชนมากระทำากบกลมของขอมลนนๆ ดงตวอยางขางตนซงเปนการแบงกลมของใบสงของ แลวใชฟงกชน SUM เพอหายอดรวมผลลพธของกลม เมอเราทำาการแบงกลมแลวควรจะทำาการเรยงลำาดบของขอมลตามกลมทเราไดจดแบงดวยเสมอ ซงเราใชคำาสง ORDER BY ในการใชคำาสงเรยงลำาดบนคณสามารถจะสงใหเรยงจากมากไปหานอยโดยใช DESC ใสเพมเขาไปหลง ชอฟลดหรอชอคอลมนทตองการเชน ORDER BY INV_DTL.INV_NO DESC แตถาไมใสหรอใสคำาวา ASC จะถอวาใหเรยงจากนอยไปมากHAVING จะคลายๆกบคำาสง WHERE คอใชในกรณตองการเลอกขอมลจากกลมตามเงอนไขทกำาหนด เชน ถาเราตองการหาวามใบสงของใบใหนบางทมราคารวมมากกวา 5000 บาทบาง เรากเขยนคำาสงดงน SELECT INV_DTL.INV_NO, SUM(INV_DTL.QUANTITY * INV_DTL.UNITPRICE) AS TOTAL ; FROM INV_DTL GROUP BY INV_DTL.INV_NO ORDER BY INV_DTL.INV_NO ; HAVING TOTAL > 5000
169
ใหคณสงเกตวาผมทำาการเปลนชอคอลมนผลรวมใหม จาก SUM(...) เปน TOTAL คณสามารถนำาชอใหมนมาใชงานไดเลย การสรางตารางไขว (cross-tab) ตารางไขวแตไมเขว คอการกลบขอมลจาก แถว ไปเปนคอลมน เพอความสะดวกในการนำาเสนอ สวนใหญจะกระทำากบการหาผลรวมสรปของขอมลตางๆ ในการสรางตารางไขวนน Visual FoxPro ไดเตรยม Cross-Tab Wizard ไวอำานวยความสะดวกใหเราเรยบรอยแลว คณสามารถเขาไปใชงานไดโดยการเลอกเมน File คลกท New แลวเลอก Query ทำาการคลกทปม Wizard แลวเลอก Cross-Tab Wizard คลกปม Ok จากนนกทำาตามท Wizard แจงมาใหทำา แตผมขอบอกไดเลยถาขอมลคณมการ join กนแลวละกคณกตองทำาการสราง View(เรองของ View จะนำาเสนอในตอนตอไป) กอนถงจะทำาได แตในทนจะนำาเสนอแบบลกทงเอฟเอม 95 เพอทจะใหทานรถงการสราง Cross-Tab ซงไมไดยากอะไรเลยถารหลกวธการทผมจะนำาเสนอตอไปนสมมตวาผมอยากทราบยอดขายของลกคาแตละราย โดยแยกตามพนกงานขาย ดงตารางตอไปน
รหสลกคา
พนกงานขาย 1
พนกงานขาย 2
พนกงานขาย 3... (จำานวนคอลมนจะเทากบจำานวนพนกงานขาย)
รวม
10001 180.00 180.
0010002 25000.0
0 2500.00
10009 678.00 678.
00
170
กอนอนเราตองทำาการเลอกขอมลกอนโดยใช SELECT - SQL ดงตวอยางSELECT Inv_head.cust_id, Customer.sales_id, Inv_head.inv_no,;SUM(INV_DTL.QUANTITY * INV_DTL.UNITPRICE);FROM mydatabase!inv_head ;LEFT OUTER JOIN mydatabase!inv_dtl; ON Inv_head.inv_no = Inv_dtl.inv_no;LEFT OUTER JOIN mydatabase!customer ; ON Inv_head.cust_id = Customer.cust_id ;GROUP BY Inv_dtl.inv_no ;ORDER BY Inv_head.cust_id, Customer.Sales_id, Inv_dtl.Inv_no ;INTO CURSOR MYCURSORเมอทำาการรนคำาสงเรยบรอยแลวเราจะไดขอมลเกบอยท ตาราง MYCURSOR ใหลองใชคำาสง BROWSE เพอเรยกดขอมล ซงจะมลกษณะดงรป แตขอมลอาจแตกตางกนบางขนอยทตอนคณปอนขอมล
เมอเราไดขอมลแลวสงเกตวาตารางทไดยงเปนปรกต สงทเราตองการคอกลบขอมลของ Sales_id จากแถวไปเปน คอลมน ใหทำาการปอนคำาสงตามน DO (_GENXTAB) WITH 'MYTAB' ,.T. ,.T., .T. ,1 ,2 ,4 , .T.เมอทำาการรนคำาสงเรยบรอยแลวเราจะไดขอมลเกบอยท ตาราง MYTAB ใหลองใชคำาสง BROWSE เพอเรยกดขอมล ซงจะมลกษณะดงรป
171
เปนอนเรยบรอยสำาหรบการทำาตารางไขว หลงจากนคณจะนำาขอมลทไดไปทำาอะไรตอกได เชน ออกรายงานเปนตน
แนะนำาคำาสง DO (_GENXTAB) เปนโปรแกรมทใชในการสรางตารางไขว(cross-tab) ซงมรปแบบคำาสงดงน DO (_GENXTAB) WITH <output file>, [<output type>], [<close source>], ; [<show thermometer>], [<row>], [<column>], [<cell>], [<row total>]เรามาดกนวา parameter แตละตวใชงานอยางไร <output file> เปนชอของตาราง cross-tab <output type> กำาหนดเปน .T. output file ตารางทไดจะเปนตารางชวคราว(CURSOR) กำาหนดเปน .F. หรอไมกำาหนด output file ตารางทไดจะเปนประเภทตามตารางตนฉบบ <close source> กำาหนดเปน .T. หรอไมกำาหนด จะทำาการปดตารางตนฉบบใหอตโนมต กำาหนดเปน .F. จะยงไมปดตารางตนฉบบ <show thermoeter> กำาหนดเปน .T.หรอไมกำาหนด จะแสดงบารบอกการทำางาน กำาหนดเปน .F. จะยงไมใหแสดงบารบอกการทำางาน <row> กำาหนดหมายเลขฟลด ทจะใหมาเปน row ในตารางไขว จากตวอยางขางตน ทตาราง MYCURSOR ฟลด Cust_id จะเปนหมายเลข 1, Sales_id เปนหมายเลข 2, Inv_no เปนหมายเลข 3, Sum_exp_4 เปนหมายเลข 4
172
<col> กำาหนดหมายเลขฟลด ทจะใหมาเปน column ในตารางไขว <cell> กำาหนดหมายเลขฟลด ทจะใหมาเปนขอมลในตารางไขว <row total> กำาหนดเปน .T. จะทำาการสรางฟลดผลรวมใหดวยRushmore TechnologyRushmore Technology เปนเทคโนโลยทชวยเพมความเรวในการเขาถงขอมลใน Visual FoxPro ซงเปนลกษณะเดนทเกดขนตงแต FoxPro 2 สมยทยงเปน DOS อย ซงเปนเทคโนโลยทชวยเพมความเรวในการเขาถงเรคคอรด โดยอาศยแฟมดชนเขาชวย ซงแฟมดชนของ Visual FoxPro มอย 2 ชนด คอ แฟมดชนมาตรฐาน(.IDX) กบ compound index(.CDX) โดยทแฟม .CDX จะถกเปดโดยอตโนมตเมอเราทำาการเปดตารางขนมาใชงาน ฉะนน เราสามารถใชความสามารถของ Rushmore ไดทนท แตถาเรามแฟม .IDX เราตองทำาการเปดแฟมดชนทมความสมพนธกบเงอนไขทเราตองการกอนแลวเราจะสรางแฟมดชนอยางไรถงจะใชความสามารถของ Rushmore Technology ได?ตองขอบอกตรงนกอนเลยวา การใช Rushmore Technology สามารถใชงานไดกบคำาสงตางๆเหลานโดยอาศยวล FOR ไดดวย AVERAGE BLANK BROWSE CALCULATECHANGE COPY TO COPY TO ARRAY COUNT DELETE
INDEXLABELLISTLOCATERECALLREPLACEREPLACE FROM ARRAYREPORTSCAN
173
DISPLAY EDIT EXPORT
SORTSUMTOTAL
เทคโนโลย Rushmore จะทำางานไดเรวมากเมอคณใช คอมพวเตอรเพยงเครองเดยวทำางานกบตารางเดยว แตใชวาจะใชกบหลายผใช หรอหลายๆตารางไมได เพยงแตประสทธภาพการทำางานจะดอยลงมาเทานนเองขอควรระวง Rushmore Technology จะไมทำางานถาคณสรางแฟมดชนทมเงอนไข NOT เชน INDEX ON CUST_ID FOR .NOT.DELETE() TAG CUSTOMER เชน ถาตองการคำานวณยอดรวมของ invoice ถาเราตองการความเรวในการคำานวณ ใหทำาการสรางแฟมดชนดงตวอยางตอไปนOPEN DATABASE MYDATABASEUSE INV_DTLINDEX ON INV_NO TAG INV_NO1&& เมอเราใชคำาสงตามตวอยางดานลางเรากจะไดใชความสามารถของ rushmoreCalculate Sum(Inv_dtl.Quantity*Inv_dtl.UnitPrice) ; For Inv_dtl.inv_no = 1 ; To nMytotal? nMytotal
จากทกลาวมานเราพอจะสรปไดวา Rushmore Technology นนอาศยหลกการเขาถงขอมลจากแฟมดชน ฉะนนเราจะเพมความเรวใหกบโปรแกรมของเรา เมอเราใชวล FOR ครงใด โปรดสำารวจแฟมดชนของคณวามลกษณะตรงกนกบเงอนไขใน FOR หรอไม เชนตองการเปรยบขอมลของฟลดใด กควรจะทำาดชนใหกบฟลดนนๆดวย UPDATE INV_DTL SET QUANTITY = 30 WHERE INV_DTL.INV_NO = 1 .AND. PROD_NO = '10001'
174
ในสวน SQL เรากสามารถใชความสามารถของ Rushmore Technology ไดเชนกน ดงตวอยางตอไปน SELECT INV_DTL.INV_NO, SUM(INV_DTL.QUANTITY * INV_DTL.UNITPRICE) ; FROM INV_DTL WHERE INV_DTL.INV_NO = 1 Visual FoxPro ตงแตรน 5.0 เปนตนมาไดเพมฟงกชนในการตรวจสอบการทำางานของ rushmore technology กบ คำาสง SQL มาใหซงมรปแบบคำาสงดงน SYS(3054, 0 | 1 | 11 ) 0 กำาหนดไมใหแสดงสถานะการ optimize ของ rushmore technology 1 กำาหนดใหแสดงสถานะการ optimize ของ rushmore technology แตจะแสดงกบตารางเดยว 11 กำาหนดใหแสดงสถานะการ optimize ของ rushmore technology แตจะแสดงกบตารางทมการเชอมกน(join)ตวอยางเชน ถาตองการตรวจสอบดวาคำาสงตอไปนจะใชความสามารถของ Rushmore หรอไม ใหพมพคำาสงดงน ? SYS(3054,1)แลวลองใชคำาสง UPDATE - SQL ทำาการปรบปรงขอมลของตาราง INV_DTL โดยทำาการเปลยน quantity เปน 30 ตามเงอนไขทกำาหนดดวาผลลพธจะเปนอยางไร UPDATE INV_DTL SET QUANTITY = 30 WHERE INV_DTL.INV_NO = 1 .AND. PROD_NO = '10001'หลงจากทเรยกคำาสงแลวโปรแกรมจะแสดงขอความดงนUsing index tag Inv_no1 to rushmore optimize table Inv_dtlUsing index tag Prod_id to rushmore optimize table Inv_dtlRushmore optimization level for table inv_dtl:full
175
แสดงวาคำาสงขางตนไดใชความสามารถของ rushmore อยางเตมทใหคณลองสงเกตคำาสงตอไปนดวาเกดอะไรขนบางเมอเราทำาการ เชอมตารางลายๆตารางเขาดวยกน ? SYS(3054,11) SELECT Inv_head.cust_id, Customer.sales_id, Inv_head.inv_no , ; SUM(INV_DTL.QUANTITY * INV_DTL.UNITPRICE) ; FROM mydatabase!inv_head ; LEFT OUTER JOIN mydatabase!inv_dtl ;
ON Inv_head.inv_no = Inv_dtl.inv_no ; LEFT OUTER JOIN mydatabase!customer ; ON Inv_head.cust_id = Customer.cust_id ; GROUP BY Inv_dtl.inv_no ; ORDER BY Inv_head.cust_id, Customer.Sales_id, Inv_dtl.Inv_no ; WHERE INV_DTL.INV_NO = 1 ; INTO CURSOR MYCURSORจากทกลาวมาทงหมดนเรากสามารถใชความสามารถของ rushmore technology ชวยในการเพมความเรวในการเขาถงขอมลไดดยงขนทนเรามาดรปแบบการใชงาน SELECT - SQL และเทคนคตางๆกนตอกำาจดขอมลทซำากนออกดวย วล DISTINCT SELECT DISTINCT Inv_dtl.Inv_no FROM Inv_dtlการใชตวแปรมาโคร (Macro Substitution) ในกรณทคำาสงหรอเงอนไขใน query ของเรายาวมากๆ เราสามารถใชตวแปรมาโครแทนคำาสงหรอเงอนไขเหลานนได
176
cMymacro = "Inv_head.Inv_no # 1 AND Inv_head.Cust_Id = '10002'" SELECT * FROM Inv_head WHERE &cMymarcro ในบางครงการใชตวแปรมาโครกไมสะดวกนกเราอาจใชตวแปรแทนในการสงงาน query ไดเชน cMyfield = "CUST_ID" cMycond = "10002" SELECT * FROM Customer WHERE EVALUATE(cMyfield) = (cMycond)การใชงาน Subquery Subquery คอ การใชคำาสง SQL ภายใตคำาสง SQL อกท เพอทำาการเลอกขอมลตามเงอนไขใน subquery อกครงหนง เชน ถาเราตองการอยากทราบวาลกคารายใดทไมเคยซอสนคาของเราเลย เราสามารถสอบถามขอมลไดโดยใชคำาสงตอไปน SELECT * FROM Customer ; WHERE Customer.Cust_Id NOT IN ; (SELECT DISTINCT Inv_head.Cust_Id FROM Inv_head)ตอนตอไปจะเปนการเรยนรคำาสง SQL คำาสงอนๆรายงาน (Report)รายงานถอเปนสวนทสำาคญทสดอกสวนหนงของระบบงาน การสรางโปรแกรมสำาหรบพมพรายงานโดยหลกทวๆไปแลวจะประกอบไปดวยสวนประกอบ 3 สวนคอ 1. สวนของการรบขอมล สวนนสวนใหญจะเปนฟอรมทจะรอรบขอมลทผใชงานปอนเขาไปตามเงอนไขทกำาหนด เพอทจะนำาขอมลทปอนไปประมวลผลในการออกรายงาน 2. สวนของการประมวลผลขอมล ในสวนนจะเปนการนำาขอมลทผใชปอนขอมลจากฟอรม มาประมวลผลเพอใหไดขอมลตามตองการ 3. สวนของรายงาน เปนการนำาขอมลทไดจากการ
177
ประมวลผลแลวแสดงออกมาในรปแบบตางๆตามทตองการ เชนแสดงทจอภาพ ,เครองพมพ หรอ เกบเปนแฟมขอมลจากทกลาวมาขางตนรายงานบางแบบอาจมวธการนอกเหนอจากนกได เรมตนสรางรายงานตวอยางรายงานตอไปนจะเปนรายงานแสดงสรปยอดการสงซอของลกคาโดยใหทำาการเรยงลำาดบตามยอดการสงซอจากมากไปหานอย(Ranking) มวธการดงน
ทำาการสรางฟอรมตามตวอยาง 1. ท command windows ปอนคำาสง SET DEFA TO C:\MYAPP MODIFY COMMAND MYPROJECT (โปรเจก myproject คณสามารถ download โปรแกรม ตวอยางไดท เร มสรางระบบงาน) 2. คลกทแทป Docs คลกท Forms แลวเลอก New จากนนใหทำาการคลกท New Form 3. กำาหนด form properites โดยคลกเมาสปมขวา แลวเลอก properties กำาหนดคณสมบตของฟอรม ดงน Autocenter = .T. Caption = รายงานสรปยอดการซอสนคา Controlbox = .F.
178
4. ทำาการสราง Text Box ตวแรก แลวกำาหนด property ดงน Name = cFromCust_ID Inputmark = XXXXX 5. สราง Text Box ตวทสอง แลวกำาหนด Property ดงน Name = cToCust_ID Inputmark = XXXXX 6. สราง Option Group แลวกำาหนด Property ดงน ท Optiongroup1 Name = optSelect ทำาการปอนคำาสงในแทป Method ใน Click Event ดงน IF This.Value = 1 Thisform.cFileName.Enabled =.T. ELSE Thisform.cFileName.Enabled =.F. ENDIF ท Optiongroup1 -> Option1 Name = optPreview ท Optiongroup1 -> Option2 Name = optPrint ท Optiongroup1 -> Option3 Name = optFile 7. สราง Text Box ตวทสาม แลวกำาหนด Property ดงน Name = txtFileName Inputmark = XXXXXXXX Enabled = .F. 8. สราง Command Button ตวแรก แลวกำาหนด Property ดงน Name = cmdPrint Caption = พมพ FontName = MS Sans Serif ทำาการปอนคำาสงในแทป Method ใน Click Event ดงน
179
* Check Error EntryIF Thisform.cFromCust_ID.Value < Thisform.cToCust_ID.Value =MESSAGEBOX("จากรหสลกคาตองนอยกวาถงรหสลกคา","ผดพลาด") Thisform.cFromCust_ID.Setfocus RETURNENDIF
IF Thisform.optSelect.Value = 3 AND EMPTY(Thisform.cFileName.Value) =MESSAGEBOX("กรณาปอนชอแฟม","ผดพลาด") Thisform.cFileName.Setfocus RETURNENDIF
* Select DatacFrom = ALLTRIM(Thisform.cFromCust_ID.Value)cTo = ALLTRIM(Thisform.cToCust_ID.Value)
SELECT C.cust_id, C.name, C.creditlmt,;C.sales_id, sum( D.quantity* D.unitprice) as Total ;FROM mydatabase!customer C ;LEFT OUTER JOIN mydatabase!inv_head H;INNER JOIN mydatabase!inv_dtl D ;ON H.inv_no = D.inv_no ;ON C.cust_id = H.cust_id;WHERE (C.cust_id BETWEEN (cFrom) AND (cTo)) OR ; (EMPTY(cFrom) AND EMPTY(cTo)) ;GROUP BY C.cust_id ;ORDER BY Total DESC ;INTO CURSOR MYCURSOR
IF _TALLY=0 =MESSAGEBOX("ไมมขอมล","ผดพลาด")
180
Thisform.cmdCancel.ClickELSE * Print Report DO CASE CASE Thisform.optSelect.Value = 1 REPORT FORM CUSTRPT.FRX PREVIEW NOCONSOLE CASE Thisform.optSelect.Value = 2 REPORT FORM CUSTRPT.FRX TO PRINTER PROMPT NOCONSOLE CASE Thisform.optSelect.Value = 3 REPORT FORM CUSTRPT.FRX TO ; FILE (Thisform.cFileName.Value) ASCII NOCONSOLE ENDCASE Thisform.cmdCancel.ClickENDIF 9. สราง Command Button ตวแรก แลวกำาหนด Property ดงน Name = cmdCancel Caption = ยกเลก FontName = MS Sans Serif ทำาการปอนคำาสงในแทป Method ใน Click Event ดงน Thisform.Release 10. เสรจแลวทำาการบนทกฟอรม โดยคลกทเมน Form แลวเลอก Save ใสชอแฟมวา CUSTRPTทำาความรจกกบ Report Designerการสรางรายงานนน Visual FoxPro ไดเตรยมเครองมอทชวยในการสรางรายงานไวใหแลว ซงกคอ Report Designer เราสามารถเขาไปสรางรายงานไดโดยใชคำาสง CREATE REPORT ชอไฟลหรอ คลกทเมน File เลอก New แลวคลกท Report จากนนกคลกทปม New File
181
กอนอนเรามาทำาความรจกกบ ลกษณะของรายงานประเภทตางๆท Visual FoxPro ไดเตรยมไว ซงมดงน
Column report เปนรายงานทแสดง 1 เรคคอรดตอ 1 บรรทด เชน รายงานรายชอลกคา รายงานสรปยอดการซอสนคา Row report เปนรายงานทในหนงหนาจะมเพยง คอลมนเดยว โดยทฟลดแตละฟลดจะเรยงลงมา One-to-meny report เปนรายงานท 1 เรคคอรดจะประกอบดวยตารางหลายตารางมาเชอมความสมพนธกน เชน ใบสงสนคา Multi-column เปนรายงานทใน 1 หนาจะมหลายๆ คอลมน และฟลดแตละฟลดจะเรยงลงมา Label เปนรายงานทใชพมพปายฉลาก
สำารวจ Report Designerเมอทำาการสรางรายงานโดยใชคำาสง CREATE REPORT แลวเรากจะไดพบกบ Report Designer ซงเปนเครองมอทชวยในการสรางรายงานของ Visual FoxPro เรามาทำาการสำารวจดกอนวาใน report designer ประกอบไปดวยสวนตางๆอะไรบาง
182
แถบ ลกษณะการพมพพมพ คำาสง
Titleพมพครงเดยวในรายงาน เมอเรมตนรายงาน
คลกทเมน Report เลอก Title/Summary คลกท Title band
Page Header พมพเมอขนหนาใหม ปรากฎตอนสราง Report
Column Header
พมพเมอขนหนาใหม ตามคอลมน
คลกทเมน File เลอก Page Setup ในชองของ Columns ใหกำาหนด Number มากกวา 1 (จำานวนของคอลมนทใหแสดงในรายงาน)
Group Header
พมพเมอเปลยนกลมขอมล
คลกทเมน Report เลอก Data Grouping... แลวกำาหนดฟลดทตองการใหแบงกลม
Detail พมพตามเรคคอรด ปรากฎตอนสราง Report
183
Group Footer
พมพเมอเปลยนกลมขอมล
คลกทเมน Report เลอก Data Grouping... แลวกำาหนดฟลดทตองการใหแบงกลม
Column Footer
พมพตอนสนสดหนา ตามคอลมน
คลกทเมน File เลอก Page Setup ในชองของ Columns ใหกำาหนด Number มากกวา 1 (จำานวนของคอลมนทใหแสดงในรายงาน)
Page Footer
พมพเมอเปลยนกลมขอมล
ปรากฎตอนสราง Report
Summary
พมพครงเดยวในรายงาน ตอนสนสดของรายงาน
คลกทเมน Report เลอก Title/Summary คลกท Summary band
แนะนำา ในรายงานถาตองการกำาหนดฟอนต(font) ทงรายงาน หลงจากทเขาส Report Designer ใหคลกท เมน Report เลอก Default Font... แลวทำาการกำาหนดฟอนตตามตองการทำาการสรางรายงานสรปยอดการซอสนคา
184
1. คลกทแทป Docs คลกท Reports แลวเลอก New จากนนใหทำาการคลกท New Report 2. กำาหนด Defalut Font โดยคลกทเมน Report เลอก Defalut Font... กำาหนดฟอนตเปน CordiaUPC ขนาด 14 3. ทำาการกำาหนดขอความในสวนของ Page Header โดยการคลกท ใน Report controls แลวทำาการคลกในตำาแหนงทตองการแลวปอนขอความตามตองการในกรณทตองการแกไขขอความทปอนผด ใหคลกท จะเปนรปบมลงไปแลวกไปคลกทขอความทตองการแกไข แลวทำาการแกไขขอความตามตองการการสรางเลขลำาดบท 4. ลำาดบทของรายงานเราอาจจะใช ฟงกชน RECNNO() แตบางกรณกไมสามารถใชงานได ใหคณทำาการสรางตามดงน ใหทำาการคลกทเมน Report แลวเลอก Variables...
ทชอง Variables กำาหนดตวแปร ใหชอวา NO ทชอง Caculates กำาหนดเปน Count แลวคลกปม OK 5. ทำาการกำาหนดฟลดหรอตวแปรทตองการพมพออกในรายงานในสวนของ Detail โดยการคลกท แลวไปคลกในตำาแหนงทตองการ แลวปอนชอตวแปรหรอฟลดในชอง Expression แลวกำาหนดรปแบบการพมพทชอง Format แลวคลกปม OK ทชอง Expression กำาหนดตวแปรชอ no ทชอง Format กำาหนดรปแบบการพมพเปน 9999 ทชอง Expression กำาหนดฟลดชอ cust_id ทชอง Expression กำาหนดฟลดชอ name ทชอง Expression กำาหนดฟลดชอ creditlmt ทชอง Format กำาหนดรปแบบการพมพเปน @Z 999,999,999.99
185
ทชอง Expression กำาหนดฟลดชอ total ทชอง Format กำาหนดรปแบบการพมพเปน @Z 999,999,999.99 ทชอง Expression กำาหนดฟลดชอ sales_id ในรายงานทเราทำาการสรางขนนจะไมมการอางถงตารางของมลดงนนฟลดทใชงานเราจะอางมาจาก ตารางชวคราวของคำาสง SELECT-SQL ทไดสรางไวใน ฟอรมกอนหนา ดงนนชอฟลดตางๆกใหตงชอตามชอฟลดใน SELECT-SQL 6. สรางยอดรวมของรายงานโดยทำาการคลกทเมน Report เลอก Title/Summary แลวคลกทชอง Summary band คลกปม OK เรากจะไดแถบ Summary ขนมาในสวนของ Report Designer ทำาการคลกท ทชอง Expression กำาหนดชอฟลดทพมพชอ total ทชอง Format กำาหนดรปแบบการพมพเปน @Z 999,999,999.99 แลวทำาการคลกท ปม Calculations... ทชอง Calculate ใหคลกท Sum หลงจากทคณไดทำาการตกแตงรายงานเปนทพอใจแลวทำาการ save รายงานโดยคลกทเมน File แลวเลอก Save ตงชอวา CUSTRPT หลงจากนนใหคณเรยกฟอรมขนมาใชงานแลวพมพรายงานด....แนะนำา รายงานพมพเปนแฟมเกบไว สามารถทจะพมพออกทางเครองพมพไดโดยใชคำาสง RUN COPY /b ชอไฟล LPT1:การพมพรายงานใน Visual FoxPro เราสามารถกำาหนดใหมการพมพหรอไมพมพฟลดบางฟลด หรอกำาหนดไมใหมการพมพบรรทดทเปนชองวาง ไดโดยการเขาไปกำาหนดทฟลดนนๆ เชน ทฟลด Total เราจะไมใหมการพมพขอมลถาขอมลนนมคาเปน .NULL. (คา null จะเกดขนตอนทเราสรางความสมพนธระหวางตาราง ซงตารางทนำามาสรางความสมพนธกนนนอาจจะไมมขอมลทมความสมพนธซงกนและกนจงเกดคา null ขนมา) 1. ใหทำาการเรยกรายงาน CUSRPT มาทำาการแกไขโดยพมพ
186
คำาสงท Command Window ดงน MODIFY REPORT CUSRPT 2. ท Report Designer ใหทำาการคลกเมาสปมขวาทฟลด Total แลวเลอก Properites... 3. ท Report Expression ใหทำาการคลกทปม Print When... 4. ในชอง Print only when expression is true: ใหปอนเงอนไขวา .NOT.ISNULL(TOTAL) เปนการสงใหโปรแกรมไมทำาการพมพขอมลของฟลด TOTAL ถาฟลดมคาเปน .NULL. 5. ในสวนนคณสามารถทจะกำาหนดวาถาเรคคอรดใดทวางเปลาไมใหมการพมพออกมาโดยทำาการคลกท Remove line if blank จากนนใหคลก OK ตอมาท Report Expression. ใหทำาการคลกปม OKเลอกขอมลแลวนำามาพมพในบางครงการพมพรายงานอาจไมจำาเปนทจะตองพมพตามกฏเกณทกได เชนตองการพมพรายการท 1 และรายการท 8 ถง 10 เปนตน ดงนนเรากตองมการสรางฟอรมเพอรอรบขอมลทไดทำาการเลอกแลวนำามาพมพ ออกในรายงาน ตวอยางทจะกลาวตอไปนเปนเพยงแนวทางทจะใหทานสามารถนำาไปประยกตใชงานในดานอนๆ ไมเพยงแตรายงานอยางเดยวการทำางาน จะแสดงรายการทงหมดทฟอรมแลวใหทำาการ เลอกรายการโดยกดปม Shift หรอปม Ctrl คางไวแลวลากแถมแสงคลมรายการทตองการ จากนนกสงใหโปรแกรมพมพรายงานออกมาตามขอมลทไดเลอกเอาไว ซงการเลอกขอมลตางๆเกบไวเราจะอาศยตวแปรอะเรยเปนตวชวยในการเกบขอมล แลวนำาขอมลนนมาเปนเงอนไขในการออกรายงาน
187
1. ใหทำาการสรางรายงานกอนโดยพมพคำาสงท command window ดงน CREATE REPORT CUSTRPT2 2. คลกเมาสปมขวาท report designer แลวเลอก Data Environment 3. คลกเมาสปมขวาท Data Environment แลวเลอกตาราง Customer จากนนกคลกทปม Close 4. คลกท report designer จากนนคลกทเมน Report แลวเลอกรายการ Quick Report เมอสรางรายงานเสรจกทำาการ save รายงาน 5. ใหสรางฟอรมโดยพมพคำาสงท command window ดงน CREATE FORM CUSTRPT2 6. ท Form Designer ใหคลกทเมน Form เลอก New Property พมพทชอง Name วา AChosen[1] จากนนกคลกปม Close 7. ใหนำา List Box จาก Form Control มาใสไวใน Form แลวกำาหนด properties ดงน RowSourceType = 2 RowSource = Customer ColumnCount = 2 ColumnWidths = 50,250 MultiSelects = .T. Name = LStcust_id 8. สราง Command Button แลวกำาหนด properties ดงน Caption = Run Report Click Event ปอนคำาสงดงนlnCounter = 0DIMENSION ThisForm.achosen[ThisForm.lstCust_id.ListCount]WITH ThisForm
188
FOR i = 1 TO .lstCust_id.ListCountIF .lstCust_id.Selected(i)lnCounter = lnCounter + 1.achosen[lnCounter] = .lstCust_id.List[i]ENDIFENDFORENDWITHIF lnCounter = 0WAIT WINDOW "No Records Chosen !"ELSEDIMENSION ThisForm.achosen[lnCounter]REPORT FORM CustRpt2 FOR ASCAN(ThisForm.achosen,cust_id) > 0 PREVIEWENDIFจากนนกทำาการ Save แลวลองเรยกขนมาใชงานด...จะสงเกตไดวาการเลอกรายการมาพมพนนเราใชตวแปรอะเรยมาเปนเงอนไขในการเลอกขอมล เมอคณเขาใจการใชงานตวแปรอะเรยนแลวกนำาไปไชงานอยางอนไดอกนะจะบอกใหรายงาน กบ การพมพในอดตกาลทผานมา ถาทานผอานไดเคยสมผสกบ FoxPro for DOS มากอนการกำาหนดลกษณะการพมพใหกบรายงานนนจะไมยงยากเหมอนกบ Visual FoxPro เชนถาเราจะกำาหนดขนาดของหนากระดาษ กำาหนดจำานวนบรรทดตอหนาทจะพมพ เรากสามารถทจะกำาหนดไดใน report designer นนไดเลย หรอจะกำาหนดระยะหางระหวางบรรทดเรากใชคำาสง Escape Code ของเครองพมพกไดอก หรอถาจะทำารายงานแบบพศดาลกเขยนโปรแกรม .PRG ขนมาเองเลย แตพอมายค Windows วธการดงกลาวทานจงลมไปไดเลย นำามาใช บ ได ทนเรากมาเขาเรองของ Visual FoxPro ทละเรอง แลวคอยรวมเลมอกท... ใน Visual FoxPro การจะกำาหนดคาของเครองพมพนนมนจะไปอง อะชตะกบ Printers ทกำาหนดไวใน windows เสมอ เชนถาเราตองการเปลยนแปลงขนาดของกระดาษกตองไปแกไขใน หนา
189
properties ของเครองพมพ หรอถามกระดาษทมขนาดไมเหมอนกบท Windows กำาหนดมาให ถาเราจะกำาหนดขนาดของหนากระดาษกตองไปกำาหนดท เมนใน Windows ท Start -> Setting -> Printer แลวคลกขวาเลอก Properties เพอเขาไปทำาการแกไขขนาดของกระดาษ ในสวนของแทป Paper แลวเลอกขนาดเปน Customs ดงภาพ
จะเหนไดวากวาจะทำาไดนนมนยงยากขนาดไหน หรอถาจะใหผใชกำาหนดเองตอนจะพมพรายงานแลวสงใหโปรแกรมแสดงหนาจอ printer setup ขนมาใหกำาหนดกสามารถทำาได (ยกเวนการกำาหนดขนาดแบบ custom) ถาเปนไปไดผมกอยากใหผใชออกรายงานโดยทไมตองมายงกบ printer setup เลยจะดกวา ถาอยากรวาจะทำาอยางไรตามมาเลยครบสำารวจรายงานกนกอน
190
เมอเราทำาการสรางรายงานขนมา Visual FoxPro จะจดจำาคาตางๆของเครองพมพทถกตดตงไวใน Windows แลวนำาคานนมาเกบมาไวในรายงานของเราดวยเสมอ ซงเราจะทำาการเปลยนแปลงคาตางๆโดยไมตองการแก properties ของ เครองพมพเราตองทราบตำาแหนงทเกบคาเหลานกอนวาเกบอยทแหงหนตำาบลใด โดยทำาดงนใหทำาการเปดไฟลรายงานขนมาโดยทำาดงน USE ชอรายงาน.FRX
เชน USE CUSTRPT2.FRX LOCATE FOR OBJTYPE = 1 AND OBJCODE = 53 BROWSEเมอคณทำาการ browse ดคณกจะเหนเรคคอรดททำาการเกบสถานะตางๆของรายงาน ซงกดไมรเรอง ใหคณทำาการ คลกเมาส 2 ครงท ฟลด Expr คณกจะพบกบคาทไวสำาหรบเซตคาของเครองพมพของรายงาน
จากภาพเปนสถานะของเครองพมพ Epson LQ-1050 ซงในรายงานของคณอาจไดคาทแตกตางจากนขนอยกบชนดของเครองพมพทใชอย
191
สงทเราจะตองแกไข เราตองแกไขทฟลด memo ของ Expr ทมเงอนไขเปน Objtype = 1 และ Objcode = 53 โดยการเปลยนแปลงคาไปเปนคาทเราตองการ แลวจะทำาอยางไรหรอครบ? ผมคงไมใหคณเขามาแกตรงนหรอกครบเดยวมนกเปลยอกถามใครไปแกรายงานแลว save รายงานนนคาของเครองพมพทไมพงประสงคจะกลบมาเยอนอกกอนอนคณตองรวาคาทแสดงเหลานหมายถงอะไรแลวเราจะทำาการเรยกคาเหลานจาก properties ของเครองพมพใน Windows ไดอยางไร? คำาสงตางๆทเราจะใชกนมดงนคำาสง GETPRINTER() เปนคำาสงทใชแสดงรายชอของเครองพมพ แลวใหเราทำาการเลอกเครองพมพทตองการและจะทำาการสงคาทเปนชอของเครองพมพทไดเลอกไว เชนcPrinterName = GETPRINTER()คำาสง APRINTER() เปนคำาสงทใชสรางตวแปรอะเรยแลวจะทำาการเกบชอของเครองพมพไวในตวแปรอะเรยทสรางขน เชนAPRINTER(cPrinter)คำาสง PRTINFO() เปนคำาสงทใชบอกถงคาของเครองพมพทใชอย ซงคาทไดมานเราจะสามารถนำามากำาหนดหรอเปลยนแปลงคาในฟลด Expr ของไฟลรายงานทเราจะทำาการแกไข โดยทคาทมอยจะมทงสน 13 ชนดคอ (ดรายละเอยดของคาทสงกลบมาใน help) PRTINFO(1) จะแสดงคาของ ORIENTATION PRTINFO(2) จะแสดงคาของ PAPERSIZE ถาคาเปน 256 ขนาดของกระดาษเปนแบบ custom PRTINFO(3) จะแสดงคาของ PAPERLENGTH เปนขนาดความยาวของกระดาษทกำาหนดเปนแบบ custom PRTINFO(4) จะแสดงคาของ PAPERWIDTH เปนขนาดความกวางของกระดาษทกำาหนดเปนแบบ custom PRTINFO(5) จะแสดงคาของ SCALE PRTINFO(6) จะแสดงคาของ COPIES
192
PRTINFO(7) จะแสดงคาของ DEFAULTSOURCE PRTINFO(8) จะแสดงคาของ PRINTQUANTITY PRTINFO(9) จะแสดงคาของ COLOR PRTINFO(10) จะแสดงคาของ DUPLEX PRTINFO(11) จะแสดงคาของ YRESOLUTION PRTINFO(12) จะแสดงคาของ TTOPTION PRTINFO(13) จะแสดงคาของ COLLATEคำาสง SET PRINTER TO เปนคำาสงทใชกำาหนดเครองพมพเพอใชออกรายงาน เชน SET PRINTER TO NAME (cPrinterName)หลงจากทคณไดทำาความเขาใจเกยวกบคำาสงขางตน (แบบงงงง) แลวผมจะขอยกตวอยางเพอใหลองศกษาแลวนำาไปประยกตใชเองด อาจจะสรางไฟล .DBF เกบคาตางๆไว หรอใช text file เกบคาไวกได แลวสรางฟงกชนขนมาจดการอกกได ...อนนกขนอยกนทานทงหลายแลวละครบ 1. ใหคณทำาการสรางรายงานขนมาดงน CREATE REPORT MYREPORT1 2. คลกเมาสปมขวาทตวรายงานแลวเลอก Data Environment... ทหนาตางของ Data Enviroment ใหคลกเมาสปมขวาเลอกรายการ Add.. เลอกไฟล customer.dbf จากนนกคลกทปม Close 3. คลกเมาสทรายงาน แลวเลอกเมน Report เลอก Quick Report... จากนนคลกปม OK 4. ทำาการ save รายงานโดยกดปม Ctrl-W 5. ทำาการสรางไฟลเพอเกบสถานะของการพมพ คณอาจจะสรางไฟลเปน .DBF หรอ text file กได ในตวอยางนจะของใหคณทำาการสรางโดยใช text file โดยทำาการพมพคำาสงท command window ดงน
193
MODIFY FILE MYPRINT จากนนทำาการพมพคาตางๆดงน DEVICE=Epson LQ-1050 OUTPUT=LPT1: PAPERSIZE=256 PAPERLENGTH=4162 PAPERWIDTH=1256 DEFAULTSOURCE=8 ทำาการ save โดยกดปม Ctrl-W คณกจะไดไฟลเกบสถานะการพมพชอ MYPRINT.TXT สงทผมกำาหนดไวประกอบดวย DEVICE จะเปนชอของเครองพมพทใชออกรายงาน ถาไมใสบรรทดนจะเปนการใชเครองพมพของ Windows ทเซตเปน Default ไว OUTPUT บอกถง output ของรายงาน PAPERSIZE กำาหนดขนาดของกระดาษ 256 คอ custom size ซงคณตองกำาหนดความกวางและยาวของกระดาษดวย PAPERLENGTH กำาหนดความยาวของกระดาษมหนวยเปน n x .01 ซม. เชน 1200 * .01 = 12 เซนตเมตร PAPERWIDTH กำาหนดความกวางของกระดาษ DEFAULTSOURCE กำาหนดเปน 8 คอใช tractor feedสวนคาอนๆทจะเซตกตามสบาย กระดาษตามแนวนอนเซตอยางไร? 6. เมอเราทำาสงตางเปนทเรยบรอยเราตองเขยนคำาสงควบคมการทำางานอกท โดยการสรางโปรแกรม .PRG ดงน MODIFY COMMAND MYPRINT ทำาการปอนคำาสงดงน SET PRINTER TO NAME Epson LQ-1050 && กำาหนดเครองพมพทจะใชพมพรายงาน ชอทกำาหนดอาจเปนชอ network printer กได USE MYREPORT1.FRX LOCATE FOR OBJTYPE = 1 AND OBJCODE = 53 REPLACE Tag WITH "" , Tag2 WITH "" &&
194
เปนการลางคาของ printer ทรายงานเซตไว APPEN MEMO Expr FROM MYPRINT.TXT OVERWRITE && นำาคาทกำาหนดไวมาใสไวในรายงาน USE REPORT FORM MYREPORT1 PREVIEW && TO PRINT ทำาการ save แลวลองเรยกโปรแกรมดวาเกดอะไรขน เสรจแลวคณลองแกไข text file ทเกบคาทใชกำาหนดสถานะการพมพแลวลองเรยกรายงานดวาเกดการเปลยนแปลงอยางไร?การกำาหนดให PRIN PERVIEW มขนาดใหญคบจอ(ใชไดกบ VFP 6 ขนไป)ลกษณะทวไปของ Visual FoxPro นนถาเราทำาการกำาหนดขนาดของหนาตาง ทลบาร หรอสงตางๆ ทาง VFP จะเกบคาเหลานนไวในไฟล foxuser.dbf ให พอเวลาเราทำาการเรยกใชงานครงตอไป VFP กจะจำาสงเหลานนไดเชนเดยวกนถาเรากำาหนดขนาดของ preview ใหใหญเตมจอ ครงตอไปเมอเขาส VFP การ preview กจะมขนาดเตมจอเหมอนครงกอนตวอยางนจะเปนการสรางหนาตาง preview รายงานแบบเตม Windows ครบทานผชม 1.ใหคณสรางฟอรมขนมา ดงน CREATE FORM MYPREVIEW 2. กำาหนด Property ดงน TitleBar = 0 Name = MyPreview ShowWindow = 2 WindowState = 2 จากนนกทำาการ Save 3. ทโปรแกรมสำาหรบพมพรายงานใหใสคำาสงดงน .... DO FORM MYPREVIEW NAME MYPREVIEW
195
REPORT FORM MYREPORT1 PREVIEW IN WINDOWS MYPREVIEW MYPREVIEW.RELEASE ....จากนไปกจะใหญคบจอ.... Version ตำากวานลองแลวไมผาน ตองใช คำาสง KEYBOARD '{CTRL+F10}' แทนตรงคำาสง DO FORM... การใชงาน Project Managerอาจชาไปบางสำาหรบเรองวธการใชงาน Project Manager ซงบางทานถาทราบอยแลวกผานไปได ไมตองอานกได ในบทนจะเปนการแนะนำาการใชงานเทานนเอง ขอยำาเฉพาะมอใหมในสมยกอนนนเราใชงาน Foxbase รนแรกๆ เรากทำาการสรางองคประกอบตางๆเชน โปรแกรม ฐานขอมล รายงาน เมน กนเองซง Foxbase รนแรกๆไมมเครองมอในการจดการ บางทานกใชวธการสราง sub-directory เพอทำาการการจดหมวดหม แยกแยะวากลมนเปน ขอมล กลมนเปนโปรแกรม เปนตน ตอมาพอมาถง รนทเปน FoxPro กเกดสงอำานวยความสะดวกนขนมา ซงกเรยกวา catalog manager ผมเขาใจวาคงเรยนแบบ dBASE IV มากกวา ตอมาใน Visual FoxPro กมเหมอนกนแตเปนชอเสยใหมเปน Project Manager ผมวาชอนแหละเหมาะสมด ซงตวนแหละเปนตวจดการในการทำางานของเราตงแตเรมตน จนจบถงขนสรางระบบงานแลวนำามนไปแจกจายใชงาน การสราง Project1. ท เมน File ใหเลอก New2. ทำาการเลอก Project แลวเลอก New File3. ใน Create dialog box ในชอง Enter ปอนชอโปรเจกทตองการ 4. คลกปม Save
196
หรอท Command Window ปอน คำาสง CREATE PROJECT ชอโปรเจก
เรามาดองคประกอบกนกอนใน Project Manager จะแบงหมวดหม (Categories) เปน 5 ชนด คอ Data จะเปนตวจดการเกยวกบ ฐานขอมล(database) ตาราง(free table) ควร(query)Documents เปนตวจดการเกยวกบ ฟอรม(form) รายงาน(report) ฉลาก(label)Classes จะเปนตวจดการ คลาส(Visual Class Library)Code จะเปนตวจดการ โปรแกรม(program) API Library Application Other จะเปนตวจดการ เมน(menu) Text File Other File เชน รปภาพตอมาในสวนของปมคำาสง จะประกอบไปดวยNew ใชสำาหรบสรางไฟลใหม อนนขนอยวา ขณะนนคณอทหมวดไหนของ project
197
Add เปนการนำาไฟล ทมอยแลวมาเพมไวใน project Open เปนคำาสงเปดฐานขอมล(open database) Close เปนคำาสงปดฐานขอมล(close database)Modify เปนการแกไขไฟลRun เปนการสงใหไฟลนนทำางาน ถาอยในสวนของ data จะเปนปม browse ซงเปนการขอดขอมลในตารางRemove เปนการนำาไฟลนนออกจาก project หรอ ทงนำาออกและลบออกกไดBuild เปนปมสราง application ทสามารถนำาไปใชงานไดเลยปมคำาสงขางตนจะเปลยนแปลงไปตาม categories ทเราใชงานอยขณะนนเรามาดกนซวา Project Manager มอะไรใหเราทำาไดบางใหคณทำาการเรยกโปรแกรมตวอยางทผมใหไปไวลองศกษามาดกนกอน โดยพมพคำาสงดงน MODIFY PROJECT MYPROJECTการ build project เปน .EXE ไฟล ขนตอนการ build project เปน .EXE ไฟลนนกอนอนเราตอง set main โปรแกรมใน project manager กนกอน ใหทำาดงน (ผมไดสราง ไฟลชอ main.prg ไวเพอใชสำาหรบ set main)1. ใหทำาการคลกแทป Code ใน Project Manager 2. ใหทำาการคลกตรง + (บวก)ทอยหนา Program (ถาเปน -(ลบ) กไมตองคลก)3. จากนนใหคลกปมขวาของเมาส ทแฟม main แลวทำาการคลกทคำาสง set main (วธสงเกตวาแฟมนนๆไดถก set main หรอยงถามเครองหมาย อยดานหนาคำาสงแสดงวาไดทำาการ set main เรยบรอยแลว ในกรณทเราไดทำาการ set main อยแลวแลวไปคลกซำาจะถอวาเปนการยกเลกการ set main) ตอมากทำาการ build project ใหเปนไฟล .EXE โดยการคลกทปม Build... เลอก Build Excutable ในสวนของ Option ของ
198
dialog box Build Option จะประกอบไปดวย Recompile All File จะเปนการ compile โปรแกรมทงหมดกอนทจะทำาการ build Display Error ใหทำาการแสดง ขอผดพลาดออกมา ในขณะทำาการ build Run After Build ใหทำาการเรยกเรยกระบบงาน ขนมาทำางานหลงจาก build เสรจ ใหคณทำาการ เลอก Recompile All File ,Display Error แลวคลกทปม OK เมอโปรแกรมทำาการ Build Excutable เสรจคณกสามารถทจะทำาการเรยกระบบงานนนๆภายใตโปรแกรม windows ไดเลยการกำาหนด Project Infromation ใน Project Manager เราสามารถทจะกำาหนด information ของโปรเจกของเราไดโดย การคลกปมขวาท Project Manager แลวเลอก Project Info... จากนนเราจะไดพบกบ Project Infomation dialog box
เรามาดในสวนของ แทป Project วาทำาอะไรไดบาง
199
สวนแรกจะเปนการกำาหนด information ตางๆของคณ คณสามารถปอนไดตามสบายสวนตอมา จะประกอบดวย Home เปนการกำาหนด default directory Last Built บอกวนททำาการ build ครงสดทาย File บอกจำานวนไฟลทมอยใน project Debug Info เปนการกำาหนดใหสามารถ debug โปรแกรมไดหรอไม Encrypted กำาหนดใหทำาการเขารหสเมอทำาการ compile Attach Icon กำาหนด icon เพอใชแทน icon รปหมาจงจอก เมอทำาการคลกแลว คณสามารถนำา icon ทตองการมาใสไวไดโดยการคลกทปม Icon... จากนนคณกนำา ไฟล icon ทคณตองการมาใสไวทชอง File Name
แนะนำา คณสามารถสราง Icon ขนเองไดโดยใชโปรแกรม
200
IMAGEDIT.EXE ซงเกบอยใน directory ./IMAGEDIT ภายใต directory ของ Visual FoxPro เคลดไมลบ คณสามารถลดขนาด application ททำาการ build โดยการ ไมกำาหนดใหมการ debug ใหทำาการคลกท Debug Info เพอทำาใหเปนชองวางสวนของ แทป Files
เมอเราทำาการคลก แทป Files ใน Project Information คณกจะไดพบกบไฟลทงหมดทมอยใน project ในสวนนจะประกอบไปดวย Type จะบอกประเภทของ ไฟลนนๆ จะแสดงเปนลษณะของ icon Name แสดงชอ ไฟล Last Modified แสดงวนทปรบปรงครงสดทาย Include ในสวนนเปนตวกำาหนดวาในการ build จะนำาไฟลเขามารวมไวใน application ทไดทำาการ build ดวยหรอไม คณสา
201
มารถคลกในสวนนไดเลยเพอบอกให project ทราบ ถาม X(กากบาท) แสดงวาใหนำามารวมไวใน application ถาเปนชองวาง ไมนำาไฟลนนมารวมใน application ถาเปนสทบ เปนการแสดงใหทราบวาไฟลนนเปนโปรแกรมหลกในการ build (set main) ** ถาคณสงเกตใหด ไฟลทเปน ฐานขอมลจะไมกำาหนดใหเปน Include เพราะเนองจากขนาดของไฟลจะมการเปลยนแปลงอยเสมอ Code เปน code page ประเทศไทยใช 874ปญหาชวนหวฉนจะทำาอยางไรด ตอนสรางฟอรมแลวกำาหนด ตารางฐานขอมลใน DataEnviroment แลวตอมาตองทำาการยายฐานขอมลไปอย directory อน ? เมอเผลอไป zap ขอมลอนเปนสดทรก ( โอลลลลล ... ลาาาา ) จากๆๆๆๆ สรางฟอรมแลวกำาหนด ตารางฐานขอมลใน DataEnviroment แลวตอมาตองทำาการยายฐานขอมลไป อย directory อน ? สำาหรบทานทสรางฟอรมโดยใช DataEnvironment เพอกำาหนดตาราง วว และความสมพนธตางๆ เพอใชในฟอรม ตอนสรางมนจะจำา path ของ directory นนไวเมอเรานำาโปรแกรมทสรางเสรจแลวไปแจกจายแลวเปลยน directory เปนชอใหม หรอเขยนโปรแกรมบน Drive C: แลวเปลยนใจอยากจะทำาระบบเปนแบบ Client Access โดย กอบป เฉพาะฐานขอมลไปไวท LAN สวนโปรแกรมกไวท Drive C: ซง directory ตอนแรกกบหลงจากยายแลวไมตรงกนเปนตน หรอทำาอยางไรกได ททำาใหมนเกด error ตามภาพดานลางน
202
แสดงวาฟอรมนนหา ฐานขอมลชอ mydatabase.dbc ไมเจอ .... แลวเราจะจดการกบมนอยางไรดละ?การแกปญหาทเกดขน เราตองสามารถทจะกำาหนด direve และ path ใหกบฟอรมตางๆทเราสรางขนมาไดเอง โดยทำาดงน 1. ในกรณทเราตองการเปลยน drive และ path โดยไมตองการยงกบโปรแกรม กใหสรางไฟล ทมนามสกล .H (header file) เชน MyApp.H โดยใช Text Editor อะไรกได หรอจะใชคำาสงท command window กได โดยพมพดงน MODIFY COMMMAND MYAPP.Hจากนนกปอนคำาสงดงน
แลวทำาการ save ไฟลน โดยกดปม Ctrl-W 2. เมอคณทำาการสรางฟอรมขนมา แลวทำาการ กำาหนดตารางในสวนของ DataEnvironment ใน Form Designer แลว ใหคณทำาการคลกเมาสปมขวาท DataEnviroment ทำาการเลอก Properties... (จะมสกกฟอรมกตองทำาจะ) 3. คลกทแทป Method แลว คลกสองครงท BeforeOpenTabel
203
จากนนกทำาการปอนโปรแกรมดงตอไปน#INCLUDE MYAPP.HIF !EMPTY(DATA_PATH) and !EMPTY(DATA_DRIVE) =AMEMBERS(A_Cursors,THISFORM.dataenvironment,1) =ASORT(A_Cursors, 2) nStartpos=ASUBSCRIPT(A_Cursors, ASCAN(A_Cursors, "Object"),1) FOR I = nstartpos TO ALEN(A_cursors,1) IF A_Cursors(i,2) = "Object" cObjClass = "THISFORM.DATAENVIRONMENT."+a_cursors(i,1)+".class" IF EVAL(cObjClass)="Cursor" cObjName="THISFORM.DATAENVIRONMENT." ; + A_Cursors(i,1)+".DATABASE" Data_Name=EVAL(cObjName) NewDataPath=ALLTRIM(data_drive)+ ALLTRIM(data_path) ; + ALLTRIM(SUBSTR(Data_Name, RAT("\",Data_Name)+1)) oRef =
204
EVAL( "THISFORM.DATAENVIRONMENT."+a_cursors(i,1) ) oRef.Database = newdatapath ENDIF ELSE EXIT ENDIF ENDFORENDIF 4. หลงจากนตอไป เมอคณตองการทจะเปลยน directory หรอ path กสามารถทำาไดโดยการแกทไฟล MYAPP.H กพอ การนำาขอมลกลบหลงจากทได zap ไปแลว สเทายงรพลาด สองเทาทสวมใส บาจา กตองมเพลยงพลำากนบาง ดวยเหตผลกลใดไมทราบเมอทานพมพสามตวอกษรสงหาร (ZAP) โดยไมตงใจแตนวมนพาไป ตอไปนทานไมตองมานงนำาตาตกหรอเหงอตกอกตอไป เรามฟงกชน UNZAP มานำาเสนอ.... มงกรทองใหเสยง ชอวลวเฮยงนำาแสดงFUNCTION UNZAP PARAMETER nRECORD IF nRECORD>0 .AND. USED() IF RECCOUNT()=0 FILENAME=DBF() USE HANDLE=FOPEN(FILENAME,2) IF HANDLE>0 BYTE=FREAD(HANDLE,32) BKUP_BYTE=BYTE FIELD_SIZE=ASC(SUBSTR(BYTE,11,1))+(ASC(SUBSTR(BYTE,12,1))*256) FILE_SIZE=FSEEK(HANDLE,0,2) BYTE8=CHR(INT(nRECORD/(256*256*256))) BYTE7=CHR(INT(nRECORD/(256*256))) BYTE6=CHR(INT(nRECORD/256))
205
BYTE5=CHR(MOD(nRECORD,256)) BYTE=SUBSTR(BYTE,1,4)+BYTE5+BYTE6+BYTE7+BYTE8+SUBSTR(BYTE,9) =FSEEK(HANDLE,0) =FWRITE(HANDLE,BYTE) =FCHSIZE(HANDLE,FILE_SIZE+(FIELD_SIZE*nRECORD)) =FCLOSE(HANDLE) ENDIF USE &FILENAME ENDIF ELSE WAIT WIND "ERROR CANNOT UNZAP....." ENDIFRETURNวธใช USE CUSTOMER ZAP =UNZAP(100) การทเราจะ UNZAP ขอมลเกากลบมานนเราจำาเปนตองทราบจำานวนเรคคอรดทมอยทงหมดของไฟลนนๆกอน แตถาทานไมทราบกใหประมาณจำานวนเรคอรดแลวใสตวเลขเขาไปกอน เมอทำาการ UNZAP เรยบรอยกจะไดขอมลเทากบจำานวนเรคคอรดททานไดใสเขาไป จากนนกทำาการ BROWSE ดวา เรคคอรดสดทายทเปนขอมลจรงๆ เปนเรคคอรดทเทาไหร (ถดจากนนจะเปนขยะ) เมอไดจำานวนเรคคอรดทเปนจรงแลว กใหทานกลบไป ZAP ขอมลนนใหมอกครง แลวก UNZAP ตามจำานวนเรคคอรดทเปนจรง.... ZAP ไมใชปญหาแตปญหามกลนตดจาน มสารตกคางตองใช ไลปอนเอฟ (เอ...ไดคาโฆษนาหรอเปลาเนย) การสราง HELPสวนชวยเหลอ(Help) เปนสวนหนงทไดถกพฒนามาอยางตอเนอง ในยคแรกทยงใช DOS เปนระบบปฎบตการจะเปนแบบ .DBF-
206
Style Help พอเรมเขามาสในยคของ Windows กไดเปลยนมาเปนแบบ Graphical Help ครนเขาสยคของ Internet กไดเกดม HTML Help ซงกคอ help ทสรางโดยใชภาษา HTML(Hypertext Markup Language) สำาหรบหนงสอเลมนจะอธบายการสรางสวนชวยเหลอในแบบ HTML Help กอนททานจะทำาการสรางสวนชวยเหลอไดนนจำาเปนจะตองมโปรแกรมทใชในการสรางกอน ซงเราไมสามารถสรางโดยใชโปรแกรม Visual FoxPro ไดโดยตรง สำาหรบโปรแกรมทเราจะใชมชอวา HTML Help Workshopการ Setup โปรแกรม HTML Help Workshop ทำาการใสแผน CD โปรแกรม Visual FoxPro 6 ลงใน CD-Rom Drive แลวคลกทปม Start จากนนทำาการคลกท Run ใหปอนคำาสงดงน
ทำาการ setup โปรแกรมตามขนตอนทกำาหนด
คณสามารถ Download โปรแกรม HTML Help Workshop ไดท เวปไซด http://msdn.microsoft.com/workshop/author/htmlhelp/htmlhelp.exe
ทำาการ Setup ดงตอไปน
207
208
209
คลกปม Next โปรแกรมกจะทำาการ Install โปรแกรม HTML Workshop ลงสเครองคอมพวเตอรจนเสรจการสราง HTML Helpในการสราง HTML Help จะมขนตอนในการสรางดงนคอ สรางเอกสารทอยในรปของไฟล Hypertext Markup Language (HTML) สราง Help Project สราง Table of Contents (TOC) หรอสารบญ สราง Help Index (ดขน) สรางเอกสารทอยในรปของ ไฟล Hypertext Markup Language(HTML) เนอหาของ Help ทเราจะทำาการสรางขนมาจะประกอบไปดวย ไฟล .HTM หรอ .HTML เปนหลก คณสามารถทจะสรางเอกสารเหลานไดโดยใชโปรแกรม Microsoft FontPage หรอโปรแกรมทใชสรางเอกสาร HTML อนๆ กได วธการสรางเอกสารเพอใชเปนเนอหานนใหคณสรางเปนไฟลยอยๆตามหวขอของ Table of Contents (สารบญ) เชน ถาคณมสารบญทงหมดอย 10 หวขอ กใหคณทำาการสรางเปนไฟล HTML ตามจำานวนหวขอของสารบญ เปนตน หรออาจจะสรางไวมากหรอนอยกวากได (ในทนจะไมขออธบายวธการ
210
สรางไฟล HTML) เมอทำาการสรางเปนทเรยบรอยแลวกทำาขนตอนตอไปคอการสราง Table of Contents สราง Help Project Help Project จะเปนตวทใชจดการในเรองของการสรางสวนชวยเหลอ ซงกจะคลายกบ Project ในโปรแกรม Visual FoxPro ใหคณทำาการสรางโปรเจกขนมาดงน ทำาการเรยกโปรแกรม HTML Help Workshop ขนมาแลวคลกทเมน File จากนนคลกทรายการ New ท New dialog box เลอก Project แลวคลกปม OK
จากนนเราจะเขาส New Project Wizard ซงเปนเครองเมอทชวยอำานวยความสะดวกในการสรางโปรเจก ท dialog box ของ New Project ใหคณคลกปม Next ท dialog box ของ New Project – Destination ใหคณตงชอของโปรเจกทคณจะทำาการสรางขนมา ใหคณกำาหนดชอเปน MYHELP แลว คลกทปม Next
211
ท dialog box ของ New Project – Existing Files จะเปนสวนทใชในการกำาหนดไฟลตางๆทมอยแลวนำามาใสไวในโปรเจก HTML Help table of contents (.hhc) กำาหนดใหนำาไฟล TOC ทมอยแลวนำามารวมไวในโปรเจกHTML Help Index (.hhk) กำาหนดใหนำาไฟล ดชน ทมอยแลวนำามารวมไวในโปรเจกHTML File (.htm) กำาหนดใหนำาไฟล HTML ทมอยแลวนำามามารวมไวในโปรเจกในหนานใหคณคลกปม Next ไปกอนโดยไมตองทำาการคลกทรายการใดๆ
212
ท dialog box ของ New Project – Finish ใหคลกปม Finish หลงจากนนเรากจะได โปรเจก MYHELP ดงภาพ
คณสามารถทจะนำานำาไฟล HTML ทสรางไวกอนหนานมารวมใน โปรเจกไดโดยการคลกทปม (Add/Remove topic Files) จากนนกจะขน dialog box ของ Topic Files ใหคณทำาการคลกทปม Add เพอนำาไฟล HTML มารวมไวในโปรเจก ดงภาพ แลวคลกปม OK
213
สราง Table of Contents(TOC) Table of Contents เปนหวขอทใชในการเขาถงเนอหาของ help ซงกเหมอกบสารบญของหนงสอ มขนตอนในการสรางดงน ทำาการคลกทแทป Contents จากนนใหทำาการเลอกรายการ Create a new contents File แลวคลกปม OK ใหทำาการปอนชอไฟล contents ทสรางขนใหมวา MYTOC แลวคลกปม OK จากนนเรากจะเขาสสวนของการสราง Table of Contents ทำาการกำาหนด Heading โดยคลกทปม (Insert a heading)จากนนเราจะเขาสในสวนของ Table of Contents Entry ทแทป General ในชอง Entry title: เปนสวนทใหกำาหนดขอความทจะแสดงในสวนของสารบญ ใหทำาการปอน “เรยนเขยนโปรแกรม Visual FoxPro” (ไมตองพมพเครองหมาย “) จากนนใหคลกทปม OK ตอมากทำาการกำาหนดรายการของสารบญโดยทำาการคลกทปม (Insert a page) โปรแกรมกจะถามวา
ใหคลกทปม No เพอเพมรายการตอจาก Heading ทไดสรางไวกอนหนาน ทแทป General ในชอง Entry title: ใหปอน “เรมตนกบ Visual FoxPro” จากนนให คลกปม Add ในสวนของ Path or URL ทชอง File or URL: ใหกำาหนดชอไฟล HTML ทเราตองการ เชน TOPIC1.HTM แลวคลกทปม OK สองครงจากนนจะได TOC ดงภาพ
214
ในกรณทมรายการอนๆอกใหยอนกลบไปทำาตามในขอ 3-6 แลวแตกรณ การกำาหนดรป Icon ใหกบรายการใน TOC ใหเขาไปทำาการแกไขรายการทตองการ ใหเลอนแถบแสงไปทรายการ “เรยนเขยน
โปรแกรม Visual FoxPro” แลวคลกทปม (Edit Selection) คลกทแทป Advance ในชอง Image Index กำาหนดคา เปน 5 (Icon รป folder) จากนนคลกปม OK ตอมาใหคณกำาหนด Icon ใหกบรายการ “เรมตนกบ Visual FoxPro” โดยกำาหนดคาใหกบ Image Index เปน 1 (Icon รป หนงสอ) คณสามารถทจะลบรายการใน TOC ไดโดยการคลกทปม (Delete Selection) Help Index (ดชน) Incex (ดชน) เปนสวนททำาใหผใชงานสามารถเขาถงเนอหาของ Help ไดอยางรวดเรว ในขณะทคณกำาลงใชงาน Help อยคณสามารถทจะปอนคำาทตองการคนหาในสวนของแทป Index เมอพบคำาทตรงกบทปอน โปรแกรม Help กจะแสดงรายการทมคำาทเราไดกำาหนดไวตอนสราง Help Index ออกมา ซงเราสามารถทจะ คลกเขาไปดในรายการนนๆได มขนตอนในการสรางดงน ทำาการคลกทแทป Index จากนนใหทำาการเลอกรายการ Create a new Index File แลวคลกปม OK
215
ใหทำาการปอนชอไฟล Index ทสรางขนใหมวา MYINDEX แลวคลกปม OK จากนนเรากจะเขาสสวนของการสราง Index ซงจะมลกษณะคลายกบการสราง Contents ใหคลกทปม (Insert a keyword) จากนนเราจะเขาสในสวนของ Index Entry ทแทป General ในชอง Keyword: เปนสวนทใหกำาหนดขอความ(keyword) ทจะแสดงในสวนของดชน ใหทำาการปอน “Visual FoxPro” (ไมตองพมพเครองหมาย “) จากนนใหคลกทปม Add ในสวนของ Path or URL ทชอง File or URL: ใหกำาหนดชอไฟล HTML ทเราตองการ เชน WELCOME.HTM แลวคลกทปม OK ถาในกรณท keyword ทเรากำาหนดไวมการอางถงในไฟล HTML มากกวาหนงไฟล กใหคลกปม Add เพอทำาการเพมไฟล HTML เขาใน Keyword ไดอก กำาหนดขอความไตเตลใหกบ Helpคณสามารถทจะทำาการกำาหนดขอความใหแสดงบนไตเตลบารใหกบโปรแกรม help ของคณไดโดยการคลกทแทป Project แลวคลกทปม (Change Properties Options) ทำาการปอนขอความทชอง Title: ในสวนของ แทป General จากตวอยางใหคณปอนคำาวา “เรยนเขยนโปรแกรม Visual FoxPro”กำาหนดไฟลเพอแสดงตอนเรมเรยก Helpเมอทำาการเรยกโปรแกรม help ขนมาแลวเราสามารถทจะกำาหนดใหแสดงไฟล HTML ตอนเรมตนแสดง help ไดโดยเขาไปกำาหนดในสวนของ Project แลวทำาการ Change Properties Option เลอกแทป General ในชอง Default File: ใหกำาหนดไฟลทตองการแสดงตอนเรมเรยก helpกำาหนดใหมแทป Search ใน Helpในการสราง help นนเราสามารถทจะกำาหนดให help ของเราสามารถทจะคนหา (Search) คำาหรอขอความใดๆกได โดยการเพม
216
แทป Search ไวในโปรแกรม help จากเดมทจะมเฉพาะแทป Contents และ แทป Index ไดโดยการเขาไปกำาหนดในสวนของ Project แลวทำาการ Change Properties Option คลกทแทป Compiler แลวคลกทชอง Compile full-text search informationCompile HTML Help Fileกอนทคณจะนำาโปรเจกทไดสรางไวไปใชงานไดคณตองทำาการ Compile โปรเจกนนกอนโดยการคลกทปม (Compile HTML file) จากนนทำาการกำาหนดไฟลโปรเจกทตองการจะ Compile โดยกำาหนดในชอง Project file: และถาตองการทจะแสดง help ไฟลหลงจากททำาการ compile แลวกใหคลกทชอง Automatically display compiled help file when don ดงภาพ
การเรยกใชงาน Help ในโปรแกรม Visual FoxProเมอไดทำาการ compile โปรแกรม help เรยบรอยแลวเราจะไดไฟลทมนามสกล .CHM (MYHELP.CHM) คณสามารถทจะเรยกใชงาน help ไดโดยการเรยกโปรแกรมนท Windows ไดทนท แตสำาหรบจดประสงคในบทเรยนนคอการเรยก help ภายใตโปรแกรม Visual FoxPro คณสามรถทำาไดโดยการปอนคำาสงท
217
Command window ของ Visual FoxPro ดงน
เมอทำาการกดปมฟงกชน F1 ทแปนพมพกจะปรากฎ help ทเราสรางขนมา ในกรณทตองการตองการยกเลกการแสดง help ทไดทำาการสรางขนมา โดยใหกลบไปเปน help ของ Visual FoxPro ตามเดมใหปอนคำาสงดงน
Context-sensitive HelpContext-sensitive คอการอนญาตใหผใชงานสามารถทจะเขาถงในสวนตางๆของ help ไดโดยตรง โดยการคลกทปมเครองหมายคำาถามบนฟอรม แลวกทำาการคลกในฟอรม ณ. สวนของวตถทตองการแลวโปรแกรมกจะทำาการแสดง help ในสวนนนๆขนมาหลกและวธการเรยก Context-sensitive Help
หลกการของ Context-sensitive Help นนเมอเราทำาการคลกทปมเครองหมายคำาถามบนฟอรมแลวนำาไปคลก ณ. ตำาแหนงทตองการ กอนทโปรแกรมจะแสดง help ขนมานนมนจะไปนำาคาของ WhatsThisHelpID ทกำาหนดไวในสวน Properties ของวตถ ซงจะมคาเปนตวเลข (คานเราจะเปนผกำาหนดเองตอนสรางฟอรม) จากนนโปรแกรมกจะไปหาคาตวเลขทตรงกบคาของ WhatsThisHelpID ทไฟลเฮดเดอร ตอจากนนกจะนำาคาคงททได
218
จากไฟลเฮดเดอรมาคนหาในสวนของ [ALIAS] ใน help ถามตรงกนกจะแสดง help ของสวนนนๆขนมาวธการสราง Context-sensitive Help ใหทำาการสราง Header File ขนมาโดยตงชอวา MYMAP.H โดยพมพคำาสงท Command Window ของ Visual FoxPro ดงน MODIFY FILE C:\MYHELP\MYMAP.H จากนนทำาการปอนคำาสง
ทำาการบนทกไฟลโดยกดปม Ctrl+W#DEFINE TOPIC1 1 เปนการกำาหนดคาคงท 1 ใหกบตวแปร TOPIC1 ใหทำาการเรยกโปรแกรม HTML Help Workshop แลวเปดไฟล
MYHELP.HHP ขนมาแกไข ทแทป Project ใหคลกปม
219
HtmlHelp API Information
ทแทป Map ใหคลกทปม Header File… ใหปอนชอไฟลทไดสรางไวในขอ 1 คอ MYMAP.H แลวคลกปม OK ใหคลกทแทป Alias เพอกำาหนดไฟล HTML ใหกบตวแปร โดยคลกทปม Addจากนนทำาการปอนคาตวแปรใหตรงกบทไดกำาหนดไวในเฮดเดอรไฟล แลวกำาหนดชอไฟล HTML ทตองการใหแสดง ดงภาพ
220
ใหทำาการกำาหนดคาใน Alias ใหเทากำาทไดกำาหนดคาไวในเฮดเดอรไฟล ดงภาพ
จากนนทำาการ Compile HTML Help File การนำา Context-sensitive Help ไปใชในฟอรม ใหทำาการสรางฟอรม โดยพมพคำาสงท Command Window ของ Visual FoxPro ดงน MODIFY FORM FORMHELP ใหทำาการสรางฟอรม ตามตวอยางดงภาพ
กำาหนด Properties ของ Form ดงน
221
WhatsThisButton = .T.WhatsThisHelp = .T.กำาหนด Properties ของ Command1 ดงน Caption = Topic1WhatsThisHelpID = 1กำาหนด Properties ของ Command2 ดงน Caption = Topic2WhatsThisHelpID = 2กำาหนด Properties ของ Command3 ดงน Caption = Topic3WhatsThisHelpID = 3กำาหนด Properties ของ Command4 ดงน Caption = Topic4WhatsThisHelpID = 4กำาหนด Properties ของ Command5 ดงน Caption = Topic5WhatsThisHelpID = 5ทำาการบนทกฟอรมแลวเรยกฟอรมขนมาใชงานโดยกดปม Ctrl+E คณกจะได Help ตามความประสงค .... การใชงาน Window APIWindow API เปนฟงกชนภายนอกชนดหนงทมมาพรอมกบระบบปฎบตการ Windows ทเราใชกนอยอยางแพรหลายในขณะน ซงกคลายๆกบฟงกชนของ Visual FoxPro อนทจรงแลวฟงกชนภายนอกตางๆนนมอยมากมายทถกสรางขนมา ไมวาจะเปน Active X Control, ฟงกชนทสรางขนโดยใชภาษา C แลว Compile เปนไฟล .DLL (Dynamic Link Library) , Visual FoxPro External Library ไฟล .FLL ซงทงหมดทกลาวมานเราจะเรยกฟงกชนหรอโปรแกรมเหลานนวา API (Application Programming Interface) ทงสน มความจำาเปนดวยหรอทเราจะตองใชคำาสง Window API ?
222
ในการเขยนระบบงานหรอโปรแกรมขนนนเราไมจำาเปนตองเรยกใชงานฟงกชนของ Window API กได แตเพอเปนการเพมประสทธภาพของโปรแกรมหรอเมอโปรแกรมของคณตองมการตดตอระหวางระบบปฎบตการ คณกสามารถทำาการเรยกใชงานฟงกชนตางๆเหลานนไดตามความเหมาะสมสำาหรบระบบปฎบตการ Windows ไดเตรยมฟงกชน API ไวใหโดยจะบรรจอยภายใต System Directory ในรปของไฟลทมนามสกล .DLL ไฟลเหลานนไดแก Kernal32.DLL, Gdi32.DLL, User32.DLL, Mpr.DLL และ Advapi32.DLL เปนตนในระยะแรกๆผเขยนเคยประสบปญหาในการอานคมอคำาสง Windows API จากแหลงตางๆเทาทจะหาไดเนองจากรปแบบคำาสงและตวอยางการใชงานนนเขยนขนโดยใช ภาษา Visual Basic เปนหลก ไดแตนกในใจวาทำาไมทาง Microsoft ถงไมยอมยกตวอยางทเขยนในรปแบบของ Visual FoxPro บาง กเลยฉกคดไดวา Visual Baisc เปนลกแทๆของ Microsoft สวน Visual FoxPro เปนแคลกบญธรรม ใครจะสำาคญกวากน? แตพอทำาการเขยนฟงกชน API โดยใช Visual FoxPro กบเขยนฟงกเหลานนไดงายกวา Visual Basic อกครบทานการเรยกใชงานฟงกชนจากภายนอกคำาสงทใชในการเรยกใชงานฟงกชนจากภายนอก (ไฟลทมนามสกล .DLL) มรปแบบในการเรยกใชดงน DECLARE [cFunctionType] FunctionName IN LibraryName [AS AliasName] [ cParamType1 [@] ParamName1, cParamType2 [@] ParamName2, ...]การเรยกใชงานโดยใชคำาสง DECLARE จะเปนการรจสเตอร(Register) ฟงกชนให Visual FoxPro ทราบเทานน ยงไมไดเปนการเรยกใชงานจรง
223
ถาผมจะอธบายรปแบบคำาสงตอนนทานผอานทงหลายคงตองงงเปนแนแท (เหมอนผมตอนเรมใหมๆ ) ผมจะขอยกตวอยางการเรยกใชโดย Visual Basic แลวนำามาเปรยบเทยบกนด เผอทานไปพบเหนตวอยางการใชงานฟงกชนทเขยนดวย Visual Basic จะไดนำากลบมาเขยนใน Visual FoxPro ไดอยางสะดวกโยธนตวอยางการดงชอ User Name ในระบบปฎบตการ WindowsVisual Basic เขยนคำาสงดงนPrivate Declare Function GetUserName Lib "kernel32" Alias "UserName" (ByVal lpBuffer As String, nSize As Long) As LongVisual FoxPro เขยนคำาสงดงนDECLARE Long GetUserName IN Win32API AS UserName String @lpBuffer , Long @nSize เหนไหมครบวา Visual FoxPro เขยนคำาสงไดงายและสนกวาตงเยอะอธบายรปแบบคำาสง
Visual FoxPro
Visual Basic
DECLARE DECLAREPrivate Declare Function
เปนคำาสงทใชในการ Register ฟงกชน API
[FunctionType]
Long As Long เปนชนดของคาทสงกลบเมอเรยกใชงานฟงกชน คาทสงกลบไดมดงน SHORT
16-bit integer
INTEGER
32-bit integer
SINGLE
32-bit floating point
DOUBLE
64-bit floating point
224
LONG 32-bit long integer
STRING
Character string
FunctionName
GetUserName
GetUserName
ชอฟงกชนของ Windows API ตองปอนตวอกษรใหญเลกใหถกตองตามทกำาหนด
IN LibraryName
IN Win32API
Lib "kernel32"
เปนการเรยกใชฟงกชนจากไฟลใด สำาหรบ Visual FoxPro นนจะใชชอ Win32API แทน ไฟลเหลานทงหมด Kernal32.DLL, Gdi32.DLL, User32.DLL, Mpr.DLL และ Advapi32.DLL
AS [Alias]AS UserName
Alias "UserName"
กำาหนดชอในการเรยกใชงานแทนชอฟงกชนเดม
cParameterType1 String As String
เปนชนดของคาทใชสำาหรบนำาเขา หรอสงกลบเมอเรยกใชงานฟงกชน
ParamName1 @lpBuffer ByVal
lpBufferตวแปรทใชในการสงคาเขาและออก
cParameterType2 Long As Long
เปนชนดของคาทใชสำาหรบนำาเขา หรอสงกลบเมอเรยกใชงานฟงกชน
225
ParamName2.... @lnSize ByVal
lpSizeตวแปรทใชในการสงคาเขาและออก...
หมายเหต ในกรณทใสเครองหมาย @ ไวหนาตวแปรหมายความวาตวแปรทสงเขาไปในฟงกชนนนจะมการสงผลลพธกลบมาใหดวยการแสดงรายชอฟงกชนทไดทำาการ Register เมอเราทำาการ Register ฟงกชนตางๆแลว ถาเราตองการทราบวามฟงกชนใดถก Register แลวบางเราสามารถทำาการเรยกดไดโดยใชคำาสง DISPLAY DLLSหรอ LIST DLLSการลางคาฟงกชนทไดทำาการ Register เมอตองการลางคาฟงกชนทได Register ไปแลวสามารถทำาไดโดยใชคำาสง CLEAR DLLSการใชคำาสง CLEAR DLLS จะเปนการลางคาฟงกชนทมการ Register ไวออกทงหมดการนำาคำาสง Windows API ไปใชงาน ในชวงแรกๆทไดทำาการศกษาการใชงาน Windows API นนผเขยนลองทำาตามขนตอนตางๆโดยแปลงคำาสงจาก Visual Basic มาเปน Visual FoxPro ทกอยางทำาไดหมด เอ...แตผลลพธทำาไมไมยกออก ลองอยหลายครงหลายหนกไมสามารถทำาได จนกระทงไดไปคนเจอวาการนำาคาทสงกลบมาจากการเรยกใชงานฟงกชน API นนคาทสงกลบบางชนดสามารถนำามาใชงานไดทนท แตคาบางชนดตองมากระทำาการบางอยางเพอใหมคาจรงๆทเราสามารถนำาไปใชไดอยางถกตองใหคณลองศกษาจากตวอยาง โดยการสรางโปรแกรมชอ GETUSER.PRG โดยพมพคำาสงท Command Window ดงนMODIFY COMMMAND GETUSER.PRGแลวพมพคำาสงตามตวอยาง
226
** Program: Getuser.prg **** Purpose: Demonstrates how to use and call the Win32 **** GetUserName API. **
RetVal = 0lpUserIDBuffer = SPACE(256) && Return buffer for user ID stringnBufferSize = 256 && Size of user ID return buffer
DECLARE INTEGER GetUserName IN Win32API AS UserName ;STRING @lpUserIDBuffer, ;INTEGER @nBufferSize
RetVal=UserName(@lpUserIDBuffer, @nBufferSize)? RetVal && ถาฟงกชนทำาไมสำาเรจจะสงคากลบเปน 0 ? "Value in lpUserIDBuffer : " + lpUserIDBuffer? "Value in nBufferSize : " + STR(nBufferSize)? "User ID : " + LEFT(lpUserIDBuffer,nbuffersize-1)CLEAR DLLS** End Programทำาการบนทกโปรแกรมโดยกดปม Ctrl + W จากนนทำาการเรยกโปรแกรมโดยพมพคำาสง DO GETUSER ท Command Window แลวสงเกตผลลพททเกดขนจะสงเกตไดวาคำาสง ? "Value in lpUserIDBuffer : " + lpUserIDBuffer จะไดชอ user name กลบมาแตจะมคา null ตอทายมาใหดวยอก 1 ตวการใชงานคำาสง Windows API ในลกษณะตางๆสำาหรบตวอยางทจะนำาเสอนตอไปนทานสามารถนำาใปใชงานไดเลยทนท...ตามความประสงคการใชงานฟงกชน GetVolumnInformation
227
ฟงกชนนจะเปนการแสดงขอมลขาวสารของ Volumn ใน Disk สำาหรบผมจะใชคาทไดจาก VolumnSerialNumber โดยนำาไปใชเปนตว Lock ไมใหผอนนำาโปรแกรมเราไปลงเครองอนไดอก**---------------------------------------------------------------**** Program: Getvol.prg **** Purpose: Demonstrates how to declare and use the Win32 **** GetVolumeInformation API. ****---------------------------------------------------------------**
lpRootPathName = "c:\" && Drive and directory pathlpVolumeNameBuffer = SPACE(256) && lpVolumeName return buffernVolumeNameSize = 256 && Size of/lpVolumeNameBufferlpVolumeSerialNumber = 0 && lpVolumeSerialNumber bufferlpMaximumComponentLength = 256lpFileSystemFlags = 0lpFileSystemNameBuffer = SPACE(256)nFileSystemNameSize = 256
DECLARE INTEGER GetVolumeInformation IN Win32API AS GetVolInfo ;STRING @lpRootPathName, ;STRING @lpVolumeNameBuffer, ;INTEGER nVolumeNameSize, ;INTEGER @lpVolumeSerialNumber, ;INTEGER @lpMaximumComponentLength, ;INTEGER @lpFileSystemFlags, ;STRING @lpFileSystemNameBuffer, ;INTEGER nFileSystemNameSize
RetVal=GetVolInfo(@lpRootPathName, @lpVolumeNameBuffer, ;
228
nVolumeNameSize, @lpVolumeSerialNumber, ;@lpMaximumComponentLength, @lpFileSystemFlags, ;@lpFileSystemNameBuffer, nFileSystemNameSize)
**--------------------------------------------------------------**** Because several of the return values are padded with a null **** terminator, you will need to strip off the null terminator **** in order to get the correct value, which is what is done **** using the LEFT, ALLTRIM, and LEN functions. ****--------------------------------------------------------------**? "Drive & path name : " + ; ALLTRIM(lpRootPathName)? "Volume name : " + ; LEFT(ALLTRIM(lpVolumeNameBuffer),LEN(ALLTRIM(lpVolumeNameBuffer))-1)? "Max #/chars in vol name : " + ; ALLTRIM(STR(nVolumeNameSize))? "Volume Serial # : " + ; ALLTRIM(STR(lpVolumeSerialNumber))? "Max #/chars in dir/file names: " + ; ALLTRIM(STR(lpMaximumComponentLength))? "File System Flags : " + ; ALLTRIM(STR(lpFileSystemFlags))? "File System type : " + ; LEFT(ALLTRIM(lpFileSystemNameBuffer), ; LEN(ALLTRIM(lpFileSystemNameBuffer))-1)? "File Sys Name Size : " + ; ALLTRIM(STR(nFileSystemNameSize))CLEAR DLLS** End Program การใชงานฟงกชน GetSystemDirectory
229
เปนฟงกชนทใชในการหา System Directory ของระบบปฎบตการ Windows เนองจากในการ ตดตง โปรแกรม Windows ผตดตงสามารถจะกำาหนดชอ System Directory ใหกบระบบปฎบตการไดเอง ดงนนถาเราตองการทราบวาชออะไรเราตองใชฟงกชนตามตวอยางในการคนหา ดงน**---------------------------------------------------------------**** Program: GetSysDir.prg **** Purpose: Demonstrates how to declare and use the Win32 **** GetSystemDirectory API. ****---------------------------------------------------------------**lsSysDir = SPACE(256) && MAX_PATH, the maximum path lengthliSize = 256 DECLARE INTEGER GetSystemDirectory IN Win32API ;STRING @lsSysDir, ;INTEGER liSize
liRet = GetSystemDirectory(@lsSysDir, liSize) ? "Size of Data : " + STR(liRet) && ถาฟงกชนทำาไมสำาเรจจะสงคากลบเปน 0 ? "Windows System Directory : " + LEFT(lsSysDir,liRet)CLEAR DLLS ** End Program การใชงานฟงกชน GetTempPathเปนฟงกชนทใชในการหา Tempolary Directory ของระบบปฎบตการ Windows **---------------------------------------------------------------**** Program: GetTempDir.prg **** Purpose: Demonstrates how to declare and use the Win32 **** GetTempPath API. **
230
**---------------------------------------------------------------**lsSysDir = SPACE(256) && MAX_PATH, the maximum path lengthliSize = 256
DECLARE INTEGER GetTempPath IN Win32API ;INTEGER liSize, ;STRING @lsSysDir
liRet = GetTempPath(liSize, @lsSysDir) ? "Size of Data : " + STR(liRet) && ถาฟงกชนทำาไมสำาเรจจะสงคากลบเปน 0? "Windows Tempolary Directory : " + LEFT(lsSysDir,liRet)CLEAR DLLS** End Program การใชงานฟงกชน ExitWindowsExเปนฟงกชนทใชสงใหทำาการ ใชสำาหรบสงใหเครอง Boot, Restart หรอ Log off ระบบปฎบตการ Windows จากโปรแกรม**---------------------------------------------------------------**** Program: WinExit.prg **** Purpose: Demonstrates how to declare and use the Win32 **** ExitWindowsEx API. ****---------------------------------------------------------------**uFlags = 0* uFlags ขอมลชนด INTEGER ทใชสำาหรบกำาหนดหนาทใหฟงกชน ExitWindowsEx ( ) สามารถมคาไดดงน* 0 เมอตองการ สงให Log Off ออกจากระบบเครอขาย* 1 เมอตองการ สงให Shutdown เครอง* 2 เมอตองการสงให Restart เครองใหม* 4 เมอตองการออกจาก Windows โดยทนท (Force)dwReserved = 0DECLARE INTEGER ExitWindowsEx IN Win32API AS
231
ExitWindows INTEGER @uFlags , INTEGER dwReserved
RetVal = ExitWindows(@uFlags, dwReserved)
CLEAR DLLS** End Program การใชงานฟงกชน SHGetSpecialFolderPathเปนฟงกชนทใชในการคนหา Special Folder ของ Windows**---------------------------------------------------------------**** Program: FinFolder.prg **** Purpose: Demonstrates how to declare and use the SHELL32 **** SHGetSpecialFolderPath API. ****---------------------------------------------------------------***** Define Special Folder Constants#define CSIDL_PROGRAMS 2 &&Program Groups Folder#define CSIDL_PERSONAL 5 &&Personal Documents Folder#define CSIDL_FAVORITES 6 &&Favorites Folder#define CSIDL_STARTUP 7 &&Startup Group Folder#define CSIDL_RECENT 8 &&Recently Used Documents#define CSIDL_SENDTO 9 &&Send To Folder#define CSIDL_STARTMENU 11 &&Start Menu Folder#define CSIDL_DESKTOPDIRECTORY 16 &&Desktop Folder#define CSIDL_NETHOOD 19 &&Network Neighborhood Folder#define CSIDL_TEMPLATES 21 &&Document Templates Folder#define CSIDL_COMMON_STARTMENU 22 &&Common Start Menu Folder#define CSIDL_COMMON_PROGRAMS 23
232
&&Common Program Groups#define CSIDL_COMMON_STARTUP 24 &&Common Startup Group Folder#define CSIDL_COMMON_DESKTOPDIRECTORY 25 &&Common Desktop Folder#define CSIDL_APPDATA 26 &&Application Data Folder#define CSIDL_PRINTHOOD 27 &&Printers Folder#define CSIDL_COMMON_FAVORITES 31 &&Common Favorites Folder#define CSIDL_INTERNET_CACHE 32 &&Temp. Internet Files Folder#define CSIDL_COOKIES 33 &&Cookies Folder#define CSIDL_HISTORY 34 &&History Folder
cSpecialFolderPath = space(255)
DECLARE SHGetSpecialFolderPath IN SHELL32.DLL ;AS GetFolder LONG hwndOwner, ;STRING @cSpecialFolderPath, ;LONG nWhichFolder
*** เชนตองการคนหา StartUp Folder วาอย ณ.ทใด เราจะใชตวแปร CSIDL_STARTUP ซงมคาเทากบ 7GetFolder(0, @cSpecialFolderPath, CSIDL_STARTUP)
?SubStr(RTrim(cSpecialFolderPath),1, Len(RTrim(cSpecialFolderPath))-1)
CLEAR DLLS** End Program การใชงานฟงกชน FindExecutable
233
เปนฟงกชนทใชในการคนหาชอไฟลทตองการ แลวแสดง Folder ทไฟลนนๆบรรจอย**---------------------------------------------------------------**** Program: FindFile.prg **** Purpose: Demonstrates how to declare and use the SHELL32 **** FindExecutable API. ****---------------------------------------------------------------**lpFile = "NOTEPAD.EXE"lpDirectory = ''lpResults = SPACE(128)
DECLARE INTEGER FindExecutable IN SHELL32 ;STRING@lpFile, STRING@lpDirectory, ;STRING @lpResults
liReturnValue = FindExecutable(@lpFile, @lpDirectory,@lpResults)* ในกรณททำาการคนหาแลวไมพบ IiReturnValue จะมคาดงน* 0 = Out of memory or resources* 31 = No association for file type* 2 = Specified file not found* 3 = Specified path not found* 11 = Invalid EXE format?liReturnValuelpResults = LEFT(lpResults, AT(CHR(0), lpResults) - 1)
? "Full path of application: " + lpResults
CLEAR DLLS** End Programการใชงานฟงกชน MessageBeepเปนฟงกชนทใชในการสงเสยนเตอน เหมอนกบ คำาสง ? CHR(7) แตคณสามารถทจะนำาเสยงจาก Sound ของ Windows มาใชได
234
โดยเสยงตางๆคณสามารถเขาไปกำาหนดใน Control Panel ในสวนของ Sounds**---------------------------------------------------------------**** Program: Beep.prg **** Purpose: Demonstrates how to declare and use the WIN32API **** MessageBeep API. ****---------------------------------------------------------------**#DEFINE MB_OK 0 && Default Sound#DEFINE MB_ICONHAND 16 && Certical Stop#DEFINE MB_ICONQUESTION 32 && Question#DEFINE MB_ICONEXCLAMATION 48 && Exclamation#DEFINE MB_ICONASTERISK 64 && AsteriskDECLARE INTEGER MessageBeep IN Win32API INTEGER=MessageBeep(MB_OK)CLEAR DLLS** End Programการกำาหนดหนาตางใหอยบนสดของ Windows(Topmost Window)ในสมยทเรายงใชระบบปฎบตการ DOS เราจะไมคอยจะมปญหาเกยวกบการใชงานโปรแกรมสกเทาได เนองจากวาเมอทำาการเรยกโปรแกรมขนมาแลว เราจะตองใชงานโปรแกรมนนจนเสรจ แลวออกจากโปรแกรมดงกลาวกอน จงจะสามารถทำางานหรอเรยกโปรแกรมอนๆตอไปได(ยกเวนโปรแกรมประเภทฝงตว) แตพอมาถงยคของระบบปฎบตการ Windows งานหลายๆงานสามารถเปดใชงานไดพรอมๆกน ซงกเปนขอดของระบบปฎบตการ Windows แตผมเปนพวกหวโบราณกเลยอยากใหผใช เมอเขาสโปรแกรมทผมสราง
235
ขนมาดวย Visual FoxPro ใชแตโปรแกรมของผมจนกระทงออกจากโปรแกรมโดยทไมสามารถใชโปรแกรมตวอนๆไดเลยไมวาจะเปน Word , Excel เปนตน ดงนนจงเปนทมาของ ฟงกชนทผมจะนำาเสนออยนฟงกชนทจะนำาเสนอนเปนฟงกชนทกำาหนดให หนาตางหรอฟอรมทเราตองการ กำาหนดใหอยบนสดของ Window เสมอ (Topmost Window)ใหคณทำาการสรางฟงกชนตามตวอยางตอไปน**---------------------------------------------------------------**** Program: topwindow.prg **** Purpose: Demonstrates how to declare and use the WIN32API **** FindWindowA API. **** SetWindowPos API. ****---------------------------------------------------------------**FUNCTION TOPWINDOWPARA cCaption, lStatus
DECLARE LONG FindWindowA IN WIN32API ;STRING class, ;STRING title
DECLARE SetWindowPos IN WIN32API ;LONG HWND, ;LONG hwndafter, ;LONG x, ;LONG Y, ;LONG cx, ;LONG cy, ;LONG flagsformhandle = 0formhandle = FindWindowA(0,cCaption) IF formhandle = 0=MESSAGEBOX("ไมพบ window ทตองการ")ELSE
236
swp_nosize = 1 swp_nomove = 2 hwnd_topmost = -1 hwnd_notopmost = -2 lretval=0 IF lStatus lretval = SetWindowPos(formhandle,hwnd_topmost,; 0,0,0,0,swp_nosize+swp_nomove) ELSE lretval = SetWindowPos(formhandle,hwnd_notopmost,; 0,0,0,0,swp_nosize+swp_nomove) ENDIF ENDIFCLEAR DLLSRETURNตวอยางการใชงาน ใหคณปอนคำาสงตอไปนท Command Window_Screen.MinButton=.F._Screen.MaxButton=.F._Screen.WindowState = 2=TOPWINDOW(_Screen.Caption,.T.)* _Screen.Caption ใชสำาหรบ Main Visual FoxPro Window * ในกรณทตองการหา window อนๆ กใช ใช caption ของ window นนๆ* ถาไมตองการใหผใชสามารถใช Task Bar ได ใหกำาหนดเปน Auto Hide ในกรณทตองการยกเลกการกำาหนด topmost window กใหใชคำาสงดงน=TOPWINDOW(_Screen.Caption,.F.)
ไวจะนำามาลงใหอกครบทาน.....
237
วนททฝนใฝหลายๆทานคงจะพบปะสงสรรคปญหาเกยวกบวนทกนบางพอสมควร ไมวาจะเปนเรองของ Y2K ซงฝรงตานำาขาวมนหลอกชาวโลกทงหลายใหหลงคารมมาแลว แต บ มอะในกอ ไก ขอ ไข มแตเสยตง โดยสวนตว Y2K หรออะไรพวกนถาเรากำาหนดการปอน ป เปนแบบ 4 หลกแลวปญหากไมม เราจะใชคำาสงกำาหนด ปเปน 4 หลก ดงน SET CENTURY ONแตประเดนทเราจะมาดกนคอ จะทำาอยางไรกบฟลดวนทด แลวอยากจะใหวนทเปนแบบทเราตองการ (ผเขยนตองการตางหาก)
อยากใหฟลดวนท แสดงเปน วนทแบบ ไทยๆ เชน 10 กนยายน 2543 (วนครบรอบ 2 ขวบ ของ web site ไวเหมอนใจนก)เมอเขาไปปอนอยากปอนสนๆ แค 10/09/2543แลวถาผใชปอน เปน 2000 กใหแปลงมาเปน 2543 ใหดวยกดพอปอนเสรจกใหแสดงกลบเปนอยางเกา 10 กนยายน 2543และสงทขาดมไดคอตรวจสอบการปอนวนทวาถกตองหรอเปลาเรามาเรมกนเลยละกนครบใหคณสรางฟงกชนตางๆดงนกอนครบ*BC2BE.PRG**************************************************************** Function Convert date from BC to BE* ---โปรแกรม...... แปลงคาวนทจาก ค.ศ. เปน พ.ศ.* ---ตวอยาง...... cTDATE=BC2BE(DATE())***************************************************************FUNC BC2BE PARA BCDATE && ค.ศ. IF TYPE('BCDATE')#'D'
238
RETURN ''ENDIFLOCAL cDD,cMMcDD = ALLT(STR(DAY(BCDATE),2))cDD = IIF(LEN(cDD)=1,"0"+cDD,cDD)cMM = ALLT(STR(MONTH(BCDATE),2))cMM = IIF(LEN(cMM)=1,"0"+cMM,cMM)RETU cDD+'/'+cMM+'/'+STR(YEAR(BCDATE)+543,4)
*BE2BC.PRG**************************************************************** Function Convert date from BE to BC* ---โปรแกรม...... แปลงคาวนทจาก พ.ศ. เปน ค.ศ.*-- นำาไปใช...... dEDATE=BE2BC('25/03/2543')***************************************************************FUNC BE2BC PARA BEDATE && DD/MM/YYYY พ.ศ. LOCAL nDD,nMM,nYYYYIF TYPE('BEDATE')#'C'RETURN ''ENDIFnDD = VAL(SUBST(BEDATE,1,2))nMM = VAL(SUBST(BEDATE,4,2))nYYYY = VAL(SUBST(BEDATE,7,4))-543IF TYPE('nDD')#'N' .OR. TYPE('nMM')#'N' .OR. TYPE('nYYYY')#'N'RETURN ''ELSEIF nDD > 0 .AND. nMM > 0 .AND. nYYYY > 0RETURN DATE(nYYYY,nMM,nDD)ENDIFENDIFRETURN ''
239
*BE2TD.PRG**************************************************************** ---FUNCTION BE2TD* ---โปรแกรม...... แปลงคาวนทไทยเปนแบบภาษาไทยเตมยศ*-- นำาไปใช...... cTdate=BE2TD('12/01/2543')***************************************************************FUNC BE2TDPARA cTDATE IF TYPE('cTDATE')#'C'RETURN ''ENDIFRETURN SUBST(cTDATE,1,2) + ' ' + ;TCMONTH(BE2BC(cTDATE)) + ' ' + ;SUBST(cTDATE,7,4)
*TD2BE.PRG**************************************************************** ---FUNCTION TD2BE* ---โปรแกรม...... แปลงคาวนทไทยเตมเปนวนทไทย*-- นำาไปใช...... cTdate=TD2BE('12 มกราคม 2543')***************************************************************FUNC TD2BEPARA cTDATE LOCAL cMM,nMMSTOR SPACE(2) TO nMMIF TYPE('cTDATE')#'C'RETURN ''ENDIFDO CASECASE AT('มกราคม', cTDATE) > 0
240
cMM = 'มกราคม'nMM = '01'CASE AT('กมภาพนธ', cTDATE) > 0cMM = 'กมภาพนธ'nMM = '02'CASE AT('มนาคม', cTDATE) > 0cMM = 'มนาคม'nMM = '03'CASE AT('เมษายน', cTDATE) > 0cMM ='เมษายน'nMM = '04'CASE AT('พฤษภาคม', cTDATE) > 0cMM = 'พฤษภาคม'nMM = '05'CASE AT('มถนายน', cTDATE) > 0cMM = 'มถนายน'nMM = '06'CASE AT('กรกฎาคม', cTDATE) > 0cMM = 'กรกฎาคม'nMM = '07'CASE AT('สงหาคม', cTDATE) > 0cMM = 'สงหาคม'nMM = '08'CASE AT('กนยายน', cTDATE) > 0cMM = 'กนยายน'nMM = '09'CASE AT('ตลาคม', cTDATE) > 0cMM = 'ตลาคม'nMM = '10'CASE AT('พฤศจกายน', cTDATE) > 0cMM = 'พฤศจกายน'
241
nMM = '11'CASE AT('ธนวาคม', cTDATE) > 0cMM = 'ธนวาคม'nMM = '12'ENDCASEIF !EMPTY(nMM)RETURN ALLT(LEFT(cTDATE,ATC(cMM,cTDATE)-1))+ ;'/'+nMM+'/' + RIGHT(cTDATE,LEN(cTDATE)- ;(ATC(cMM,cTDATE)+LEN(cMM)))ENDIFRETURN ''
*CHKTD.PRG**************************************************************** ---FUNCTION CHKTD* ---โปรแกรม...... ตรวจสอบการปอนวนทไทย*-- นำาไปใช...... LDate=CHKTD('22/01/2543') return .T. or .F.***************************************************************FUNC CHKTDPARA BEDATE && พ.ศ. IF TYPE('BEDATE')#'C'RETURN .F.ENDIFON ERROR mABC= ERROR()LOCAL nDD,nMM,nYYYY,XXX,mABCmABC=0nDD = VAL(SUBSTR(BEDATE,1,2))nMM = VAL(SUBSTR(BEDATE,4,2))nYYYY = VAL(SUBSTR(BEDATE,7,4))-543XXX=DATE(nYYYY,nMM,nDD)ON ERROR
242
IF mABC # 0 .OR. EMPTY(XXX)RETURN .F.ENDIFRETURN .T.*TCMONTH.PRG**************************************************************** ---FUNCTION TCMONTH* ---โปรแกรม...... แปลงคาเดอนเปนภาษาไทย*-- นำาไปใช...... mMONTH=TCMONTH(DATE())***************************************************************FUNC TCMONTH PARA dDATEIF TYPE('dDATE')#'D'RETURN ''ENDIFDO CASE CASE MONTH(dDATE)=1RETURN 'มกราคม'CASE MONTH(dDATE)=2RETURN 'กมภาพนธ'CASE MONTH(dDATE)=3RETURN 'มนาคม'CASE MONTH(dDATE)=4RETURN 'เมษายน'CASE MONTH(dDATE)=5RETURN 'พฤษภาคม'CASE MONTH(dDATE)=6RETURN 'มถนายน'CASE MONTH(dDATE)=7RETURN 'กรกฎาคม'CASE MONTH(dDATE)=8RETURN 'สงหาคม'
243
CASE MONTH(dDATE)=9RETURN 'กนยายน'CASE MONTH(dDATE)=10RETURN 'ตลาคม'CASE MONTH(dDATE)=11RETURN 'พฤศจกายน'CASE MONTH(dDATE)=12RETURN 'ธนวาคม'ENDCASERETURN ''
*TM2M.PRG**************************************************************** ---FUNCTION TM2M* ---โปรแกรม...... แปลงคาเดอนไทยเตมเปนเดอน* ---ผเขยน........ Kasem K.* ---วนแกไข....... 12.08.99*-- นำาไปใช...... nMonth=TM2M('มกราคม')***************************************************************FUNCTION TM2MPARAMETER cTMONTHnMM = 0DO CASECASE AT('มกราคม', cTMONTH) > 0nMM = 01CASE AT('กมภาพนธ', cTMONTH) > 0nMM = 02CASE AT('มนาคม', cTMONTH) > 0nMM = 03CASE AT('เมษายน', cTMONTH) > 0nMM = 04
244
CASE AT('พฤษภาคม', cTMONTH) > 0nMM = 05CASE AT('มถนายน', cTMONTH) > 0nMM = 06CASE AT('กรกฎาคม', cTMONTH) > 0nMM = 07CASE AT('สงหาคม', cTMONTH) > 0nMM = 08CASE AT('กนยายน', cTMONTH) > 0nMM = 09CASE AT('ตลาคม', cTMONTH) > 0nMM = 10CASE AT('พฤศจกายน', cTMONTH) > 0nMM = 11CASE AT('ธนวาคม', cTMONTH) > 0nMM = 12ENDCASERETURN nMMสรางเสรจแลว ตอมากเรมสราง คลาสยอย เพอเกบเอาไปใชงานในโอกาสตอไปในภายภาคหนา พมพคำาสงท Command Windows ดงนCLEATE CLASSจากนนปอนขอมลตามตวอยางดงภาพ
แลวกคลกปม OK จากนนทานกจะเขาส Class Designerกำาหนด Property ของ Object ดงน
245
Alignment = 2-CenterFontName = MS Sans SerifFormat = KWidth = 130ท Object: txtdateth Procedure: Valid ปอนคำาสงLOCAL nYEARIF This.Value#' / / 'IF SUBSTR(This.Value,7,4) > '1800' AND SUBSTR(This.Value,7,4) < '2200'nYEAR=VAL(SUBSTR(This.Value,7,4))+543This.Value=SUBSTR(This.Value,1,6)+ALLT(STR(nYEAR))ENDIFIF SUBSTR(This.Value,7,4) <= '1800' OR SUBSTR(This.Value,7,4) > '2743'=MESSAGEBOX('ปอนวนทไมถกตอง',64,'')RETURN 0 ENDIFIF !CHKTD(This.Value)=MESSAGEBOX('ปอนวนทไมถกตอง',64,'')RETURN 0ENDIFENDIFท Object: txtdateth Procedure: LostFocus ปอนคำาสงIF This.Value#' / / 'This.Value = BE2TD(This.Value)ELSEThis.Value = ''ENDIFThis.InputMask = ''ท Object: txtdateth Procedure: GotFocus ปอนคำาสงIF This.Value#' / / 'This.Value = TD2BE(This.Value)
246
This.InputMask = '99/99/9999'ENDIFจากนนกทำาการ บนทกเกบไวใชงานไดเลยครบทาน โดยกดปม Ctrl + WDown Load ตวอยางการใชงาน
247