常用編程命令及常用函數(shù)
注:在語法中如用方括號“[ ]”括起來的詞句,表示可以不用。
常用命令
常用函數(shù)
假設(shè)語句
根據(jù)一邏輯表達(dá)式的值,有條件的執(zhí)行一組命令。
語法:
IF 邏輯表達(dá)式 [THEN]
程序組1
[ELSE
程序組2]
ENDIF
參數(shù):
邏輯表達(dá)式代表一邏輯值,如果這邏輯值為真,系統(tǒng)執(zhí)行程序組1,否則不執(zhí)行程序組1,如果有else及程序組2的話,則執(zhí)行程序組2,如沒有則什么也不執(zhí)行,直接執(zhí)行endif后面的語句。
備注:
在if...endif之間還可以有if...endif,即該命令是可以嵌套的。
then可以有也可以沒有,對程序沒有影響。
else及程序組2可以有也可以沒有,但如果有的話,在邏輯表達(dá)式的值為假時,程序組2將被執(zhí)行。
if 與 endif 必須配對使用,即有一個 if 必須有一個 endif, 否則程序會出錯。
舉例:
例1:假如分?jǐn)?shù)字段的值大于等于90,則讓等級字段的值為“優(yōu)”,并顯示該記錄。程序如下:
if 分?jǐn)?shù)>=90
replace 等級 with '優(yōu)'
display
endif
例2:在數(shù)據(jù)庫中可以把性別字段設(shè)為邏輯型,“真”代表“男”,“假”代表“女”,但顯示時不能顯示真、假,否則別人看不懂,而應(yīng)顯示男、女,因此我們設(shè)一變量xb,根據(jù)性別字段的具體值,將xb的值設(shè)為男或女,然后在需要的時候顯示xb的值即可。程序如下:
if 性別
xb='男'
else
xb='女'
endif
其中第一句:if 性別,表示“假如性別為真”的意思,不要寫成“if 性別=.t.”。
以上程序也可以寫成如下形式,效果相同:
if .not. 性別
xb='女'
else
xb='男'
endif
即,假如性別不為真的話,xb的值就為女,否則為男。
循環(huán)語句(do while...enddo)
根據(jù)條件重復(fù)執(zhí)行一組程序。
語法:
DO WHILE lExpression
Commands
[LOOP]
[EXIT]
ENDDO
參數(shù):
lExpression 為一邏輯表達(dá)式,其值如果是“真”,即執(zhí)行commands程序組,如果表達(dá)的值為“假”,則跳過該段程序組,執(zhí)行enddo后面的語句。
Commands 當(dāng)表達(dá)式 lExpression 值為真時所要執(zhí)行的程序組。
LOOP 此為 do while...enddo 命令的一個子句,它可以放在 commands 程序組中間的任何地方,當(dāng)程序一旦執(zhí)行到該子句時,則返回 do while 重新執(zhí)行。此子句根據(jù)需要可以有,也可以沒有。
EXIT 與loop一樣是 do while...enddo 命令的一個子句,它可以放在 commands 程序組中間的任何地方,當(dāng)程序一旦執(zhí)行到該子句時,則跳出循環(huán),執(zhí)行enddo后面的語句。此子句根據(jù)需要可以有,也可以沒有。
備注:
程序一旦執(zhí)行到do while 語句,如果 lExpression 的值為真,則執(zhí)行 commands 程序組,該程序組執(zhí)行完后,就到enddo語句,enddo會將程序返回 do while 再次驗證 lExpression 是否為真,如仍是,則又一次執(zhí)行 commands ,如此循環(huán)往復(fù),直到 lExpression 為假,或遇上 exit 語句。
該語句可以嵌套,即循環(huán)中還可以有循環(huán)。
do while 與 enddo 必須配對使用,即有一個 do while 必須有一個 enddo 否則程序會出錯。
舉例:
例1:在數(shù)據(jù)庫中不斷將記錄指針往下移,直到數(shù)據(jù)庫結(jié)尾。程序如下:
do while .not. eof()
skip
enddo
例2:在上面的例子加入此功能,當(dāng)遇到性別字段為“女”時,跳出循環(huán)。程序如下:
do while .not. eof()
if 性別='女'
exit
endif
skip
enddo
例3:不斷將記錄指針往下移,當(dāng)遇到數(shù)量字段的值大于等于600時退出循環(huán),如遇到值小于400的,將其值乘2,然后再檢驗一次是否大于600,如是則退出循環(huán)。程序如下:
do while 數(shù)量<600
if 數(shù)量<400
replace 數(shù)量 with 數(shù)量*2
loop
endif
skip
enddo
分支語句(do case...endcase)
根據(jù)不同的條件執(zhí)行不同的程序組。
語法:
DO CASE
CASE 邏輯表達(dá)式1
程序組1
[CASE 邏輯表達(dá)式2
程序組2
...
CASE 邏輯表達(dá)式n
程序組n]
[OTHERWISE
程序組0]
ENDCASE
參數(shù):
CASE 邏輯表達(dá)式 程序組 ... 當(dāng)程序執(zhí)行到 do case 時,便檢驗第一個 case 的邏輯表達(dá)式(邏輯表達(dá)式1)是否為真,如不為真,接著檢驗第二個 case 的邏輯表達(dá)式,以此類推直到邏輯表達(dá)式n。當(dāng)檢測到第一個為真的邏輯表達(dá)式時,便執(zhí)行跟隨在其后面的程序組,執(zhí)行完后跳過后面所有的 case ,接著執(zhí)行 endcase 后面的語句,也就是說即使后面還有為真的邏輯表達(dá)式也不執(zhí)行了。
如果所有 case 后面的邏輯表達(dá)式都為假,則執(zhí)行 otherwise 后面的程序組(如果有的話, otherwise 及其程序組是可以沒有的,如果沒有則什么都不做,直接執(zhí)行 endcase 以后的程序)
備注:
在do case 和 endcase 之間可以有任意多個 case 。
do case 和 endcase 必須配對使用,即有一個 do case 必須有一個 endcase ,否則程序會出錯。
舉例:
如果工資在200元以下,增加50%;300元以下,增加30%;500元以下,增加20%;其它增加10%。程序如下:
do case
case 工資<=200
replace 工資 with 工資*1.5
case 工資<=300
replace 工資 with 工資*1.3
case 工資<=500
replace 工資 with 工資*1.2
otherwise
replace 工資 with 工資*1.1
endcase
在這里要注意一個問題,不能把300元的 case 放在200元之前,否則一個100元的,按理應(yīng)加50%,但當(dāng)遇到小于300元的 case 時,其邏輯表達(dá)式為真(小于200元的肯定小于300元),因此就會執(zhí)行后面的程序,加30%,并且執(zhí)行完后,就不再執(zhí)行其它的 case 了,這樣就產(chǎn)生了錯誤的結(jié)果,所以應(yīng)按從小到大的順序來排列。
賦值語句(store...to)
將一個數(shù)據(jù)賦給一個變量。
語法:
STORE 表達(dá)式 TO 變量名表
參數(shù):
表達(dá)式的值即為要賦給變量的數(shù)據(jù)。
變量名表即為要被賦值的各變量。在這里可以是一個變量,也可以是多個變量,如果有多個變量,其間用“,”(逗號)隔開。
備注:
如果是給一個變量賦值,該語句可寫成如下形式:
變量名=表達(dá)式
表達(dá)式可以是一個數(shù)值,也可以是一個算術(shù)式。
舉例:
例1:將3賦給ab、xyz、jfz三個變量,程序如下:
store 3 to ab,xyz,jfz
例2:將變量gz的值加100賦給yfgz。程序如下:
yfgz=gz+100
調(diào)用表單語句
運行一個由表單設(shè)計器設(shè)計的表單文件。該文件是經(jīng)編譯過的。
語法:
DO FORM 表單文件名 [NAME 變量名 [LINKED]]
參數(shù)
表單文件名即是要運行的由表單設(shè)計器設(shè)計的表單文件名稱。
變量名為調(diào)用該表單所用的變量名稱,做為表單,不能直接用這的名稱去調(diào)用它,必須將其賦給一個變量,然后用這個變量來調(diào)用它。如果您不會在這個表單之外調(diào)用它,也可以不要這個變量。
在程序中產(chǎn)生的所有變量在程序運行結(jié)束后將被釋放,即這些變量不再存在,因此也就無法繼續(xù)調(diào)用這些變更,如果為了調(diào)試程序需要在程序運行結(jié)束后在命令窗口中調(diào)用這個表單,必須加上 linked 子句。
舉例:
在程序中調(diào)用xy7表單,并將賦給一個變量lucky,程序如下:
do form xy7 name lucky
調(diào)用子程序語句(do)
運行一個VFP程序。當(dāng)我們要在一個程序中調(diào)用另一個程序(子程序)時使用此命令。
語法:
DO 程序名
參數(shù):
程序名即為被調(diào)用的程序名稱。
備注:
如被調(diào)用的程序的擴展名是“prg”,調(diào)用時可不用帶擴展名,否則要帶上擴展名。
舉例:
有一個程序,名稱為 xy7.prg,調(diào)用它的程序如下:
do xy7
返回調(diào)用程序語句(return)
返回調(diào)用本程序(該語句所在程序)的程序。
前面講過調(diào)用子程序的語句,從一個程序A調(diào)用另一個程序B后,系統(tǒng)便開始執(zhí)行B程序中的語句,到一定時候往往要從程序B返回程序A,便可使用該語句。
語法:
RETURN
備注:
程序A調(diào)用程序B,當(dāng)從B返回A后,系統(tǒng)接著執(zhí)行調(diào)用語句(do b)下面的一條語句。
舉例:
程序a.prg如下:
do while .not. eof()
if 工資<100
do b
endif
skip
enddo
程序b.prg如下:
replace 工資 with 工資*1.5 &&將工資增加50%
display &&顯示出該記錄,這樣可以將所有增加了工資的記錄顯示出來
return
首先執(zhí)行程序a.prg,當(dāng)程序執(zhí)行到 do b 語句時,便轉(zhuǎn)去執(zhí)行程序 b.prg ,在程序 b 中執(zhí)行到 return語句時,又返回程序 a ,并接著執(zhí)行 do b 的下一條語句 endif 。
啟動事件處理語句(read events)
啟動VFP的事件處理程序。
語法:
READ EVENTS
備注:
當(dāng)該命令執(zhí)行后,系統(tǒng)即停止繼續(xù)執(zhí)行后續(xù)的語句,這時我們可以調(diào)用之前所啟動的菜單、表單等對象,并用這些對象的事件程序去完成相應(yīng)的任務(wù),直到發(fā)出
clear events 命令,系統(tǒng)才接著執(zhí)行 read events 后面的命令語句。
可能初學(xué)者看了上面的內(nèi)容還不是很清楚,不要緊,我們在后面課程中會進(jìn)一步講解。
清除事件處理語句(clear events)
終止由 read events 語句啟動的事件處理程序。
語法:
clear events
備注:
開關(guān)命令執(zhí)行狀態(tài)語句(set talk on/off)
確定是否顯示VFP命令執(zhí)行的狀態(tài)。
語法:
SET TALK ON | OFF
參數(shù):
ON 顯示VFP命令執(zhí)行的狀態(tài)。
OFF 不顯示VFP命令執(zhí)行的狀態(tài)。
備注:
使用時,on、off 二者之中必須選擇一個。
很多VFP命令執(zhí)行后,會顯示執(zhí)行后的結(jié)果狀態(tài),如 locate for 命令執(zhí)行,如找到記錄的會顯示被找到的記錄號,否則會顯示“已到文件尾”,但一般我們在程序中是不需要這些顯示的,比如找到了記錄就直接顯示出來,沒找到一般用一個對話框來給出更清楚的提示,所以在程序一開始往往要將 set talk 關(guān)閉。
結(jié)束程序語句(cancel)
結(jié)束當(dāng)前正在運行的所有程序,返回VFP或操作系統(tǒng)。
語法:
cancel
備注:
數(shù)值轉(zhuǎn)換字符函數(shù)(str())
返回與指定數(shù)值表達(dá)式對應(yīng)的字符。
語法:
str(數(shù)值表達(dá)式[,長度[,小數(shù)位數(shù)]])
返回值的類型
字符型
參數(shù):
數(shù)值表達(dá)式:要被轉(zhuǎn)換為字符的數(shù)值表達(dá)式。
長度:轉(zhuǎn)換后字符的長度。該長度等于小數(shù)點和小數(shù)點右邊第個數(shù)字所占字符的數(shù)目總和。
如果指定長度大于所需長度,自動在前面加空格補齊。
如果指定長度小于所需長度,返回一串星(*)號,表示數(shù)值溢出。
如省略長度,則默認(rèn)長度為10。
小數(shù)位數(shù):指定返回字符串中的小數(shù)位數(shù)。
如指定位數(shù)小于實際位數(shù),則返回值四舍五入。
如指定位數(shù)大于實際位數(shù),則加0補齊。
如省略小數(shù)位數(shù),默認(rèn)為0。
在指定了小數(shù)位數(shù)的情況下,如指定長度(第二個參數(shù))小于總長度,但大于整數(shù)長度,則返回對小數(shù)部分做了四舍五入的字符。
備注:
返回后的值看起來還是數(shù)的形式,但它的數(shù)據(jù)類型已經(jīng)變了,不再是一個數(shù)值,也就是不能再用來做加、減、乘、除的算術(shù)運算,但可以和字符進(jìn)行加減。比如:
? '季度'+1
就會出錯,因為一個字符是不能和一個數(shù)值相加的。寫成如下形式就可以了:
? '季度'+str(1,1)
結(jié)果是:
季度1
注意,這里一定要指定長度,否則由于默認(rèn)長度是10,就會出現(xiàn)如下結(jié)果:
季度 1
假如不知道數(shù)值有幾位數(shù)怎么辦呢?請參見
ltrim()函數(shù)。
字符轉(zhuǎn)換數(shù)值函數(shù)(val())
將數(shù)字組成的字符表達(dá)式轉(zhuǎn)換成數(shù)字值。
語法:
val(字符表達(dá)式)
返回值的類型
數(shù)值型
參數(shù):
字符表達(dá)式:要被轉(zhuǎn)換為數(shù)值的字符表達(dá)式。該表達(dá)式由最多16位的數(shù)字組成,若超過16位,則對其圓整。
備注:
val()函數(shù)從左到右返回字符表達(dá)式中的數(shù)字,直到遇到非數(shù)值型字符(忽略前面的空格)時為止。
若字符表達(dá)式的第一個字符不是數(shù)字,也不是正、負(fù)號,則返回0。
舉例:
a='123'
如果按下面的寫法,就會出錯,因為一個字符不能與一個數(shù)值相加:
? a+3
寫成如下形式便可以了:
? val(a)+3
結(jié)果是126。
取系統(tǒng)日期函數(shù)(date())
返回由操作系統(tǒng)控制的當(dāng)前系統(tǒng)日期。
語法:
date()
返回值的類型
日期型
取年份函數(shù)(year())
從指定的日期表達(dá)式中返回年份。
語法:
year(日期表達(dá)式)
返回值的類型
數(shù)值型
參數(shù):
日期表達(dá)式:指定的日期表達(dá)式,該函數(shù)即是返回其年份值。
舉例:
? year(date())
如果當(dāng)前的系統(tǒng)日期是1999年2月5日,則顯示的結(jié)果為1999。
取月份函數(shù)(month())
從指定的日期表達(dá)式中返回月份。
語法:
month(日期表達(dá)式)
返回值的類型
數(shù)值型
參數(shù):
日期表達(dá)式:指定的日期表達(dá)式,該函數(shù)即是返回其月份值。
舉例:
? month(date())
如果當(dāng)前的系統(tǒng)日期是1999年2月5日,則顯示的結(jié)果為2。
取天日函數(shù)(day())
以數(shù)值型返回日期表達(dá)式是當(dāng)月的第幾天。
語法:
day(日期表達(dá)式)
返回值的類型
數(shù)值型
參數(shù):
日期表達(dá)式:指定的日期表達(dá)式,該函數(shù)返回該日期是當(dāng)月的第幾天。
舉例:
? day(date())
如果當(dāng)前的系統(tǒng)日期是1999年2月5日,則顯示的結(jié)果為5。
取整函數(shù)(int())
返回數(shù)值表達(dá)式值的整數(shù)部分。
語法:
int(數(shù)值表達(dá)式)
返回值的類型
數(shù)值型
參數(shù):
數(shù)值表達(dá)式:指定的數(shù)值表達(dá)式,該函數(shù)返回其整數(shù)部分。
舉例:
? int(123.47)
結(jié)果是123。
四舍五入函數(shù)(round())
對指定表達(dá)式進(jìn)行四舍五入運算,并把結(jié)果返回。
語法:
round(數(shù)值表達(dá)式,小數(shù)位數(shù))
返回值的類型
數(shù)值型
參數(shù):
數(shù)值表達(dá)式:指定的數(shù)值表達(dá)式,該函數(shù)返回其四舍五入后的值。
小數(shù)位數(shù):保留的小數(shù)位數(shù)。
舉例:
? int(123.457,2)
結(jié)果是123.46。
刪除標(biāo)記函數(shù)(delete())
確定當(dāng)前記錄是否已做刪除標(biāo)記,若已做刪除標(biāo)記,返回真(.t.),否則返回假(.f.)。
語法:
delete([表別名|工作區(qū)])
返回值的類型:
邏輯型
參數(shù):
表別名|工作區(qū):該參數(shù)指定所要確定的表的別名或所在工作區(qū),即您可以在一個工作區(qū)去檢測另一工作區(qū)的表的記錄是否做了刪除標(biāo)記,而另一工作區(qū)的表可用其別名或工作區(qū)號來指定。該參數(shù)如省略,隱含為當(dāng)前工作區(qū),如有該參數(shù)的話,別名或工作區(qū)只選一個。
記錄號函數(shù)(recno())
返回當(dāng)前表或指定表中的當(dāng)前記錄號。
語法:
recno([表別名|工作區(qū)])
返回值的類型:
數(shù)值型
參數(shù):
表別名|工作區(qū):該參數(shù)指定所要確定的表的別名或所在工作區(qū),即您可以在一個工作區(qū)去得到另一工作區(qū)的表的當(dāng)前記錄號,而另一工作區(qū)的表可用其別名或工作區(qū)號來指定。該參數(shù)如省略,隱含為當(dāng)前工作區(qū),如有該參數(shù)的話,別名或工作區(qū)只選一個。
記錄數(shù)函數(shù)(reccount())
返回當(dāng)前表或指定表中的記錄數(shù)目。
語法:
reccount([表別名|工作區(qū)])
返回值的類型:
數(shù)值型
參數(shù):
表別名|工作區(qū):該參數(shù)指定所要確定的表的別名或所在工作區(qū),即您可以在一個工作區(qū)去得到另一工作區(qū)的表的記錄數(shù),而另一工作區(qū)的表可用其別名或工作區(qū)號來指定。該參數(shù)如省略,隱含為當(dāng)前工作區(qū),如有該參數(shù)的話,別名或工作區(qū)只選一個。
找到記錄函數(shù)(found())
如果locate、continue、seek等查找記錄的命令成功(即找到了記錄),該函數(shù)返回“真”(.t.),否則返回“假”(.f.)。
語法:
found([表別名|工作區(qū)])
返回值的類型:
邏輯型
參數(shù):
表別名|工作區(qū):該參數(shù)指定所要確定的表的別名或所在工作區(qū),即您可以在一個工作區(qū)知道另一個工作區(qū)上次查找記錄是否找到,而另一工作區(qū)的表可用其別名或工作區(qū)號來指定。該參數(shù)如省略,隱含為當(dāng)前工作區(qū),如有該參數(shù)的話,別名或工作區(qū)只選一個。
舉例:
locate for 姓名='莊稼'
?found()
如找到記錄,顯示結(jié)果為.t.,否則為.f.。
表結(jié)尾函數(shù)(eof())
確定記錄指針是否在表的結(jié)尾處。
語法:
eof([表別名|工作區(qū)])
返回值的類型:
邏輯型
參數(shù):
表別名|工作區(qū):該參數(shù)指定所要確定的表的別名或所在工作區(qū),即您可以在一個工作區(qū)知道另一個工作區(qū)表的指針是否在尾部,而另一工作區(qū)的表可用其別名或工作區(qū)號來指定。該參數(shù)如省略,隱含為當(dāng)前工作區(qū),如有該參數(shù)的話,別名或工作區(qū)只選一個。
備注:
這里所說的結(jié)尾處,并非是指最后一個記錄,而是最后一個記錄的后面,即沒有記錄。
舉例:
go bottom
skip
?eof()
顯示結(jié)果為.t.。
如果沒有skip,僅僅走到最后一個記錄,返回的將是.f.,而必須再往下跳一下才會是“真”結(jié)尾。
此時如輸入命令:display,則沒有記錄顯示。這一點與
bof()函數(shù)不同。
表開頭函數(shù)(bof())
確定記錄指針是否在表的開頭。
語法:
bof([表別名|工作區(qū)])
返回值的類型:
邏輯型
參數(shù):
表別名|工作區(qū):該參數(shù)指定所要確定的表的別名或所在工作區(qū),即您可以在一個工作區(qū)知道另一個工作區(qū)表的指針是否在開頭,而另一工作區(qū)的表可用其別名或工作區(qū)號來指定。該參數(shù)如省略,隱含為當(dāng)前工作區(qū),如有該參數(shù)的話,別名或工作區(qū)只選一個。
備注:
這里所說的開頭,并非是指第一個記錄,而是第一個記錄的前面。
舉例:
go top
skip -1
?bof()
顯示結(jié)果為.t.。
如果沒有skip -1,僅僅走到第一個記錄,返回的將是.f.,而必須再往上跳一下才會是“真”開頭。
但與
eof()函數(shù)不同,此時如輸入命令display,將顯示第一條記錄。
消除后續(xù)空格函數(shù)(trim())
將字符表達(dá)式的后續(xù)空格全部刪除,并將結(jié)果返回。
語法:
trim(字符表達(dá)式)
返回值的類型:
字符型
參數(shù):
字符表達(dá)式:指定的字符表達(dá)式,該函數(shù)將刪除其后續(xù)空格。
備注:
trim()函數(shù)等同于rtrim()函數(shù)。
舉例:
如表的“姓名”字段長度為10,當(dāng)前內(nèi)容為“張三”,那么如下語句:
? 姓名+'先生:'
其顯示結(jié)果是:
張三 先生:
而語句:
? trim(姓名)+'先生:'
顯示結(jié)果是:
張三先生
消除前導(dǎo)空格函數(shù)(ltrim())
將字符表達(dá)式前面的空格全部刪除,并將結(jié)果返回。
語法:
trim(字符表達(dá)式)
返回值的類型:
字符型
參數(shù):字符表達(dá)式:指定的字符表達(dá)式,該函數(shù)將刪除其后續(xù)空格。
舉例:
在講
str()函數(shù)時我們舉過一個例,即把一個字符與一個數(shù)值相加時,應(yīng)采用如下形式:
? '季度'+str(1,1)
但是當(dāng)我們沒有辦法確定這個數(shù)值的位數(shù)時,這個辦法就行不通了,您不可能規(guī)定它的長度只能是1或2等等。那么怎么辦呢,采用ltrim()函數(shù)可以解決了:
? '項目'+ltrim(str(sz))
這里假設(shè)事先已有一個數(shù)值存入了sz變量,但不知道這個數(shù)值是幾,也就更不知道有幾位數(shù),那么在隱含狀態(tài)下,str()函數(shù)將把sz轉(zhuǎn)換為長度為10的字符,其前面可能有若干空格,通過ltrim()函數(shù)的處理,不論前面有多少空格,都可以得到如下結(jié)果(假設(shè)數(shù)值是15):
項目15
更多編程命令
BLANK 命令
如果發(fā)出該命令時不帶任何參數(shù),則清除當(dāng)前記錄中所有字段的數(shù)據(jù)。
語法
BLANK
[FIELDS 字段名列表]
[范圍]
[FOR 條件]
[WHILE 條件]
[NOOPTIMIZE]
說明
如果使用了字段名列表,則清除指定字段中的數(shù)據(jù),另外也可以在字段名前面加上別名,以清除其它工作區(qū)的表中數(shù)據(jù),但要注意一點,如果當(dāng)前工作區(qū)的記錄指針指在了表的末尾,那么它也不能清除您所指定的其它工作區(qū)中的字段,即使其它工作區(qū)的記錄指針沒有指向末尾。
COPY FILE 命令
復(fù)制文件。
語法
COPY FILE 文件名1 TO 文件名2
說明
文件名中可以用“*”和“?”,如 *.prg。
要注意的一點是“文件名2”必須有,比如:
copy file *.prg to c:\temp\*.prg
不象 DOS 的 COPY 命令可以沒有目的文件名,而且命令中的“FILE”也一定要有。
COPY STRUCTURE EXTENDED 命令
將當(dāng)前工作區(qū)的表結(jié)構(gòu)信息復(fù)制到另一表中。
語法
COPY STRUCTURE EXTENDED TO 表文件名 [FIELDS 字段名表]
參數(shù)說明
FileName :指定結(jié)構(gòu)信息所存放的表文件名。
FIELDS 字段名表 :指定需要復(fù)制表結(jié)構(gòu)中哪些字段的信息,如省略,則復(fù)制所有字段的信息。
說明
該命令將一個表的各字段信息復(fù)制到一個新表中,每個字段為一個記錄,這是一個專門的表,其字段是固定,這些字段分別記錄各字段的字段名、長度、數(shù)據(jù)類型等等,各字段的字段名及其意義如下:
字段名 |
數(shù)據(jù)類型 |
意義 |
FIELD_NAME |
字符 |
字段名。 |
FIELD_TYPE |
字符 |
數(shù)據(jù)類型。C=字符型,Y=貨幣型,N=數(shù)值型,F(xiàn)=浮點型,I=整數(shù)型,B=雙精度型,D=日期型,T=日期時間型,L=邏輯型,M=備注型,G=通用型 |
FIELD_LEN |
數(shù)值 |
字段長度。 |
FIELD_DEC |
數(shù)值 |
小數(shù)位數(shù)。 |
FIELD_NULL |
邏輯 |
字段是否可用 null 值。 |
FIELD_NOCP |
邏輯 |
字段是否允許代碼頁翻譯。 |
FIELD_DEFA |
備注 |
字段的隱含值。 |
FIELD_RULE |
備注 |
字段驗證規(guī)則。 |
FIELD_ERR |
備注 |
字段驗證規(guī)則出錯時的提示信息。 |
TABLE_RULE |
備注 |
表驗證規(guī)則。 |
TABLE_ERR |
備注 |
表驗證規(guī)則出錯時的提示信息。 |
TABLE_NAME |
字符 |
長表名。 |
INS_TRIG |
備注 |
插入觸發(fā)器代碼。 |
UPD_TRIG |
備注 |
更新觸發(fā)器代碼。 |
DEL_TRIG |
備注 |
刪除觸發(fā)器代碼。 |
TABLE_CMT |
備注 |
表說明。 |
如
圖1,即為用 COPY STRUCTURE EXTENDED 命令生成的 rsda 表的結(jié)構(gòu)信息表,在這個表中就可以看到 rsda.dbf 表的各字段情況。
那么用這個命令產(chǎn)生的結(jié)構(gòu)信息表有什么用呢?這可以讓我們在編程時改變一個表的結(jié)構(gòu),因為信息結(jié)構(gòu)表也是個表,我們可以象操作一般表一樣去修改它的內(nèi)容,當(dāng)然修改時要遵從表結(jié)構(gòu)的有關(guān)規(guī)定,比如字段名不能超過10個字符,字段類型必須是上表中的字符之一,字段名不能重名等等。
當(dāng)然我們修改了這個表后不會對原表馬上產(chǎn)生作用,因為它們已經(jīng)是分別獨立的兩個表,在物理上沒有任何聯(lián)系,但我們可以首先使用以下命令:
CREATE 表文件名 FROM 結(jié)構(gòu)信息表文件名
根據(jù)結(jié)構(gòu)信息表創(chuàng)建一個新表,再將原表的數(shù)據(jù)加到這個新表中,刪除原表,將新表改為原表名,這樣就修改了表的結(jié)構(gòu)。比如,我們要將 rsda 表部門字段的長度改為20,程序如下:
select rsda && 選擇 rsda 表。 copy structure to rsdajg extended &&將 rsda 表的結(jié)構(gòu)信息復(fù)制到 rsdajg 表。 use rsdajg &&打開 rsdajg 表,同時關(guān)閉 rsda 表。 replace field_len with 20 for trim(field_name)= ='部門' &&將部門字段的字段長度修改為20。 *實際上上一句的意思是將 rsdajg 表的 field_name 為“部門”的記錄的 field_len 字段值改為20。 use &&關(guān)閉 rsdajg 表,要從這個表創(chuàng)建新表,必須將其關(guān)閉。 create rsda2 from rsdajg &&從 rsdajg 中提取信息創(chuàng)建 rsda2 表。 append form rsda &&從 rsda 表中獲取數(shù)據(jù)。 erase rsda.dbf &&刪除 rsda.dbf 表。 rename rsda2.dbf to rsda.dbf &&將 rsda2.dbf 改名為 rsda.dbf。 |
FLUSH 命令
將表和索引中的數(shù)據(jù)存入磁盤。
語法
FLUSH
說明
當(dāng)我們修改一個表時,修改完后,我們可能并不馬上將表關(guān)閉,那么這時所做的修改可能只是在內(nèi)存中,而沒有真正存到盤,如果這時死機或停電,那么......,所以我們可以在程序適當(dāng)?shù)牡胤接么嗣畲_保數(shù)據(jù)存盤。
比如,我們可以在菜單中加個“保存”命令,該命令就調(diào)用 FLUSH 語句,供操作者在適當(dāng)?shù)臅r候調(diào)用此命令來保存數(shù)據(jù)。
還可以用一個表單,在其中放一個計時器,在計時器的 timer 事件中用此命令,這樣就做成一個具有自動保存數(shù)據(jù)的功能,甚至可以在菜單中加一個設(shè)置計時器時間的命令,以供操作者設(shè)置自動保存數(shù)據(jù)的間隔時間。
FOR...ENDFOR 命令
按指定的次數(shù)循環(huán)執(zhí)行一組命令。
語法
FOR 變量=初始值 TO 結(jié)束值 STEP 步長值
命令組
[EXIT]
[LOOP]
ENDFOR | NEXT
參數(shù)描述
變量:指定一個變量作為計數(shù)器,該變量可以不預(yù)先存在,F(xiàn)OR 命令會自動創(chuàng)建。
初始值 TO 結(jié)束值:即計數(shù)器的初始值和結(jié)束值,也就是指定循環(huán)的次數(shù)。
STEP 步長值:設(shè)定計數(shù)器每次增加或減少的量,如果省略此子句,則每次增加1,比如 for jsq=1 to 10,那么將會循環(huán)10次,如果是 for jsq=1 to 10 step 2,那么循環(huán)將會是5次,因為每循環(huán)1次計數(shù)器增加2,從1到10只需增加5次就行了。
可能有人會問了,既然循環(huán)5次,那為什么不 for jsq=1 to 5 呢?這往往是為了在某些情況下使程序編起來方便和易于理解,比如要對數(shù)據(jù)表中的記錄進(jìn)行某項操作,要求每隔一條記錄做一次,起始和結(jié)束的記錄是根據(jù)具體情況變化的,也就是初始值和結(jié)束值都是變量,那么我們就可以使用步長子句,并將步長設(shè)為2,這樣就不用具體去計算到底需要多少次循環(huán)了,如果再加上步長也是變量,即有時隔一條記錄,有時會隔多條記錄,則步長子句就更必要了。
注意 |
步長的變化是指在不同次的完整循環(huán)中步長會變,一般在一次完整的循環(huán)中不要更改初始值、結(jié)束值和步長。 |
另外步長可以是負(fù)的,這又有什么必要?當(dāng)我們需要根據(jù)一個數(shù)值不斷減小來進(jìn)行某項操作時就需要了,比如我們需要對記錄進(jìn)行某項操作,這個操作要求先處理第10條記錄,再第9條(因為在處理第9條時需要根據(jù)第10條的情況),依次到第1條,那么我們就可以:
for jsq=10 tp 1 step -1 * 操作命令組 go jsq &&設(shè)上面的操作移動了記錄指針,此時已不指在第10條記錄上,則不能用 skip -1 將指針移到第9條 endfor |
很明顯,雖然可以用其它方法,但這樣編出的程序最簡潔,一目了然。
EXIT 和 LOOP:與 DO WHILE 中的意義一樣。
說明
計數(shù)器只有在大于結(jié)束值時才結(jié)束循環(huán),即當(dāng)計數(shù)器等于結(jié)束值時仍要循環(huán),也就是說:
for jsq=1 to 10
是循環(huán)10次,而不是9次,也就是當(dāng) jsq 的值為10時,還要循環(huán)一次,當(dāng)它為11時,則退出循環(huán),執(zhí)行 endfor 之后的程序。
注意 |
DO WHILE...ENDDO 與 FOR...ENDFOR 都是循環(huán),它們有什么區(qū)別呢?在需要使用計數(shù)器的情況下,由于 FOR...ENDFOR 不需要專門的計數(shù)語句,所以程序執(zhí)行的速度快,因此能用 FOR...ENDFOR 時盡量用。 |
ON ERROR 命令
設(shè)置一命令,當(dāng)系統(tǒng)錯誤發(fā)生時,該命令執(zhí)行。
這也就是程序員們常說的錯誤捕獲陷井。所謂錯誤捕獲陷井的意思就是在系統(tǒng)中啟動一個監(jiān)控程序,一旦錯誤發(fā)生,這個監(jiān)控程序就將錯誤捕獲,并不讓錯誤顯示出來,可保證程序的繼續(xù)運行,然后用一個命令去對出現(xiàn)的錯誤進(jìn)行處理,比如顯示一個錯誤提示等。如果錯誤不發(fā)生,這個命令則始終不執(zhí)行。
語法
ON ERROR [命令]
參數(shù)說明
命令:此即為指定的在捕獲錯誤后所要執(zhí)行的程序。一旦程序執(zhí)行到某個語句發(fā)生錯誤,該命令即被執(zhí)行,執(zhí)行完后,接著執(zhí)行發(fā)生錯誤的下一條語句。
提示 |
有時為了對錯誤進(jìn)行處理,一條命令可能是不夠的,則可用該命令調(diào)用一個子程序,那么需要在子程序執(zhí)行完后才接著執(zhí)行發(fā)生錯誤的下一條語句。
如果子程序中有 RETRY 命令,該命令將使子程序返回,并重新執(zhí)行發(fā)生錯誤的語句,這個命令一般用在這種情況下,當(dāng)子程序?qū)﹀e誤進(jìn)行了處理,使得再執(zhí)行該命令時不會發(fā)生錯誤了,這樣就可以使程序按照正常情況運行下去。 |
多學(xué)一招 |
當(dāng)處理錯誤子程序執(zhí)行時,您還可以用 ERROR(), MESSAGE(), LINE(), PROGRAM() 等函數(shù)返回出錯的編號、信息、出錯的語句所在行號以及出錯的程序等,這些可能對處理錯誤有幫助。 |
如省略命令參數(shù),則取消錯誤捕獲陷井。
說明
ON ERROR 命令不能嵌套,也就是說在 ON ERROR 所執(zhí)行的子程序中不能再有 ON ERROR 命令,否則等于取消錯誤捕獲。
示例
當(dāng) DBF 文件的結(jié)構(gòu)化復(fù)合索引損壞時,如果您打開 DBF 文件就會出錯,下面的例子就捕獲錯誤并自動修復(fù)索引:
*主程序 on error do xfsy &&設(shè)置錯誤陷井 use rsda &&打開表,如果索引損壞,則會產(chǎn)生錯誤,xfsy 程序?qū)䦂?zhí)行 on error &&取消錯誤陷井 ... cancel
*修復(fù)子程序 procedure xfsy &&修復(fù)子程序的過程名 erase rsda.cdx &&刪除索引文件 use rsda &&打開表 index on 編號 tag of rsda.cdx &&重建索引“編號” index on 姓名 tag of rsda.cdx &&重建索引“姓名” |
ON ESCAPE 命令
設(shè)置一命令,當(dāng)按了ESCAPE時,該命令執(zhí)行。
語法
ON ESCAPE
[命令]
參數(shù)說明
命令:該命令即為指定的按下 ESC 鍵后所要執(zhí)行的命令。
假設(shè)當(dāng)程序執(zhí)行到第10條語句時您按下了 ESC,那么在命令執(zhí)行完后,將接著執(zhí)行第11條語句,如果命令是調(diào)用一個子程序,而子程序中有 RETRY 語句,則返回重新執(zhí)行第10句。
說明
假如 ON KEY LABEL 命令也同時指定了 ESC 鍵,ON ESCAPE 所指定的命令優(yōu)先執(zhí)行。
如 SET ESCAPE OFF 則該命令也不起用。
注意 |
這個命令常常用來在一個循環(huán)中退出循環(huán),比如:
on escape exit do while .t. *循環(huán)體中的命令組 enddo on escape
這樣在循環(huán)中執(zhí)行命令時,只要您隨時動用您的玉指按下 ESC 鍵,即可令程序退出循環(huán)。
但別高興得太早,上面這個程序在執(zhí)行時常常出錯,但也不是總出錯,為什么呢?因為 exit 命令必須在循環(huán)體中,假如程序正執(zhí)行到 do while 或 enddo,這時您動了玉指,程序就會出錯,怎么解決這個問題呢?這樣:
on escape tc=.t. tc=.f. do while .t. *循環(huán)體中的命令組 if tc exit endif enddo on escape
思考題:上面這個程序為什么不會出錯? |
ON KEY LABEL 命令
指定一個命令,當(dāng)鍵盤上某個鍵(也可以是組合鍵或鼠標(biāo))被按下后,該命令執(zhí)行。
語法
ON KEY LABEL 鍵名 [命令]
參數(shù)描述
各鍵的鍵名如下:
鍵 |
鍵名 |
← |
LEFTARROW |
→ |
RIGHTARROW |
↑ |
UPARROW |
↓ |
DNARROW |
HOME |
HOME |
END |
END |
PAGE UP |
PGUP |
PAGE DOWN |
PGDN |
DEL |
DEL |
BACKSPACE |
BACKSPACE |
SPACEBAR |
SPACEBAR |
INS |
INS |
TAB |
TAB |
SHIFT+TAB |
BACKTAB |
ENTER |
ENTER |
F1 to F12 |
F1, F2, F3 ... |
CTRL+F1 to CTRL+F12 |
CTRL+F1, CTRL+F2 ... |
SHIFT+F1 to SHIFT+F12 |
SHIFT+F1, SHIFT+F2 ... |
ALT+F1 to ALT+F12 |
ALT+F1, ALT+F2, ALT+F3 ... |
ALT+0 to ALT+9 |
ALT+0, ALT+1, ALT+2 ... |
ALT+A to ALT+Z |
ALT+A, ALT+B, ALT+C ... |
CTRL+LEFT ARROW |
CTRL+LEFTARROW |
CTRL+RIGHT ARROW |
CTRL+RIGHTARROW |
CTRL+HOME |
CTRL+HOME |
CTRL+END |
CTRL+END |
CTRL+PAGE UP |
CTRL+PGUP |
CTRL+PAGE DOWN |
CTRL+PGDN |
CTRL+A TO CTRL+Z |
CTRL+A, CTRL+B, CTRL+C ... |
CTRL+0 |
CTRL+0 |
RIGHT MOUSE BUTTON |
RIGHTMOUSE |
LEFT MOUSE BUTTON |
LEFTMOUSE |
MOUSE BUTTON |
MOUSE |
ESC |
ESC |
ON KEY LABEL 鍵名 后面不跟命令則解除該鍵所要執(zhí)行的命令(即解除所設(shè)的程序陷井)。
說明
該命令的用法與 ON ESCAPE 的用法基本上是一樣的。
注意 |
該命令對于在系統(tǒng)菜單及系統(tǒng)對話框上的按鍵不起作用。
對于 on mouse 等命令,在鼠標(biāo)點擊件時不起作用。 |
示例
on key label ctrl+e tc=.t.
tc=.f.
do while .t.
*循環(huán)程序組
if tc
exit
endif
enddo
on key label ctrl+e
PACK DATABASE 命令
將數(shù)據(jù)庫所有表中作了刪除標(biāo)記的記錄物理刪除,即真正從磁盤上刪除。
語法
PACK DATABASE
說明
執(zhí)行該命令時,數(shù)據(jù)庫必須以獨占方式打開。
該命令可用于在程序中定期清理數(shù)據(jù)庫各表中的刪除記錄,因為軟件可能經(jīng)常要作刪除,對大的表會影響運行速度,所以可以在軟件中設(shè)置 set delete on,即隱去作了刪除標(biāo)記的記錄,但這些記錄并沒有真正刪除,但這些垃圾記錄太多了也對系統(tǒng)不利,故可設(shè)一功能由操作人員在需要時運行此命令來清理整個數(shù)據(jù)庫。
SCAN...ENDSCAN 命令
將記錄指針由頭到尾掃描一遍,每移動一次記錄指針可執(zhí)行一組命令。
類似于循環(huán) DO...ENDDO 或 FOR...ENDFOR,只是這是專門針對表的循環(huán)。
語法
SCAN [范圍] [FOR 條件1] [WHILE 條件2]
[命令組]
[LOOP]
[EXIT]
ENDSCAN
參數(shù)描述
范圍:在指定范圍內(nèi)掃描,即不從開頭掃描到最后。
FOR 條件1 及 WHILE 條件2:只掃描符合條件的記錄。
如果不帶范圍和條件子句,則隱含掃描表中的全部記錄。
示例
庫存日記帳表(字段有日期、入庫數(shù)、出庫數(shù),庫存數(shù)),每記錄一筆出入庫,則計算相應(yīng)的庫存數(shù)并放入表中,有時意外情況可能導(dǎo)致庫存數(shù)出錯,因此需要有一功能將庫存數(shù)重新計算一遍,下面這個程序就是完成這個功能:
go top dqkc=庫存數(shù) &&記下第一條記錄的庫存數(shù) skip &&跳到第2條記錄 scan rest &&只需掃描從第2條記錄起的所有記錄 replace 庫存數(shù) with dqkc+入庫數(shù)-出庫數(shù) dqkc=庫存數(shù) &&記下當(dāng)前記錄的庫存數(shù) endscan |
上面這段程序與下面這段程序是等價的:
go top dqkc=庫存數(shù) &&記下第一條記錄的庫存數(shù) skip &&跳到第2條記錄 do while .not. eof() replace 庫存數(shù) with dqkc+入庫數(shù)-出庫數(shù) dqkc=庫存數(shù) &&記下當(dāng)前記錄的庫存數(shù) skip endscan |
所不同的就是不用每次都 skip,系統(tǒng)自動移動記錄指針,這樣程序運行的速度快,尤其對于按條件掃描的情況就更快了,因為用 do 的話每次都要用 locate 或 continue 進(jìn)行查詢,速度很受影響。
與這段程序也是等價的:
go top dqkc=庫存數(shù) &&記下第一條記錄的庫存數(shù) skip &&跳到第2條記錄 for jsq=2 to reccount() replace 庫存數(shù) with dqkc+入庫數(shù)-出庫數(shù) dqkc=庫存數(shù) &&記下當(dāng)前記錄的庫存數(shù) skip endfor |
您喜歡用哪個呢?
注意 |
上面第三段程序中有個小問題,在 for 語句中用了 reccount() 函數(shù),而函數(shù)都要經(jīng)過運算才能得到結(jié)果,比起直接從一個變量中獲取值要慢,假如只執(zhí)行1次,兩者相差無幾,但上面是用在循環(huán)中,for 這一句可能會執(zhí)行幾十萬次,那么就會使速度降低很多,為此可改成下面這樣: ... jls=reccount() for jsq=2 to jls ... |
SET CONFIRM 命令
當(dāng)輸入的內(nèi)容填滿輸入?yún)^(qū)域時是否需要按回車鍵跳出輸入?yún)^(qū)域。
語法
SET CONFIRM ON | OFF
參數(shù)描述
ON 需要按回車鍵。也可以按 TAB 或其它箭頭鍵等。
提示 |
對表單上的文本框也起作用。當(dāng)對于需要慎重輸入的地方,可將其設(shè)置為 ON,以便讓操作者在離開輸入之前可再看一下所輸入的內(nèi)容有沒有問題,如果不設(shè)置為 ON,當(dāng)輸入內(nèi)容輸入滿時,光標(biāo)會自動離開文本框,不利于發(fā)現(xiàn)錯誤。 |
OFF 不需要按回車鍵(隱含)。
SET DEFAULT 命令
設(shè)置隱含的驅(qū)動器及目錄。
設(shè)置了隱含的路徑,我們可以在程序運行打開每個隱含路徑下的文件時不用再指定路徑了。
語法
SET DEFAULT TO [路徑]
參數(shù)說明
路徑:可以是符合操作系統(tǒng)要求的任何路徑,比如:
set default to d:\soft\rsgl
set default to \
set default to ..
注意 |
如果路徑中帶有空格,必須用引號將路徑括起來,否則會出錯。比如:
set default to "d:\soft\rsgl 佳帆" |
示例
當(dāng)我們的程序在運行時,一般我們都需要知道該程序運行所在的目錄,因為往往許多數(shù)據(jù)也是放在這個目錄下,我們不能指定一個絕對的路徑,因為程序編好后可能拿到另一臺電腦上用,其路徑可能發(fā)生變化,一旦變化便找不到所需要的數(shù)據(jù)文件了,因此我們必須有一種方法獲取其當(dāng)前所在的路徑,有一種辦法是這樣:
cxlj=sys(5)+sys(2003)+'\'
這在程序編譯成獨立 EXE 文件時運行是對的,但在 VFP 系統(tǒng)中運行 PRG 程序卻不對,它返回的是 VFP 所在的目錄,為了解決這個問題,可采用如下程序:
CXLJ=SYS(16) &&獲取當(dāng)前運行的程序名及其所在路徑 FOR JSQ=1 TO LEN(CXLJ) &&用一個循環(huán)找出最右邊一個反斜線,將其后的程序名去掉,只剩路徑 CXZF=LEFT(RIGHT(CXLJ,JSQ),1) &&從 CXLJ 的右邊依次取出每個字符 IF CXZF='\' &&查看這個字符是不是反斜線 CXLJ=STUFF(CXLJ,LEN(CXLJ)-JSQ+1,JSQ,'') &&如果是,就將反斜線之后的字符全刪掉并退出循環(huán) EXIT ENDIF ENDFOR SET DEFAULT TO "&CXLJ" &&用宏替換設(shè)置隱含路徑,用引號是為了帶空格的路徑也能正確設(shè)置 |
SET SKIP TO 命令
在表之間建立一對多關(guān)系。
語法
SET SKIP TO [表1 [, 表2] ...]
參數(shù)描述
表1 [, 表2] ... 為一對多表中的子表的別名。可以有多個子表,它們之間用逗號隔開。
如省略此參數(shù),則取消一對多關(guān)系,但一對一關(guān)系仍存在。
說明
我們用 SET RELATION 命令可創(chuàng)建表之間的一對一關(guān)系,也就是當(dāng)我們將父表的記錄指針移到某一個記錄上時,子表的記錄指針也會移到相應(yīng)的關(guān)聯(lián)記錄上,比如我們有一個人事檔案(rsda,有字段編號、姓名等),另有一個參加項目表(cjxm,有字段編號和項目,項目中記錄該人員所參加過的項目,編號建立了索引),然后用如下程序:
close all use rsda select 0 use cjxm set order to 編號 select rsda set relation to 姓名 into cjxm |
那么當(dāng)我們將 rsda 的記錄指針移到一個記錄上時,cjxm 也會移到相同編號的記錄上,但由于是一對一關(guān)系,只有 cjxm 中的相同編號的第1個記錄會與 rsda 中的記錄對應(yīng),其它的記錄不會與之對應(yīng)。
但我們知道一個人可能參加了多個項目,由于一對一的關(guān)系,我們沒法從父表中知道子表中有多少個記錄與之對應(yīng),比如這時您在父表中鍵入如下命令:
display 編號,姓名,cjxm,項目 for 編號='10'
那么只會有一條記錄出現(xiàn),因為 rsda 中只有一個編號為 10 的記錄,雖然可能他參加了多個項目,但這時不會顯示出來,要想顯示出來就必須建立一對多的關(guān)系,比如我們在 rsda 所在工作區(qū)鍵入如下命令:
set skip to cjxm
然后再運行上面的 display 命令,子表中所有對應(yīng)的記錄都會顯示出來,即可看到 10 號人員所參加的所有項目,而編號和姓名都是一樣的。
怎么樣,很不錯吧!
這時如果您用 browse 看 rsda 表,假如 cjxm 中有多條編號為 10 的記錄,您會發(fā)現(xiàn) 10 號記錄下面會多出幾條記錄來,它們的內(nèi)容全部是“*”,且不可修改,這就是系統(tǒng)根據(jù)一對多關(guān)系增加的假記錄,依靠這些記錄,上面的 display 命令才能帶來我們想要的結(jié)果。
注意 |
如果這時刪除子表中的記錄,且做了 pack,那么關(guān)聯(lián)將被解除,包括一對多和一對一,如仍需要一對多關(guān)系,必須重新用 set relation 和 set skip to 建立一對多關(guān)系。 |
思考題
大家思考下用 set skip to 是否能很好地解決問題。
在中文版VFP6.0中,有一些數(shù)據(jù)分布在三個數(shù)據(jù)庫中,如A庫中有各個企業(yè)的基本情況,在B庫中有各個企業(yè)的董事會組成成員情況,在C庫中有各個企業(yè)的分支機構(gòu)情況,三者可以通過企業(yè)編號進(jìn)行索引,其相互關(guān)系是:A庫中一個記錄即一個企業(yè),對應(yīng)于B庫中的至少三個記錄(即不同的組成成員),再對應(yīng)于C庫中的至少三個記錄(即不同的分支機構(gòu)),現(xiàn)在的問題是,我如何能在一張頁面上,同時打印A庫中的一條記錄,B庫和C庫中的三條以上的記錄。 |
SET SKIP OF 命令
設(shè)置菜單或菜單項是否跳過,即是否可用。
語法
SET SKIP OF MENU 主菜單名 邏輯表達(dá)式
SET SKIP OF PAD 主菜單項名 OF 主菜單名 邏輯表達(dá)式
SET SKIP OF POPUP 子菜單名 邏輯表達(dá)式
SET SKIP OF BAR 子菜單項 OF 子菜單名 邏輯表達(dá)式
參數(shù)描述
MENU 主菜單名 邏輯表達(dá)式
設(shè)置主菜單是否跳過,邏輯表達(dá)式為“真”時跳過,即整個菜單不可用,反之則可用。
例如,可以使用以下命令禁止 VFP 的系統(tǒng)菜單 _MSYSMENU:
set skip of menu _msysmenu .t.
使用以下命令則啟用它:
set skip of menu _msysmenu .t.
PAD 主菜單項名 OF 主菜單名 邏輯表達(dá)式
設(shè)置主菜單中某個菜單項是否跳過,如果設(shè)置為跳過,假如該項下有子菜單,則子菜單不能拉下來。
可用如下命令禁止 VFP 主菜單上的“編輯”菜單:
set skip of pad _msm_edit of _msysmenu .t.
POPUP 子菜單名 邏輯表達(dá)式
設(shè)置某個子菜單是否跳過,如設(shè)置為跳過,該子菜單可以拉下,但其中的菜單項都不可用。
可用如下命令禁止 VFP 的“編輯”子菜單:
set skip of popup _medit .t.
BAR 子菜單項 OF 子菜單名 邏輯表達(dá)式
設(shè)置某個子菜單中的某個菜單項是否跳過。
可以用下面的命令設(shè)置 VFP “文件”子菜單中的“新建”不可用:
set skip of bar _mfi_new of _mfile .t.
說明
那么對于菜單設(shè)計器設(shè)計的我們自己的菜單怎樣進(jìn)行設(shè)置呢?其實當(dāng)我們用菜單設(shè)計器設(shè)計好一個菜單并完成生成后,就會生成一個擴展名為 mpr 的菜單程序,它與 prg 程序是一樣的,我們可以用如下命令將其打開來看:
modify command xxx.mpr
打開后我們就可以看到其中的主菜單名及其相應(yīng)的主菜單項、子菜單、子菜單項等。下面便是一個 mpr 文件:
*菜單的說明信息略
SET SYSMENU TO SET SYSMENU AUTOMATIC DEFINE PAD _s950ndhs4 OF _MSYSMENU PROMPT "系統(tǒng)錄入及查詢" COLOR SCHEME 3 DEFINE PAD _s950ndhs6 OF _MSYSMENU PROMPT "系統(tǒng)維護" COLOR SCHEME 3 DEFINE PAD _s950ndhs7 OF _MSYSMENU PROMPT "統(tǒng)計" COLOR SCHEME 3 DEFINE PAD _s950ndhs8 OF _MSYSMENU PROMPT "備份數(shù)據(jù)" COLOR SCHEME 3 ON PAD _s950ndhs4 OF _MSYSMENU ACTIVATE POPUP 系統(tǒng)錄入及 ON PAD _s950ndhs6 OF _MSYSMENU ACTIVATE POPUP 系統(tǒng)維護 ON PAD _s950ndhs7 OF _MSYSMENU ACTIVATE POPUP 統(tǒng)計 ON PAD _s950ndhs8 OF _MSYSMENU ACTIVATE POPUP 備份數(shù)據(jù)
*主菜單即為 _MSYSMENU *主菜單中的菜單項分別為 _s950ndhs4, _s950ndhs6 等 *_s950ndhs4 下的子菜單是“系統(tǒng)錄入及” *_s950ndhs6 下的子菜單是“系統(tǒng)維護” DEFINE POPUP 系統(tǒng)錄入及 MARGIN RELATIVE SHADOW COLOR SCHEME 4 DEFINE BAR 1 OF 系統(tǒng)錄入及 PROMPT "數(shù)據(jù)錄入" ; KEY ALT+L, "ALT+L" ; MESSAGE '錄入房地產(chǎn)廣告信息' DEFINE BAR 2 OF 系統(tǒng)錄入及 PROMPT "數(shù)據(jù)查詢" ; KEY ALT+C, "ALT+C" ; MESSAGE '查詢和修改錄入的房地產(chǎn)廣告信息' DEFINE BAR 3 OF 系統(tǒng)錄入及 PROMPT "數(shù)據(jù)整理" ; KEY ALT+Z, "ALT+Z" ; MESSAGE '如發(fā)現(xiàn)數(shù)據(jù)有問題,可調(diào)用此命令進(jìn)行整理,如整理后仍有問題,請與軟件供應(yīng)商聯(lián)系' DEFINE BAR 4 OF 系統(tǒng)錄入及 PROMPT "\-" DEFINE BAR 5 OF 系統(tǒng)錄入及 PROMPT "退出系統(tǒng)" ; KEY ALT+E, "ALT+E" ON SELECTION BAR 1 OF 系統(tǒng)錄入及 do sjlr ON SELECTION BAR 2 OF 系統(tǒng)錄入及 do lrsjcx ON SELECTION BAR 3 OF 系統(tǒng)錄入及 do sjzl ON SELECTION BAR 5 OF 系統(tǒng)錄入及 clear event
*“系統(tǒng)錄入及”子菜單中的各菜單項為 1、2、3 等
*以下略 |
比如可以在程序中使“系統(tǒng)錄入及查詢”下的“數(shù)據(jù)整理”不可用,即“系統(tǒng)錄入及”子菜單中的第3個菜單項,命令為:
set skip of bar 3 of 系統(tǒng)錄入及 .t.
我們知道在菜單設(shè)計器可為每個菜單項設(shè)置跳過表達(dá)式,那么這個命令還有什么用嗎?有時用它還是比較方便,比如我們要讓一個子菜單中的所有菜單項不可用,我們可以設(shè)置該子菜單不可用,如用跳過要一個個菜單項去設(shè),或者每個菜單項都設(shè)一個比較復(fù)雜的表達(dá)式,再要不就設(shè)調(diào)這個子菜單的主菜單項不可用,那樣又看不到子菜單中有什么內(nèi)容了(有時雖然不可用但也想看看),總之是比較麻煩,那么用這個命令就好一些。
不好的地方是要把 mpr 程序打開來記住那些菜單名、菜單項,你們也看到上面了,不是那么好記的。反正這個世界沒有十全十美的東西,我們只好將就點了。
VALIDATE DATABASE 命令
保證當(dāng)前庫中表和索引位置的正確性。
語法
VALIDATE DATABASE
[RECOVER]
[NOCONSOLE]
[TO PRINTER [PROMPT] | TO FILE 文件名]
參數(shù)描述
RECOVER:顯示一個對話框,該對話框允許您定位表和索引,這些表和索引不在被檢查的數(shù)據(jù)庫, 中。必須在命令窗口中發(fā)出 VALIDATE DATABASE RECOVER 命令,在程序中發(fā)布該命令會產(chǎn)生錯誤信息。
NOCONSOLE:如發(fā)現(xiàn)數(shù)據(jù)庫中有錯誤,不向屏幕輸出錯誤信息。
TO PRINTER [PROMPT]:打印錯誤信息。
TO 文件名:將錯誤信息輸出到一個文件。
說明
該命令確保數(shù)據(jù)庫包含的表和索引處于正確位置,確保數(shù)據(jù)庫中的表包含正確的字段,以及確定數(shù)據(jù)庫中索引標(biāo)識是否存在。
該命令對當(dāng)前數(shù)據(jù)起作用,而且要求數(shù)據(jù)庫必須是以獨占方式打開。
雖然該命令一般不用在程序中,但由于一些初學(xué)者是第一次接觸數(shù)據(jù)庫(不是表),故這個命令還是有必要講一下。當(dāng)我們發(fā)現(xiàn)數(shù)據(jù)庫有不正常的情況時,就可用這個命令檢測和恢復(fù)數(shù)據(jù)庫。
示例
下面的示例打開 testdata 數(shù)據(jù)庫,并使用 VALIDATE DATABASE 命令,以確保表和索引的位置在數(shù)據(jù)庫中是正確的。
close databases set path to (home(2)+'data\') &&設(shè)置數(shù)據(jù)庫路徑 open database testdata exclusive &&以獨占方式打開數(shù)據(jù)庫
validate database |
CALCULATE 命令
對字段或帶有字段的表達(dá)式進(jìn)行統(tǒng)計計算。
語法
CALCULATE 表達(dá)式列表
[范圍][FOR 條件][WHILE 條件]
[TO 變量列表| TO ARRAY 數(shù)組名]
[NOOPTIMIZE]
參數(shù)描述
表達(dá)式列表
這里所用到的表達(dá)式與其它命令中所用到的表達(dá)式不一樣,這里必須是規(guī)定的幾個函數(shù)表達(dá)式,如下:
函數(shù) |
含義 |
AVG(表達(dá)式) |
計算表達(dá)式的平均值。 |
CNT() |
返回表中記錄的個數(shù)。 |
MAX(表達(dá)式) |
返回表達(dá)式中的最大值。 |
MIN(表達(dá)式) |
返回表達(dá)式中的最小值。 |
NPV(表達(dá)式1,表達(dá)式2,[表達(dá)式3]) |
計算一個固定周期利率下,一系列現(xiàn)金流的凈現(xiàn)值。表達(dá)式1為十進(jìn)制表示利率;表達(dá)式2代表一系列現(xiàn)金流的字段、字段表達(dá)式或數(shù)值表達(dá)式,每個現(xiàn)金流可正可負(fù),當(dāng)它是字段時,每個記錄的字段值都認(rèn)為是一個現(xiàn)金流;表達(dá)式3指定可選的初始投資,如果不包括初始投資,則假定初始投資發(fā)生在第一階段末,這個初始投資就是第一個記錄,而且是負(fù)的,代表現(xiàn)金流出。 |
STD(表達(dá)式) |
計算表達(dá)式的標(biāo)準(zhǔn)偏差。 |
SUM(表達(dá)式) |
對表達(dá)式的值求和。 |
VAR(表達(dá)式) |
計算表達(dá)式的均方差。 |
注意:這里的函數(shù)是不能單獨使用的,它們與單獨同名的函數(shù)也是不一樣的,比如,CALCULATE MIN() 與 MIN() 是不同的,前者計算某一字段中各記錄的最小值,函數(shù)只需寫一個字段名,后者則是計算一系列表達(dá)式中的最小值,所有的表達(dá)式都必須寫入函數(shù)中。
TO 變量列表
將計算結(jié)果存入指定的變量。注意變量列表中的變量數(shù)必須與表達(dá)式列表中的表達(dá)式個數(shù)相同。
TO ARRAY 數(shù)組名
將計算結(jié)果存入指定的數(shù)組。數(shù)組可存在,系統(tǒng)會自動創(chuàng)建,數(shù)組中的元素也不一定與表達(dá)式列表中的個數(shù)一樣,如果不夠,系統(tǒng)會自動增加,如果多了,則多出的元素保持不變。
示例
CALCULATE SUM(工資),AVG(工資),MIN(工資),MAX(工資) TO HJ,PJ,ZX,ZD
計算出工資合計、平均工資、最少工資、最多工資,并分別存入各變量。
從這個例子可以看出,用這個命令比分別用 SUM、AVERAGE 等命令方便,且執(zhí)行的速度快,因為它只需要將表掃描一次就能將各值計算出來了,而分別用命令就要掃描幾次,對于一個很大表這可不能等閑視之。