第六章 函数
6-1 函数的定义
函数(function),简单的定义就是一再重复某一串指令,以达到某特定功能。
6-2 函数的叙述 <语法格式> FUNCTION function_name([参数串行]) [define 参数串行 资料型态串行]
...
statement
...
[return 运算串行]
...
END FUNCTION
§例:
function delete_employee()
define p_stuff_num like employee.stuff_num
prompt "请输入欲删除的员工编号" for p_stuff_num
delete from employee
where stuff_num = p_stuff_num
end function
6-2 呼叫函数
<语法格式>
CALL function([([参数串行]) [RETURNING 变量串行]
§例:
database psn
main
call delete employee()
end main
function delete_employee()
define p_stuff_num like employee.stuff_num
prompt "请输入欲删除的员工编号" for p_stuff_num
delete from employee
where stuff_num = p_stuff_num
end function
6-3 (side-effect) 函数
§例:
if passwd_check_ok() then
...
6-4 GLOBALS 叙述
当使用者要宣告通用变量时,必须使用 GLOBALS 叙述
<语法格式>
GLOBALS
DEFINE_STATEMENT
...
END FLOBALS
1.globals 必须定义在程序的最前面。
2.若使用 LIKE 关健字时,则在 globals 之前必须有 database 的叙述。
6-5 变量传递的范围
┌──────────────────────────┐ │ globals │ │ define variable a │ | ┌────────────────┐ | │ | main │ | │ | define variable b │ | │ └────────────────┘ | | ┌────────────────┐ | │ | function │ | │ | define variable c │ | │ └────────────────┘ | │ │ └──────────────────────────┘
┌────────────────────────┐ │ 叙述 变量 型态 范围 │ ├────────────────────────┤ │ globals a 通用性 main | │ function | ├────────────────────────┤ │ main b 区域性 main │ ├────────────────────────┤ │ function c 区域性 function │ └────────────────────────┘
§例:
A.4GL
┌──────────────────────────┐ │ │ │ globals │ │ define var_a char(1) │ | end globals | │ │ │ main | │ let var_a = 'A' | │ call test_global() | │ call test_global() | │ end main │ │ │ └──────────────────────────┘
B.4GL
┌──────────────────────────┐ │ │ │ globals "A.4GL" │ │ define var_b char(1) │ │ │ | function test_global() | │ define var_c char(1) │ │ display "=========" | │ display "var_a = ", a | │ display "var_b = ", b | │ display "var_c = ", c | │ let var_b = 'B' | │ let var_c = 'C' | │ end function │ │ │ └──────────────────────────┘
结果:
=========
var_a = A
var_b = ?
var_c = ?
=========
var_a = A
var_b = B
var_c = ?
6-6 参数的传递
function 中的参数必须在 function 中事先用 define 定义。function 中的参数可为记录型态资料,但不可以包含数组元素,以及在记录名称之后使用 .* 的形式。
§例:
function get_price(price,amount)
define price,amount money(6,2)
...
end function
§例:
function show_data(p_employee)
define p_employee record like employee.*
...
end function
※※ 参数的值来自于呼叫函数叙述,因此参数的资料型态必须和呼叫函数叙述的资料型态保持一致。
6-7 函数传回值呼叫程序
函数传值回主程序,可以在函数中使用 return 叙述,和在 call 叙述中使用returning 子句,来达成目的。
<语法格式>
CALL function_name( ) RETURNING variable_list
...
RETURN expression
§例:
main
define price,quality smallint
let price = 10
let quality = 100
let total_tax = 1.05 * get_price(price,quality)
display "完税后:",total_tax at 24,1
end main
function get_price(price,quality)
define price,quality,total_price smallint
let total_price = price*quality
return total_price
end function
第七章 资料的处理
7-1 新增的处理
<语法格式>
INSERT INTO table_name[(column_list)] value (value_list)
§例:
FOR i = 1 TO curr_ssaltab.fins_tot
INSERT INTO sfamilytab valueS(s_st.*)
IF SQLCA.SQLCODE != 0 OR SQLCA.SQLERRD[3] <= 0 THEN
ERROR "sfamilytab 新增失败 !!"
SLEEP 2
END IF
END FOR
在未被新增的部份行,系统会自动设定 null 值
§例:
FOR i = 1 TO curr_ssaltab.fins_tot
INSERT INTO sfamilytab (sfamilytab.idno,sfamily.emp_name)
valueS(s_st.idno,s_st.emp_name)
IF SQLCA.SQLCODE != 0 OR SQLCA.SQLERRD[3] <= 0 THEN
ERROR "sfamilytab 新增失败 !!"
SLEEP 2
END IF
END FOR
§例:
INSERT INTO taxtemp(idno,format_ty,total_amt,total_tax)
SELECT idno, format_ty, SUM(net),SUM(tax)
FROM staxdetailtab
GROUP BY idno,format_ty
HAVING SUM(net) >= 500
7-2 更正的处理
<语法格式一>
UPDATE table_name
SET column_name = exp[, ...]
[WHERE clause]
§例:
UPDATE ssaltab
SET ssaltab.tax_fee = curr_ssaltab.tax_fee
WHERE ssaltab.idno = curr_ssaltab.idno
IF SQLCA.SQLCODE = 0 AND SQLCA.SQLERRD[3] > 0 THEN
ERROR "更正成功"
ELSE
ERROR "更正失败 !! ==> 请通知系统人员,谢谢"
RETURN
END IF
<语法格式二>
UPDATE table_name
SET table_name.* = record_name.*
[WHERE clause]
§例:
UPDATE ssaltab
SET ssaltab.* = curr_ssaltab.*
WHERE ssaltab.idno = curr_ssaltab.idno
IF SQLCA.SQLCODE = 0 AND SQLCA.SQLERRD[3] > 0 THEN
ERROR "更正成功"
ELSE
ERROR "更正失败 !! ==> 请通知系统人员,谢谢"
RETURN
END IF
7-3 删除的处理
<语法格式>
DELETE FROM table_name
[WHERE clause]
§例:
DELETE
FROM sfamilytab
§例:
DELETE
FROM sfamilytab
WHERE idno = curr_ssaltab.idno
7-4 查询的处理
<语法格式>
SELECT
INTO
FROM
WHERE
GROUP BY
HAVING
ORDER BY
7-4-1 查询单一的列
<语法格式>
SELECT select_list INTO variable_list
FROM table_list
[WHERE clause]
§例:
SELECT emp_name,stuff_num
INTO curr_ssaltab.emp_name,curr_ssaltab.stuff_num
FROM ssaltab
WHERE ssaltab.idno = curr_ssaltab.idno
§例:
SELECT *
INTO curr_ssaltab.*
FROM ssaltab
WHERE ssaltab.idno = curr_ssaltab.idno
7-4-2 查询一个以上的列
查询一个以上的列,必须使用宣告光标(cursor)的方式.光标分成下列两种型态:
1.非卷动式的光标(non_scrolling cursor),可以依序(sequential)取出所有资料
2.卷动式的光标(scrolling cursor),可以随机撷取取出所有数据
<语法格式>
DECLARE cursor_name [SCROLL] CURSOR [WITH HOLD] FOR
SELECT statement
此处的 cursor_name 必须是唯一,不可重复
§例:
DECLARE pointer CURSOR FOR
SELECT family_name,family_idno
FROM sfamilytab
WHERE idno = curr_ssaltab.idno
§例:
DECLARE pointer CURSOR FOR
SELECT family_name,family_idno
FROM sfamilytab
ORDER BY family_idno
7-5 挑选资料的方式
1.FOREACH 循环,相当于 WHILE 循环和 FETCH 命令的组合
<语法格式>
FOREACH cursor_name [INTO 变量串行]
statement
...
[continue foreach]
...
[exit foreach]
...
END FOREACH
§例:
DEFINE p_st ARRAY[20] OF RECORD
family_name LIKE sfamilytab.family_name,
family_idno LIKE sfamilytab.family_idno
END RECORD
DECLARE family_cursor CURSOR FOR
SELECT family_name,family_idno
FROM sfamilytab
WHERE idno = curr_ssaltab.idno
FOREACH family_cursor INTO p_st[arr_cnt].*
LET arr_cnt = arr_cnt + 1
IF arr_cnt > 20 THEN
EXIT FOREACH
END IF
IF p_st[arr_cnt].family_name is NULL THEN
CONTINUE FOREACH
END IF
...
END FOREACH
2.OPEN-FETCH-CLOSE
其实 foreach 当于 open 指针,fetch 资料和 close 指针和 FETCH 命令的
组合
A.OPEN 叙述:开启一个先前 declare 过的指针
<语法格式>
OPEN 指针名称 [USING 变量串行]
using 后的变量串行是程序串行,对应到 select 中的”?”参数
§例:
DECLARE family_cursor CURSOR FOR
SELECT family_name,family_idno
FROM sfamilytab
WHERE idno = curr_ssaltab.idno
OPEN family_cursor
§例:
DECLARE family_cursor CURSOR FOR
SELECT family_name,family_idno
FROM sfamilytab
WHERE idno = ?
PROMPT "请输入欲查询之身份证号码" FOR curr_ssaltab.idno
OPEN family_cursor USING curr_ssaltab.idno
B.FETCH 叙述
在 declare 宣告一个可卷动(scroll)指针后,使用 fetch 移动指针
<语法格式>
FETCH[next|previous|prior|first|last|current|relative m|absolute n]
指针名称 [INTO 变量串行]
§例:
FETCH FIRST ssaltab_cursor INTO p_ssaltab.*
FETCH NEXT ssaltab_cursor INTO next_ssaltab.*
FETCH RELATIVE +2 ssaltab_cursor INTO next_ssaltab.*
FETCH RELATIVE -2 ssaltab_cursor INTO prev_ssaltab.*
FETCH PRIOR ssaltab_cursor INTO prev_ssaltab.*
FETCH LAST ssaltab_cursor INTO curr_ssaltab.*
FETCH ABSOLUTE i ssaltab_cursor INTO p_ssaltab.*
C.CLOSE 叙述
关闭一个先前 declare 开启过的指针
<语法格式>
CLOSE 指针名称
§例:
CLOSE ssaltab_cursor
7-6 查询与范围叙述 BETWEEN 和 AND
<语法格式>
WHERE column_name
[NOT] BETWEEN exp_1 AND exp_2
§例:
DECLARE family_cursor CURSOR FOR
SELECT *
FROM sfamilytab
WHERE stuff_num BETWEEN 8208001 AND 8307999
§例:
DECLARE family_cursor CURSOR FOR
SELECT *
FROM sfamilytab
WHERE stuff_num BETWEEN ? AND ?
PROMPT "请输入欲查询之员工号码之范围从" FOR beg_stuff_num
PROMPT "至" FOR end_stuff_num
OPEN family_cursor USING beg_stuff_num,end_stuff_num
7-7 查询与集合叙述 IN
<语法格式>
WHERE column_name [NOT] IN (value1,value2,... valuen)
§例:
DECLARE family_cursor CURSOR FOR
SELECT *
FROM sfamilytab
WHERE zipcode IN (700,701,702,703,704 ...)
7-8 查询与模式配对叙述 MATCHES
<语法格式>
WHERE char_column MATCHES "value"
其中 char_column 必须是文字型态的值,而 value 也必须用双引号括起的文字值。一般 matches 可用一些特别的文字符号来处理文字配对。其种类有下面3种:
1.*:可以零个或多个字符.
2.?:可以代替任何单一字符.
3.[...]:可以代替在中括号里面的任何字符,并可以设定字符范围,如 [a_z];如在中括号里面的第一个字符为( ^ ),意思为”非”, 表示配对不在中括号的任何字符。
§例:
1.matches "B*"
2.matches "a?b"
3.matches "[nN]"
4.matches "[^nN]"
§例:
DECLARE family_cursor CURSOR FOR
SELECT *
FROM sfamilytab
WHERE emp_name MATCHES "陈*"
7-9 从多个表查询资料
<语法格式>
SELECT column_list
FROM table1,table2
WHERE [table1.]column=[table2.]column
§例:
DECLARE family_cursor CURSOR FOR
SELECT family_name,employee_name
FROM sfamilytab,employee
WHERE sfamily.idno = employee.idno
§例:
DECLARE family_cursor CURSOR FOR
SELECT family_name,employee_name
FROM sfamilytab,employee
WHERE idno = id
7-9-1 informix-4gl 关连式数据库选取资料说明:
§例:
TABLE A TABLE B
字段 1│ KEY 字段 2│ KEY ────┼──── ────┼──── A │ k1 X │ k1 B │ k2 Y │ k2 C │ k2 │ │ └─────────────┘
SELECT 字段1,字段 2
FROM A,B
WHERE A.key = B.key
结果:
字段1 │ 字段2 ────┼──── A │ X B │ Y C │ Y
§例: TABLE A TABLE B 字段 1│ KEY 字段 2│ KEY ────┼──── ────┼──── A │ k1 X │ k1 B │ k2 Y │ k2 C │ k3 Z │ k2 │ │ └─────────────┘
SELECT 字段1,字段 2
FROM A,B
WHERE A.key = B.key
结果:
字段1 │ 字段2 ────┼──── A │ X B │ Y B │ Z
§例:
TABLE A TABLE B 字段 1│ KEY 字段 2│ KEY ────┼──── ────┼──── A │ k1 X │ k1 B │ k2 Y │ k2 C │ k3 Z │ k2 │ │ └─────────────┘
SELECT 字段1,字段 2
FROM A,OUTER B
WHERE A.key = B.key
结果:
字段1 │ 字段2 ────┼──── A │ X B │ Y B │ Z C │
§例:
TABLE A TABLE B TABLE C 字段 1│ KEY 字段 2│ KEY 字段 3│ KEY ────┼──── ────┼──── ────┼──── 1 │ k1 2 │ k2 3 │ k3 2 │ k2 3 │ k3 5 │ k5 3 │ k3 4 │ k4 │ 5 │ k5 │ │ │ │ │ └───────────┴───────────┘
SELECT *
FROM A,B,C
WHERE A.key = C.key
结果:
字段1 │ 字段2 │ 字段3
────┼────┼──── 3 │ 2 │ 3 3 │ 3 │ 3 3 │ 4 │ 3 5 │ 2 │ 5 5 │ 3 │ 5 5 │ 4 │ 5
SELECT *
FROM A,B,OUTER C
WHERE A.key = C.key
结果:
字段1 │ 字段2 │ 字段3 ────┼────┼──── 1 │ 2 │ - 1 │ 3 │ - 1 │ 4 │ - 2 │ 2 │ - 2 │ 3 │ - 2 │ 4 │ - 3 │ 2 │ 3 3 │ 3 │ 3 3 │ 4 │ 3 5 │ 2 │ 5 5 │ 3 │ 5 5 │ 4 │ 5
§例:
SELECT *
FROM A,B,C
WHERE A.key = C.key
结果:
字段1 │ 字段2 │ 字段3 ────┼────┼──── 3 │ 2 │ 3 3 │ 3 │ 3 3 │ 4 │ 3 5 │ 2 │ 5 5 │ 3 │ 5 5 │ 4 │ 5
§例:
SELECT *
FROM A,OUTER B,OUTER C
WHERE A.key = B.key
AND A.key = C.key
结果:
字段1 │ 字段2 │ 字段3 ────┼────┼──── 1 │ - │ - 2 │ 2 │ - 3 │ 3 │ 3 5 │ - │ 5 例:
SELECT *
FROM A,OUTER(B,C)
WHERE A.key = C.key
结果:
字段1 │ 字段2 │ 字段3 ────┼────┼──── 1 │ - │ - 2 │ - │ - 3 │ 2 │ 3 3 │ 3 │ 3 3 │ 4 │ 3 5 │ 2 │ 5 5 │ 3 │ 5 5 │ 4 │ 5
§例:
SELECT *
FROM A,OUTER(B,OUTER C)
WHERE A.key = B.key
AND B.key = C.key
结果: 字段1 │ 字段2 │ 字段3 ────┼────┼──── 1 │ - │ - 2 │ 2 │ - 3 │ 3 │ 3 5 │ - │ -
第八章 萤幕画面(form)的制作 8-1画面规格之架构
画面之规格主要是由DATABASE,SCREEN,TABLES,ATTRIBUTES和INSTRUCTIONS所组成的。
8-1-2 DATABASE 区间
<语法格式>
DATABASE database_name 或DATABASE formONLY
§例:
DATABASE payroll
§例:
DATABASE formONLY
database formonly 表示在整个画面表格的所有的字段名,在数据库中没有相对应的资料表格及字段名。一般这种画面表格,是用来作为交谈式画面的输出入。因此,和数据库没有直接关连。
8-1-3 SCREEN 区间
<语法格式>
SCREEN
{
屏幕画面文字叙述 [字段号码] ...
...
}
END
在 screen 关健字后用一个左括符号{做为开始,并在end关健字前用一个右括符号}做为结束,其中end关健字为选择性的。
§例:
DATABASE payroll
SCREEN
{
身分证字号:[f01 ]教职员工号:[f24 ] 姓 名:[f02 ]
员工编号 :[m][n ][fi][fj ][f08] 服务单位:[f06 ]
核薪职等 :[f09 ][f10 职 称:[f07 ]
本 薪 :[f11] 功俸:[f26] 本俸级别:[fb ]
补助费级别:[fc] 主管级别:[b ]
资薪单位 :[e][ee ] 职 别:[c][f12 ]
异动日期 :[f14 ] 到职日期:[f25 ]
保险别 :[d][fl ] 保险号:[insu ] 福利互助:[h]
眷保总人数:[z] 眷保人数 :[w] 扶养人数:[fe]
合并眷口数: 房屋津贴:[j][fo]
研究费 :[x] 学人房贴:[y][yy ]
银行帐号 :[f17 ] 公教帐号:[f21 ]
}
END
§例:
DATABASE formONLY
SCREEN
{
★ 人事薪俸作业 ★
====================
1.人事基本档设定 2.薪资资料查询
3.各类代扣款设定 4.补发缴回作业
5.员工编号更正 6.单位名册
7.交通费作业 8.实物代金作业
9.按姓名次序名册 A.钟点费人事作业
[a]
}
END
screen 的大小不可以超过20列,因系统保留屏幕画面的4列来做为显示,提示,批注和错误讯息之用。
8-1-3-1显示字段
屏幕画面的显示字段可以让使用者输入资料和提供系统显示资料之用。
<语法格式>
[field_tag]
field_tag 为屏幕画面辨识字段的旗竿,所以在 attributes 区间必须有定义,除非用屏幕数组( screen array)的方示,否则每一个显示字段必须是唯一的字段旗竿.字段的命名最多50个字,且第一个字必须是英文字,其余是文数自或底线 ˍ 的组合。
8-1-3-2 字段分界符号
一般都是用中括号〔〕来做为字段的分界符号,但也可以用其它字符当做分界符号,只是在 instructions 区间使用delimiters 叙数来重新设定分界符号。由于相邻的字段间,若用 [][] 分隔,则屏幕至少占用两个空格,似呼浪费了一格空间。因此,可以用 "|" 符号来代替两栏间的符号 " ][ "。
§例:
DATABASE payroll
SCREEN
{
身份证字号:[f01 ] 姓 名:[f02 ] 员工编号:[a][b ][c ][d ][e ]
服务单位 :[f03 ] 职 称:[f04 ]
核薪职等 :[f05 ][f06 ] 资薪单位:[g]
[j ]
所得 所得 应 应税
所得日期 代码 所得类别 金额 税 所得 所得税 合计
=====================================================================
[y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 |k|l|m]
[y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 |k|l|m]
[y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 |k|l|m]
[y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 |k|l|m]
[y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 |k|l|m]
[y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 |k|l|m]
}
END
8-1-4 TABLE 区间
<语法格式>
TABLE table_name1,table_name2,...
若在 database 区间,宣告 database formonly,则此区间可以省略。另外table最多可以宣告使用14个 table,而且每一个 table 必须属于在 database区间里所设定的数据库。
§例:
TABLES
ssaltab
sincotab
sintytab
§例:
TABLES
sdistab,sdedutab,sbanktab,ssaltab
8-1-5 ATTRIBUTES 区间
<语法格式一>
字段编号=[数据库 table.]字段[,属性串行];
<语法格式二>
字段编号=formONLY.字段名[TYPE[资料型态|LIKE 资料 table.字段名]]
[NOT NULL][,属性串行];
§例:
ATTRIBUTES
f01 = ssaltab.idno,UPSHIFT,AUTONEXT;
m = ssaltab.proj_ty,formAT="&",COMMENTS="工作计划",AUTONEXT;
fj = ssaltab.pos_ty,formAT="&&&",AUTONEXT;
f02 = ssaltab.emp_name,AUTONEXT;
f06 = ssaltab.unit_name,NOENTRY;
f07 = ssaltab.pos_name,NOENTRY;
d = ssaltab.ins_ty,COMMENTS="0.无 1.公保 2.劳保 3.满三十年公保 "
,INCLUDE=("0" TO "3") ,AUTONEXT;
h = ssaltab.wel_num,COMMENTS="0.无 1.有",INCLUDE=(0 TO 1),AUTONEXT;
w = ssaltab.fins_num,INCLUDE=(0 TO 5) ,AUTONEXT;
j = ssaltab.house_ty,COMMENTS="0.无 1.有扣房屋津贴 ",
INCLUDE=("0","1"),AUTONEXT;
f17 = ssaltab.account_no,PICTURE = "#####",AUTONEXT;
f21 = ssaltab.paccount_no,PICTURE = "#####",AUTONEXT;
fl = formONLY.char6,NOENTRY;
insu = ssaltab.insure_no,AUTONEXT;
fo = formONLY.char5,NOENTRY;
a = plantab.yy, formAT = "&&",REVERSE, AUTONEXT;
k = plantab.budget, formAT = "#,###,###,##&",
COLOR = REVERSE WHERE k IS NOT NULL, AUTONEXT;
l = plantab.net_budget , formAT = "-,---,---,--&", AUTONEXT,
COLOR = RED blink WHERE l < 0
8-1-6 INSTRUCTIONS 区间
1.定义屏幕记录
2.改变显示字段预设的分界符号
8-1-6-1 定义屏幕记录
<语法格式一>
SCREEN RECORD rec_name(field_name1 THRU field_name2)
rec_name表示屏幕记录的名称,field_name1表示范围内第一个字段,field_name2 表示范围内最后一个字段.
§例:
INSTRUCTIONS
SCREEN RECORD (employee.idno THRU employee.address)
END
表示屏幕记录包括了从 employee_no 至 employee_address 的字段的次序和attributes 区间的字段的次序相同.
<语法格式二>
SCREEN RECORD rec_name(field_list)
fiels_list 可以是一个或一个以上用逗点分开的字段,
§例:
INSTRUCTIONS
SCREEN RECORD s_dispitem (loan_no,bank_no,amt,account_no)
END
<语法格式三>
SCREEN RECORD rec_name(table.*)
在 table.* 中的 table 是在 table 区间所宣告过的 table ,* 表示屏幕记录包括 table中所有的字段,这些字段的次序和 attributes 区间的字段的次序相同。
§例:
INSTRUCTIONS
SCREEN RECORD s_dispitem (employee.*)
END
8-1-6-2 改变显示字段预设的分界符号
<语法格式>
DELIMITERS "ab"
a 表示起始分界符号,b 表示结尾分界符号。
§例:
DELIMITERS "<>"
DELIMITERS "||"
DELIMITERS " "
8-2 OPEN form 叙述
<语法格式>
OPEN form form_name FROM "form_file"
§例:
OPEN form form_option FROM "pay101"
8-3 DISPLAY form 叙述
<语法格式>
DISPLAY form form_name
系统会显示屏幕画面的第3行开始至第22行.其中第1行是提示行,第2行是讯息行,第23行当成批注行,第24行当错误行。若要改变这些预设行则可以使用 OPTIONS 叙述。
§例:
OPEN form form_option FROM "pay101"
DISPLAY form form_option
8-4用屏幕画面写交谈式程序
通常使用 INPUT 和 DISPLAY 叙述来提供使用者和程序之间的交谈.
8-4-1 INPUT form 叙述
在使用 INPUT 叙述之前必须先开启屏幕画面文件和用 display from 叙述将画面格式显示于屏幕上。
<语法格式>
INPUT variable_list [WITHOUT DEFAULT] FROM field_list
BEFORE FIELD
┌──→
│ AFTER FIELD
├──→
│
├──→ ON KEY(key_list)
│ ┌───────────────┐
│ │ statement │
│ │ ... │
│ │ [NEXT FIELD field_name] │
└─────┤ ... │
│ [EXIT INPUT] │
│ ... │
└───────────────┘
§例:
INPUT curr_ssaltab.idno,
...
FROM ssaltab.idno,
...
BEFORE FIELD idno
IF update_option = 3 THEN
NEXT FIELD ssaltab.emp_name
ELSE IF update_option = 4 THEN
NEXT FIELD ...
END IF
END IF
# 身分证字号
AFTER FIELD idno
IF curr_ssaltab.idno IS NULL THEN
ERROR "身分证字号不可空白"
NEXT FIELD ssaltab.idno
END IF
...
AFTER FIELD ...
ON KEY(INTERRUPT)
EXIT INPUT
END INPUT
1.在 variable_list 是一串程序变量相对于 field_list 的屏幕字段。因此,必须有相同的资料型态。
2.资料从屏幕字段输入时的次序是依据 variable_list 次序不是依屏幕字段.
3.光标在屏幕画面之间移动的次序是依据 field_list 次序而定。
TABLES
ssaltab
ATTRIBUTES
f01 = ssaltab.idno ,UPSHIFT,AUTONEXT;
f02 = ssaltab.emp_name ,AUTONEXT;
f03 = ssaltab.stuff_ty ,AUTONEXT;
§例:
INPUT curr_ssaltab.idno,
curr_ssaltab.stuff_num,
curr_ssaltab.emp_name
FROM ssaltab.idno,
ssaltab.stuff_num,
ssaltab.emp_name
8-4-2 INPUT BY NAME 叙述
如果程序变量和屏幕字段具有相同的名称时,则可以使用 INPUT BY NAME
变量名称 字段名称
==== ====
p_syeartab.annu_yy annu_yy
p_syeartab.month_num annu_mm
§例:
INPUT BY NAME p_syeartab.annu_yy ,
p_syeartab.month_num
TABLES
syeartab
ATTRIBUTES
f1 = syeartab.annu_yy, COLOR = RED BLINK REVERSE
WHERE f1 < 82 ,
COLOR = RED BLINK REVERSE WHERE f1 IS NULL,
PICTURE = "##" , AUTONEXT;
f2 = syeartab.month_num, COLOR = RED BLINK REVERSE WHERE f2 <= 0,
COLOR = RED BLINK REVERSE WHERE f2 IS NULL,
formAT = "#&.&&" , AUTONEXT;
8-4-3 DISPLAY TO 叙述
<语法格式一>
DISPLAY variable_list AT ROW,COLUMN[ATTRIBUTE(attribute_list)
§例:
DISPLAY "现在时间:" AT 2,2
DISPLAY "F1:插入一笔 F2:删除一笔 F3:下页 F4:上页"AT 1,2 ATTRIBUTE(BLINK,REVERSE)
<语法格式二>
DISPLAY variable_list TO [屏幕字段串行|屏幕记录.*][ATTRIBUTE(attribute_list)]
§例:
DISPLAY curr_ssaltab.idno TO idno
DISPLAY curr_ssaltab.emp_name TO emp_name
DISPLAY curr_ssaltab.* TO ssaltab.*
<语法格式三>
DISPLAY BY NAME variable_list [ATTRIBUTE(attribute_list)
§例:
DISPLAY BY NAME curr_ssaltab.dept_ty
DISPLAY BY NAME curr_ssaltab.proj_ty
DISPLAY BY NAME curr_ssaltab.unit_ty
DISPLAY BY NAME curr_ssaltab.basegrd,
curr_ssaltab.jobgrd,
curr_ssaltab.spegrd
8-4-4 CLEAR 叙述
清除屏幕
<语法格式>
CLEAR {SCREEN|WINDOW window_name|form|field_list}
§例:
clear screen
clear window w1
clear form
clear idno,stuff_num,emp_name
8-4-5 WITHOUT DEFAULTS 叙述
§例:
INPUT BY NAME p_syeartab.annu_yy ,
p_syeartab.month_num WITHOUT DEFAULTS
§例:
INPUT curr_ssaltab.idno,
curr_ssaltab.stuff_num,
curr_ssaltab.emp_name
WITHOUT DEFAULTS
FROM ssaltab.idno,
ssaltab.stuff_num,
ssaltab.emp_name
第九章 MENU制作 9-1.MENU
<语法格式>
MENU "菜单名称"
COMMAND "菜单选择项" "HELP 讯息"
...
statement
...
[CONTINUE MENU]
...
[NEXT OPTION "菜单选择项"]
...
[EXIT MENU]
...
COMMAND "菜单选择项" "HELP 讯息"
...
END MENU
§例:
MENU "人事薪资"
COMMAND "1.新增"
...
COMMAND "2.查询"
...
COMMAND "3.更正"
...
COMMAND "4.删除"
...
COMMAND "0.结束"
END MENU
将在屏幕上显示下面菜单
人事薪资: 1.新增 2.查询 3.更正 4.删除 0.结束
§例:
DEFINE sys_permision CHAR(5) # 使用权限
MENU "人事薪资"
BEFORE MENU
IF sys_permision[1,1] != "Y" THEN
HIDE OPTION "1.新增"
END IF
IF sys_permision[2,2] != "Y" THEN
HIDE OPTION "2.查询"
END IF
IF sys_permision[3,3] != "Y" THEN
HIDE OPTION "3.更正"
END IF
IF sys_permision[4,4] != "Y" THEN
HIDE OPTION "4.删除"
END IF
CALL init_val()
COMMAND "1.新增"
INITIALIZE curr_ssaltab.* TO NULL
CALL psn_modify(1)
IF must_cancel = "Y" THEN
EXIT MENU
END IF
COMMAND "2.查询"
CALL sub_menu(2)
COMMAND "3.更正"
CALL sub_menu(3)
IF must_cancel = "Y" THEN
EXIT MENU
END IF
COMMAND "4.删除"
CALL sub_menu(4)
COMMAND "0.结束"
EXIT MENU
END MENU
FUNCTION sub_menu(update_option)
DEFINE update_option SMALLINT
LET s_menu[1].menu_name = "新增"
LET s_menu[2].menu_name = "查询"
LET s_menu[3].menu_name = "更正"
LET s_menu[4].menu_name = "删除"
LET s_menu[1].action = "5.新增"
LET s_menu[2].action = "5.查询"
LET s_menu[3].action = "5.更正"
LET s_menu[4].action = "5.删除"
LET toward_last = +1
LET toward_first = -1
LET at_end = 0
MENU s_menu[update_option].menu_name
BEFORE MENU
FETCH FIRST ssaltab_cursor INTO curr_ssaltab.*
IF SQLCA.SQLCODE = NOTFOUND THEN
ERROR "无符合查询资料 !!"
HIDE OPTION ALL
SHOW OPTION "0.结束"
NEXT OPTION "0.结束"
ELSE
CALL show_data()
HIDE OPTION "1.第一笔"
HIDE OPTION "3.上一笔"
LET fetch_dir = toward_last
FETCH NEXT ssaltab_cursor INTO next_ssaltab.*
IF SQLCA.SQLCODE != 0 THEN
HIDE OPTION "2.下一笔"
HIDE OPTION "4.最后一笔"
END IF
NEXT OPTION s_menu[update_option].action
IF update_option = 2 THEN
HIDE OPTION s_menu[update_option].action
IF SQLCA.SQLCODE != 0 THEN
NEXT OPTION "0.结束"
ELSE
NEXT OPTION "2.下一笔"
END IF
END IF
END IF
COMMAND "1.第一笔"
FETCH FIRST ssaltab_cursor INTO curr_ssaltab.*
CALL show_data()
HIDE OPTION "1.第一笔"
HIDE OPTION "3.上一笔"
SHOW OPTION "4.最后一笔"
LET fetch_dir = toward_last
FETCH NEXT ssaltab_cursor INTO next_ssaltab.*
IF SQLCA.SQLCODE = 0 THEN
SHOW OPTION "2.下一笔"
NEXT OPTION "2.下一笔"
ELSE
HIDE OPTION "2.下一笔"
NEXT OPTION "0.结束"
END IF
COMMAND "2.下一笔"
LET prev_ssaltab.* = curr_ssaltab.*
SHOW OPTION "1.第一笔"
SHOW OPTION "3.上一笔"
SHOW OPTION "4.最后一笔"
LET curr_ssaltab.* = next_ssaltab.*
CALL show_data()
CASE (fetch_dir)
WHEN toward_last
FETCH NEXT ssaltab_cursor INTO next_ssaltab.*
WHEN at_end
FETCH RELATIVE +2 ssaltab_cursor INTO next_ssaltab.*
WHEN toward_first
FETCH RELATIVE +3 ssaltab_cursor INTO next_ssaltab.*
LET fetch_dir = toward_last
END CASE
IF SQLCA.SQLCODE = NOTFOUND THEN
LET fetch_dir = at_end
HIDE OPTION "2.下一笔"
HIDE OPTION "4.最后一笔"
NEXT OPTION "1.第一笔"
END IF
COMMAND "3.上一笔"
LET next_ssaltab.* = curr_ssaltab.*
SHOW OPTION "1.第一笔"
SHOW OPTION "2.下一笔"
SHOW OPTION "4.最后一笔"
LET curr_ssaltab.* = prev_ssaltab.*
CALL show_data()
CASE (fetch_dir)
WHEN toward_first
FETCH PRIOR ssaltab_cursor INTO prev_ssaltab.*
WHEN at_end
FETCH RELATIVE -2 ssaltab_cursor INTO prev_ssaltab.*
LET fetch_dir = toward_first
WHEN toward_last
FETCH RELATIVE -3 ssaltab_cursor INTO prev_ssaltab.*
LET fetch_dir = toward_first
END CASE
IF SQLCA.SQLCODE = NOTFOUND THEN
LET fetch_dir = at_end
HIDE OPTION "1.第一笔"
HIDE OPTION "3.上一笔"
NEXT OPTION "4.最后一笔"
END IF
COMMAND "4.最后一笔"
FETCH LAST ssaltab_cursor INTO curr_ssaltab.*
CALL show_data()
SHOW OPTION "1.第一笔"
HIDE OPTION "2.下一笔"
HIDE OPTION "4.最后一笔"
LET fetch_dir = toward_first
FETCH PRIOR ssaltab_cursor INTO prev_ssaltab.*
IF SQLCA.SQLCODE = 0 THEN
SHOW OPTION "3.上一笔"
NEXT OPTION "3.上一笔"
ELSE
HIDE OPTION "3.上一笔"
NEXT OPTION "0.结束"
END IF
COMMAND s_menu[update_option].action
CALL psn_modify(update_option)
NEXT OPTION "0.结束"
COMMAND "0.结束"
CLOSE ssaltab_cursor
EXIT MENU
END MENU
9-2.OPTIONS
修改屏幕预设状况,说明文件名及功能键等
<语法格式>
OPTIONS {MESSAGE LINE 列地址 | 内定值 FIRST+1
PROMPT LINE 列地址 | 内定值 FIRST
COMMENT LINE 列地址 | 内定值 LAST-1
ERROR LINE 列地址 | 内定值 LAST
form LINE 列地址 | 内定值 FIRST+2
INPUT {WRAP|NO WRAP} | 内定值 NO WRAP
INSERT KEY 键名称 | 内定值 F1
DELETE KEY 键名称 | 内定值 F2
NEXT KEY 键名称 | 内定值 F3
PREVIOUS KEY 键名称 | 内定值 F4
ACCEPT KEY 键名称 | 内定值 ESCAPE
HELP FILE "help_file" |
HELP KEY 键名称 | 内定值 CTRL-W
INPUT ATTRIBUTE(attribute_list)
}
§例:
OPTIONS MESSAGE LINE 23,
PROMPT LINE LAST-2,
form LINE FIRST,
NEXT KEY CONTROL-N,
PREVIOUS KEY CONTROL-P
OPTIONS INPUT ATTRIBUTE (green)
9-3.建立辅助讯息
对一个使用者初次接触到一套系统时,若能提供线上辅助讯息,将使本系统的亲和性大为提高同时降低教育训练的成本。辅助讯息可提供 INPUT,PROMPT和MENU 使用。同时多个辅助讯息,可并存于一个辅助讯息文件,只要加以编号即可。
<语法格式>
MKMESSAGE helpfile.msg helpfile.ex
§例:
OPTION HELP FILE "help_file.ex",HELP KEY F1
...
MENU "人事薪资"
COMMAND "1.新增" HELP 1
...
COMMAND "2.查询" HELP 2
...
COMMAND "3.更正" HELP 3
...
COMMAND "4.删除" HELP 4
...
COMMAND "0.结束" HELP 5
...
END MENU
假设 help_file.msg 内容如下:
.1
你可以用这项功能键新增一位新员工的基本资料 ...
.2
你可以用这项功能键查询一位员工的基本资料 ...
.3
你可以用这项功能键更正一位员工的基本资料 ...
.4
你可以用这项功能键删除一位员工的基本资料 ...
.5
你可以用这项功能键离开 "人事薪资" 作业
在屏幕上显示下面菜单
人事薪资: 1.新增 2.查询 3.更正 4.删除 0.结束
当光标在 1.新增 上时,若按功能键 F1 系统会显示下面画面:
HELP: Screen Resume
Displays the next page of Help text.
-------------------------------------------------------------------
你可以用这项功能键新增一位新员工的基本资料 ...
You have reached the end of this help text. Press RETURN to continue.
第十章 多栏位的选择 10-1 选择性的查询 QUERY BY EXAMPLE
使用者可依实际需要设定查询条件,输入在屏幕画面格式中的字段里,此种查询方式称之为 Query By Example。此种查询方法的优点是在于能够使用关系(Relation)、范围(Range)、交替(Alternation)表达式、和使用万用Wildcard)符号来查询。 10-2 使用者可用的查询条件 ┌──────────────────────────┐ │ 运算子 意 义 适用资料型态 │ ├──────────────────────────┤ │ = 等于 全部 │ │ > 大于 全部 │ │ < 小于 全部 │ │ >= 大于或等于 全部 │ │ <= 小于或等于 全部 │ │ <> 不等于 全部 │ │ * 万用字符串 CHAR │ │ ? 万用字符串 CHAR │ │ : 连续的范围 全部 │ │ | 或 全部 │ └──────────────────────────┘
假设人事薪资的 form 如下:
身分证字号:[f01 ]教职员工号:[f24 ] 姓 名:[f02 ]
员工编号 :[m][n ][fi][fj ][f08] 服务单位:[f06 ]
核薪职等 :[f09 ][f10 ] 职 称:[f07 ]
本 薪 :[f11] 功俸:[f26] 本俸级别:[fb ]
补助费级别:[fc] 主管级别:[b ]
资薪单位 :[e][ee ] 职 别:[c][f12 ]
异动日期 :[f14 ] 到职日期:[f25 ]
保险别 :[d][fl ] 保险号:[insu ] 福利互助:[h]
眷保总人数:[z] 眷保人数 :[w] 扶养人数:[fe]
合并眷口数: 房屋津贴:[j][fo]
研究费 :[x] 学人房贴:[y][yy ]
银行帐号 :[f17 ] 公教帐号:[f21 ]
§例:
欲查教职员工号117至123的资料,可在教职员工号字段中输入条件
〔117:123〕。
§例:
欲查教职员工号117,119和123的资料,可在教职员工号字段中输入条件〔117|119|123〕。
当使用者输入的条件超出屏幕字段的长度时,系统自动显示你的条件在commentline 供你输入最长255个字符的条件。
§例:
欲查所有姓 "丁" 的资料,可在姓名字段中输入条件[丁* ]。
§例:
欲查所有姓名中有 "成功" 的资料,可在姓名字段中输入条件[*成功* ]。
10-3 CONSTRUCT 叙述
程序的查询条件 construct select 大约可分成四个步骤:
1.用 construct 定义,将等待使用者输入条件的各个屏幕字段组合后的条件句存放到一个字符串变量。
2.用 LET 将前面字符串变量与 select 子句的其它的部份字符串连结。
3.用 PREPARE 将前面合成的命令句,编译成可执行的 select 子句。
4.宣告 pointer cursor DECLARE-FOREACH 叙述执行 select 子句,找出使用者的资料。
<语法格式一>
CONSTRUCT variable ON column_list FROM field_list
如果 column_list 内容和 field_list 相同,则可以使用 construct by name的方式。
<语法格式二>
CONSTRUCT BY NAME variable ON column_list
§例:
DEFINE construct_clause CHAR(400)
DEFINE prepare_clause CHAR(400)
CONSTRUCT BY NAME construct_clause ON ssaltab.idno,
ssaltab.stuff_num,
ssaltab.emp_name,
...
LET prepare_clause = " SELECT * ",
" FROM ssaltab ",
" WHERE ", construct_clause CLIPPED ,
" AND ssaltab.pos_ty < 970 ",
" AND ssaltab.work_ty = ""1""",
[" AND ssaltab.work_ty = ?",]
" ORDER BY proj_ty,dept_ty,pos_ty"
PREPARE pre_update FROM prepare_clause
DECLARE ssaltab_cursor [SCROLL] CURSOR [WITH HOLD] FOR pre_update
OPEN ssaltab_cursor
[OPEN ssaltab_cursor USING p_ssaltab.work_ty]
[FETCH FIRST ssaltab_cursor INTO curr_ssaltab.*]
FOREACH ssaltab_cursor INTO curr_ssalatb.*
...
10-4 PREPARE 与 EXECUTE 叙述
对一个没有使用 select 叙述的字符串变量,可以用 execute 叙述去执行。
§例:
prepare s1 from "delete from ssaltab where stuff_num > 1000"
execute s1
§例:
let del_stmt = "delete from ssaltab where stuff_num > 1000"
prepare s1 from "del_stmt
execute s1
§例:
define p_st array[50] of record like employee.*
define i integer
...
for i = 1 to arr_count()
insert into employee values(p_st.idno,p_st.emp_name)
end for
prepare insert_cursor from "insert into employee value(?,?)"
for i = 1 to arr_count()
execute insert_cursor using p_st.idno,p_st.emp_name
end for
10-5 使用 CONSTRUCT 应注意事项 1.使用 construct 之前,应将所有的索引文件建好,每一个数据 table 的primary key 可建为 CLUSTER INDEX。假使没建好索引文件,则使用 construct 时,将使查询的速度慢的可怕!
2.注意 scroll 的使用,因查询的目的不一定只是为了查看所要的资料。一般来 说,对于要修改或删除的对象而言,先作查询并没有任何差异。简单来说 ,既然搜指针可分为可卷动 (scroll) 及不可卷动两种。可卷动的指针纯粹以查询为目的,而不可卷动指针则用于修改或删除的用途。
第十一章 多重表画面的处理 11-1 前言 本章学习如何建立一个多重资料表格的屏幕表格及如何运用屏幕数组,如何运用 INPUT ARRAY 输入资料,如何运用 DISPLAY ARRAY 显示资料。
11-2 INPUT ARRAY
<语法格式>
INPUT ARRAY program_array [WITHOUT DEFAULTS] FROM screen_array.*
[BEFORE FIELD field_list
statement
...]
[AFTER FIELD field_list
statement
...]
[BEFORE INSERT
statement
...]
[AFTER INSERT
statement
...]
[BEFORE DELETE
statement
...]
[AFTER DELETE
statement
...]
[ON KEY (key_lisy)]
...
END INPUT
§例:
DATABASE payroll SCREEN { 身份证号:[a ] 姓名:[b ] 员工编号:[c][d ][e ][f ][g ] 服务单位:[h ] 职 称:[i ] 贷款代码 贷款类别 行库代码 行库名称 期扣金额 扣款帐号 ==================================================================== [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] [j ] [k ] [l ] [m ] [n ] [o ] } END TABLES sdistab,sdedutab,sbanktab,ssaltab ATTRIBUTES a = ssaltab.idno,UPSHIFT ,AUTONEXT; b = ssaltab.emp_name ,AUTONEXT; c = ssaltab.proj_ty ,AUTONEXT,formAT = "&"; d = ssaltab.dept_ty ,AUTONEXT,formAT = "&&"; e = ssaltab.unit_ty ,AUTONEXT,formAT = "&&"; f = ssaltab.pos_ty ,AUTONEXT,formAT = "&&&"; g = ssaltab.seq_num ,AUTONEXT,formAT = "&&&"; h = ssaltab.unit_name ,NOENTRY i = ssaltab.pos_name ,NOENTRY j = sdistab.loan_no ,AUTONEXT; k = sdedutab.dedu_name ,NOENTRY l = sdistab.bank_no ,AUTONEXT; m = sbanktab.bank_name ,NOENTRY n = sdistab.amt ,formAT = "-----&",AUTONEXT o = sdistab.account_no ,AUTONEXT; END INSTRUCTIONS SCREEN RECORD s_dispitem[10] (loan_no,dedu_name,bank_no,bank_name,amt,account_no) END INPUT ARRAY p_st WITHOUT DEFAULTS FROM s_dispitem.*
BEFORE INSERT
LET sa_curr = SCR_LINE()
CLEAR s_dispitem[sa_curr].*
BEFORE FIELD loan_no
LET sa_curr = SCR_LINE()
LET pa_curr = ARR_CURR()
LET arr_cnt = ARR_COUNT()
AFTER FIELD loan_no
IF p_st[pa_curr].loan_no IS NULL THEN
ERROR "输入错误 !!, try again."
NEXT FIELD loan_no
END IF
...
AFTER FIELD bank_no
...
AFTER FIELD amt
...
...
ON KEY(INTERRUPT)
DISPLAY "" AT 1,1
EXIT INPUT
ON KEY(ACCEPT)
DISPLAY "" AT 1,1
EXIT INPUT
END INPUT
11-3 屏幕数组的卷动与编辑
当使用者按下 ENTER 或 TAB 键,则光标移到下一个字段.input array 内定四个方向键及四个功能键来做屏幕数组的卷动和编辑,当然这些功能键可以在程序中使用 OPTIONS 设定不同的键。
.左移方向键(←)
.右移方向键(→)
.上移方向键(↑)
.下移方向键(↓)
.F1键:当使用者在屏幕数组中使用F1键时,会在当时的位置新增一个空白列,并将光标移至空白列的起始位置。
.F2键:当使用F2键时,会删除在当时的列,并将下面的列的往上递补一列。
.F3键:向下卷动数组中一整页的列数据。
.F4键:向上卷动数组中一整页的列数据。
11-4 屏幕数组和程序数组的内建函数
.ARR_CURR() 传回现在指针在当前程序数组的位置。
.ARR_COUNT() 传回在程序数组的所有列总合。
.SCR_LINE() 传回现在指针在屏幕数组的位置。
.SET_COUNT(X) 设定现在程序数组的所有列数目给系统。
X 是现在程序数组元素的储存数目,当用到 input array 与 display array叙述之前,都必须先呼叫 set_count(x)。如此一来,系统才知道 arr_count()的值是多少,也就是目前程序数组中有多少笔资料。
§例:累计所得作业 SCREEN 身份证字号:[f01 ] 姓 名:[f02 ] 员工编号:[a][b ][c ][d ][e ] 服务单位 :[f03 ] 职 称:[f04 ] 核薪职等 :[f05 ][f06 ] 资薪单位:[g] =============================================================== 所得 所得 应 应税 所得日期 代码 所得类别 金额 税 所得 所得税 合计 =============================================================== [y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 ] [y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 ] [y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 ] [y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 ] [y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 ] [y1|y2|m1|m2|f1|f07 |f08 |h|f09 |f11 |f12 ] §例:某员工目前累计所得资料 所得 所得 应 应税 所得日期 代码 所得类别 金额 税 所得 所得税 合计 =============================================================== 83 年 10 月 01 应支薪俸 39075 1 37545 850 38225 83 年 10 月 86 考绩奖金 39100 1 39100 2346 36754 83 年 10 月 88 晋级奖金 2415 1 2415 0 2415 83 年 9 月 01 应支薪俸 39075 1 37545 850 38225←┐ 83 年 8 月 01 应支薪俸 39075 1 37545 850 38225 │ 83 年 7 月 01 应支薪俸 38295 1 37545 850 37445 │ 83 年 6 月 01 应支薪俸 36610 1 35860 600 36010 │ 83 年 5 月 01 应支薪俸 36610 1 35860 600 36010 │ 83 年 4 月 01 应支薪俸 36610 1 35860 600 36010←┘ 83 年 3 月 01 应支薪俸 36610 1 35860 600 36010 83 年 2 月 01 应支薪俸 36610 1 35860 600 36010 83 年 2 月 85 年终奖金 54915 1 54915 3294 51621 83 年 1 月 01 应支薪俸 36610 1 35860 600 36010
假如现在光标在第6列,也就是下面之数据: 83 年 7 月 01 应支薪俸 38295 1 37545 850 37445 此时,arr_curr 值是 6、arr_count 值是13、scr_line 值是3、set_count(13) 设定13个列的数目给系统。
§例:
DEFINE p_st ARRAY[50] OF RECORD
annu_yy LIKE sincotab.annu_yy,
year CHAR(2) , # 年
annu_mm LIKE sincotab.annu_mm,
month CHAR(2) , # 月
inc_ty LIKE sincotab.inc_ty,
inc_name LIKE sintytab.inc_name,
tot_amt LIKE sincotab.tot_amt,
tax_ty LIKE sincotab.tax_ty,
dis_amt LIKE sincotab.dis_amt,
tax LIKE sincotab.tax
END RECORD
DEFINE pa_count,pa_curr,sa_curr,arr_cnt SMALLINT
LET sa_curr = SCR_LINE()
LET pa_curr = ARR_CURR()
LET arr_cnt = 0
FOR k = 1 TO 6
CLEAR s_dispitem[k].*
END FOR
DECLARE pointer CURSOR FOR
SELECT annu_yy, annu_mm, inc_ty, tot_amt,
tax_ty, dis_amt, tax, tot_amt-tax
FROM sincotab
WHERE idno = curr_ssaltab.idno
AND annu_yy = p_yy
ORDER BY annu_mm DESC, inc_ty
LET arr_cnt = 1
FOREACH pointer INTO p_st[arr_cnt].annu_yy,p_st[arr_cnt].annu_mm,
p_st[arr_cnt].inc_ty, p_st[arr_cnt].tot_amt,
p_st[arr_cnt].tax_ty, p_st[arr_cnt].dis_amt,
p_st[arr_cnt].tax, p_st[arr_cnt].net_total
SELECT inc_name
INTO p_st[arr_cnt].inc_name
FROM sintytab
WHERE inc_ty = p_st[arr_cnt].inc_ty
LET p_st[arr_cnt].inc_name = p_sintytab.inc_name
LET arr_cnt = arr_cnt + 1
IF arr_cnt > 50 THEN
EXIT FOREACH
END IF
END FOREACH
CALL SET_COUNT(arr_cnt - 1)
INPUT ARRAY p_st WITHOUT DEFAULTS FROM s_dispitem.*
11-5 DISPLAY ARRAY
<语法格式>
DISPLAY ARRAY program_array FROM screen_array.*
display array 内定两个功能键来做屏幕数组的卷动,当然这些功能键可以在程序中使用 OPTIONS 设定不同的键。
.F3键:向下卷动数组中一整页的列数据。
.F4键:向上卷动数组中一整页的列数据。
在使用 input array 或 display array 叙述之前,必须先 call set_count(x),否则无法显示资料值。
| | |