最新消息:本站持续更新中,请注意添加收藏夹。搜索关键词时,多换一个同义词。比如要搜索界面,可以尝试页面,画面,PER档等词汇。善于搜索,将大大提高你的查找效率。

【实习之T100开发】Genero FGL (TIPTOP4GL) 学习笔记1

T100 ERP bron1984 6112浏览

Genero FGL 学习

 

Genero FGL 简介

Genero FGL 开发(编译、连接、执行)

第一个程序 Hello World

变量与运算符

变量定义(DEFINE)

预定义变量

变量集合(RECORD )

数据结构(TYPE)

变量赋值(LET)、初始化(INITIALIZE)

常数(CONSTANT)

运算符(operators)

全局变量(GLOBALS)

变数的生命周期(LOCALE、MODULE、GLOBAL)

控制输出格式(USING)

函数、流程控制

IMPORT 引入链接库(跳过)

SCHEMA / DATABASE 声明数据库

MAIN 函数与设定区块

FUNCTION 函数

报表结构 REPORT 函数(跳过)

IF

CASE

FOR

WHILE

CONTINUE

EXIT

TRY…CATCH

SLEEP

LABEL 和 GOTO()

常用的内置函数(built-in functions)

 

Genero FGL 简介

Genero FGL 语言,为 Four J’s(http://www.4js.com)于 2004 年所发表。整体结构为承袭 INFORMIX 数据库的 4GL 管理语言而来,即 INFORMIX-4GL 。

INFORMIX-4GL 属于第四代架构的语言,其优点在于构成程序的语法和英文近似,可以大幅减少学习的时间,但仅能使用于 INFORMIX 数据库的控制上。

Four J’s 取其优点,为了能够应用于更多后端数据库,开发出 FGL 语言,并因应图型化,改版为Genero FGL,有以下特点:

  • 切分为 Client、Server 架构(GDC 与 fgl),增进执行效率
  • 以 XML Bsae 做为 Client 及 Server 端数据传递的架构
  • 支援更多不同平台(OS)及数据库系统
  • 可在运行时间动态调整画面输出的格式(Layout Styles)
  • 引入基本的 对象(Object) 概念

在这里插入图片描述
在 Genero FGL 语言架构中,将 程序逻辑、画面 视为不同的项目,分别撰写。
Program(程序)= MODULE(逻辑代码) + FORM(画面代码)
在这里插入图片描述
由上图可知:

  1. Program 可由许多的 Module 与 Form 构成。
  2. 单一的 4GL 由一个或一个以上的 Function、Report 组成。
  3. 一个完整的 Program 中,必需指定一个『Main』作为程序执行入口。

Genero FGL 开发(编译、连接、执行)

当程序及画面编写完成后,还需经过编绎(Compile)连结(Link),才能够被执行(Execute)
编译需要 Genero Development License,连结及执行需要 Genero Runtime License。

编译流程
在这里插入图片描述
程序的原始文件后缀名为 .4gl,经过编译后会产生后缀为 .42m 的文件。
程序(Program)的编译:fglcomp [编译参数] 待编译文件名[.4gl]

编译前处理(preprcessor) ????????

GeneroFGL 可直接以 文字编辑程序如Vim 进行 文字格式(per 档)的开发;
也可使用 Genero Studio 内的『Form Design』功能开发 XML格式(4fd 档)的画面;
编译后都会产生后缀名为 .42f 的文件。

文字格式(per文件)编译:fglform [编译参数] 待编译文件名[.per]
XML 格式(4fd文件)编译:gsform [编译参数] 待编译文件名[.4fd]

连结流程

若该程序不需要使用其他 4gl 提供的功能,可以略过连接的程序,直接执行作业。
若该作业被切分成许多子程序,则可在执行连接前,先将子程序打包成一组动态链接函式库(Dynamic Link Library),后缀名为 .42x,打包完成后再与原始作业进行连接。
在这里插入图片描述
连接语法:fgllink -o 连结后的完整文件名 待连结文件1 [待连结文件2] ….

示例:

  1. fgllink -o test.42x test1.42m test2.42m test3.42m(生成42x文件)
  2. fgllink -o program.42r test.42x main.42m others.42m(生成42r文件)

注:画面文件不需要执行链接

执行程序

执行程序前,需先开启使用者端的 Genero 桌面客户端软件(GDC:Genero Desktop
Client),以令主机端的 fglrun 可以与客户端的『GDC』进行沟通。
在这里插入图片描述
执行指令:fglrun [执行参数] 执行文件名[.42r]

当程序未使用到其他外部资源时,也可以直接执行含 MAIN 函数的 .42m 文件。

程序执行的过程中,所有逻辑运算均于主机端执行,只有画面异动数据会以连续的 XML 封包传递到客户端,经过 GDC 解译重组后,与使用者进行互动。

fglrun -V 可以查看 fgl 的版本号。
在这里插入图片描述

第一个程序 Hello World

MAIN

DISPLAY “hello world!!”

END MAIN

在这里插入图片描述

4GL中的 注释

  • { } 可以将某个范围做备注
  • # 或 — 将某行做备注

变量与运算符

变量类型
在这里插入图片描述

变量定义(DEFINE)

直接定义变量:DEFINE 变量名 变量类型
定义变量对应数据库字段:DEFINE 变量名 LIKE 数据表.数据字段

# 直接定义 employee_no 变量, 类型是 CHAR(10)

DEFINE employee_no CHAR(10)

# 定义 p_employee_no 和数据库对应

DEFINE p_employee_no LIKE employee_file.employee_no,

p_team_no SMALLINT,

p_join_date, p_birthday DATE

预定义变量

Genero 的预定义变量及用途,可以直接使用。
在这里插入图片描述

变量集合(RECORD )

直接定义变量集合(Records)
例:直接定义 rec 这个 Records 中的各个变量类型。

DEFINE rec RECORD # 定义rec这个变量,它是个RECORD,是个变量集合

id INTEGER,

name VARCHAR(100),

birth DATE

END RECORD

定义变量集合对应数据库字段
例:定义 cust01 这个 Record 的变量与数据库中的 customer 这个 table 的字段有相同的名称及数据类型,有以下两种方法。

DATABASE example_database

MAIN

DEFINE cust01 RECORD LIKE customer.*

END MAIN

DATABASE example_database

MAIN

DEFINE cust02 RECORD

id LIKE customer.id,

name LIKE customer.name,

birth LIKE customer.birth,

sales LIKE salesman.name

END RECORD

END MAIN

数据结构(TYPE)

使用数据结构TYPE:[PRIVATE|PUBLIC] TYPE 变量名 变量类型

TYPE customer RECORD

cust_num INTEGER,

cust_name VARCHAR(50),

cust_addr VARCHAR(200)

END RECORD

DEFINE c customer

???????

PUBLIC TYPE rpt_order RECORD

order_num INTEGER,

store_num INTEGER,

order_date DATE,

fac_code CHAR(3)

END RECORD

MAIN

DEFINE o rpt_order #使用数据结构 rpt_order 并取名为 o

DECLARE order_c CURSOR FOR

SELECT order_num, store_num, order_date, fac_code FROM orders

START REPORT order_list

FOREACH order_c INTO o.*

OUTPUT TO REPORT order_list(o.*)

END FOREACH

FINISH REPORT order_list

END MAIN

变量赋值(LET)、初始化(INITIALIZE)

变量赋值:LET varibale = expression

MAIN

DEFINE c1, c2 CHAR(10)

LET c1 = “Genero”

LET c2 = c1

END MAIN

注:若变量形态为 CHAR 和 VARCHAR 时,指定给予的值有差异。
在这里插入图片描述

初始化变量集合(INITIALIZE)
用于初始化一组 RECORD 变量为 NULL,或者是初始化为数据库 Table 的默认值:

INITIALIZE 变量串行 { LIKE 字段串行 | TO NULL }

MAIN

DEFINE cr RECORD LIKE customer.*

INITIALIZE cr.cust_name TO NULL #初始化cr的cust_name字段为NULL

INITIALIZE cr.* LIKE customer.* #初始化cr的变量为customer表的值

END MAIN

常数(CONSTANT)

一些系统预定义常数
在这里插入图片描述
定义常数:CONSTANT constant_id [data_type] = value
注:定义常数可以不指定类型;系统会自动判断类型,若指定错误则会纠正。

CONSTANT c1 = “Drink” — 自行定义为 STRING

CONSTANT c2 = 4711 — 自行定义为 INTEGER

CONSTANT c3 SMALLINT = 12000 — 自行纠正为 INTEGER

CONSTANT c4 CHAR(10) = “abc” — 按照定义为 CHAR(10)

运算符(operators)

比较运算符
` 在这里插入图片描述

MAIN

DEFINE a,b INTEGER

LET a = b := 10

DISPLAY a, b — 10 10

END MAIN

MAIN

DEFINE a,b INTEGER

LET a = b = 10

DISPLAY a,b — 0 0

END MAIN

逻辑运算符
在这里插入图片描述
数值运算符
在这里插入图片描述

MAIN

DEFINE i,j SMALLINT

LET i = 9

LET j = 2

DISPLAY i + j –DISPLAY 11

DISPLAY i – j –DISPLAY 7

DISPLAY i * j –DISPLAY 18

DISPLAY i / j –DISPLAY 4.5

DISPLAY j ** i –DISPLAY 512

DISPLAY i mod j –DISPLAY 1

END MAIN

字符串运算符
在这里插入图片描述
在这里插入图片描述
?????????
说明:表达式[start,end]表示从字符串中取出子字符串,此表示方式仅能用在 CHAR 或
VARCHAR 上
,若变量型态为 STRING,则参照如下范例:

MAIN

DEFINE i,j STRING

LET i = “T100”

LET j = i.subString(1, 4)

DISPLAY j –T100

DISPLAY i.subString(1, 4) –T100

END MAIN

在这里插入图片描述
关联语法(Associative syntax) 运算符
在这里插入图片描述
日期运算符
在这里插入图片描述
对话框处理 (Dialog handling)运算符
在这里插入图片描述

全局变量(GLOBALS)

语法一:直接写定 GLOBALS 区块

GLOBALS

declaration-statement

[,…]

END GLOBALS

语法二:读入已写好的共同配置文件(外部档案)

GLOBALS “filename”

变数的生命周期(LOCALE、MODULE、GLOBAL)

LOCAL变量(Local Variables)

  • 定义位置:定义在 Module 中的函式里 (MAIN、FUNCTION 等)
  • 生命周期:只属于该定义的函式使用,离开此函式即不能再使用。

MODULE变量(Module Variables)

  • 定义位置:Module 中,但不被任何的函式包围。
  • 生命周期:为该 Module 中的共享变数。

GLOBAL变量(Global Variables)

  • 定义位置:由 GLOBALS 及 END GLOBALS 所包围的变数。
  • 生命周期:使用的所有 MODULE 的共享变量。

SCHEMA ds

GLOBALS

DEFINE g_employee CHAR(10) –GLOBAL

END GLOBALS

DEFINE g_tty CHAR(32) –MODULE

MAIN

DEFINE answer CHAR(1) –LOCAL

END MAIN

FUNCTION ins_employee()

DEFINE flag CHAR(1), –LOCAL

change SMALLINT –LOCAL

END FUNCTION

控制输出格式(USING)

针对 数值或日期 设定其 显示格式,设定时注意 溢出(overflow) 的问题。

数值格式标志
在这里插入图片描述
日期格式标志
在这里插入图片描述
???????????????????????

MAIN

DEFINE i,j SMALLINT

LET i = 12345

LET j = -12345

DISPLAY i

DISPLAY j

DISPLAY i USING”*******”

DISPLAY j USING”*******”

DISPLAY i USING”&&&&&&&”

DISPLAY j USING”&&&&&&&”

DISPLAY i USING”#######”

DISPLAY j USING”#######”

DISPLAY i USING”<<<<<<<”

DISPLAY j USING”<<<<<<<”

DISPLAY i USING”——-”

DISPLAY j USING”——-”

DISPLAY i USING”+++++++”

DISPLAY j USING”+++++++”

DISPLAY i USING”$$$$$$$”

DISPLAY j USING”$$$$$$$”

DISPLAY i USING”(######)”

DISPLAY j USING”(######)”

DISPLAY i USING”###,###.&&”

DISPLAY j USING”###,###.&&”

END MAIN

在这里插入图片描述

MAIN

DISPLAY TODAY

DISPLAY TODAY USING “yyyy-mm-dd”

DISPLAY TODAY USING “yy-mm-dd”

DISPLAY TODAY USING “yy-mmm-ddd”

END MAIN

在这里插入图片描述

函数、流程控制

IMPORT 引入链接库(跳过)

SCHEMA / DATABASE 声明数据库

使用 SCHEMA 声明数据库时,只会在编译过程中使用到声明的功能,执行程序时并不会与数据库进行实质联机。
使用 DATABASE 声明数据库时,编译时功能相同,但执行时即会链接数据库。

在这里插入图片描述

SCHEMA ds #声明数据库ds

MAIN

DEFINE lc_zz01 LIKE zz_file.zz01

SELECT zz01 INTO lc_zz01 FROM zz_file WHERE zz01=’tiptop’

END MAIN

???????????
注:使用 SCHEMA 指令,因此并未于实际登入数据库,执行时回报如下:

Program stopped at ‘test_schema.4gl’, line number 5.

SQL statement error number -1803 (-1). Connection does not exist.

MAIN 函数与设定区块

MAIN 函数是程序执行的入口,一个完整可执行的程序只能有一个 MAIN 函数。

最简单的完整作业:

MAIN

DISPLAY “hello world!”

END MAIN

MAIN 函数可简单写成如上,也可增加一些 设定区块

DEFER 设定 可定义程序是否要拦截『当使用者按下中断(interrupt)或离开(quit)键』时所送出的系统讯号:DEFER {INTERRUPT | QUIT}

OPTIONS 设定 可变更系统默认的选项
在这里插入图片描述
Exceptions 设定 定义当遇到 SQL 错误时,系统要采什么操作。
语法格式:WHENEVER [ANY] ERROR { CONTINUE | STOP | CALL function | GOTO label }

复杂的 MAIN 函数示例:

MAIN

OPTIONS #改变一些系统默认值

INPUT NO WRAP, #输入的方式:不打转

# FORM LINE FIRST + 2, #画面开始的位置

# MESSAGE LINE LAST, #讯息显示的位置

# PROMPT LINE LAST, #提示讯息的位置

FIELD ORDER FORM #整个画面会依照 p_per 所设定的字段顺序

DEFER INTERRUPT

 

WHENEVER ERROR STOP #当发生 SQL Error 时即停止程序

 

DISPLAY “Change Exception!”

 

WHENEVER ERROR CALL chk_err #此处的 CALL 是没有括号的

 

END MAIN

FUNCTION chk_err( )

DISPLAY “Error Happened!”

END FUNCTION

FUNCTION 函数

语法:[PUBLIC | PRIVATE ] FUNCTION function_name( [arg [ , … ] ] )

当设定为 PRIVATE 时,只限本 4gl 文件内使用;连结时在 42x 或 42r 内无法看到该函数。

MAIN

CALL say_hello_public()

CALL say_hello_private()

END MAIN

FUNCTION say_hello_public()

DISPLAY “Hello, world!”

END FUNCTION

PRIVATE FUNCTION say_hello_private()

DISPLAY “Hello, Private!”

END FUNCTION

CALL 执行指定的函数,若有回传值,以 RETURNING 接回。
语法格式:CALL function ( [ parameter [,…] ] ) [ RETURNING variable [,…] ]

RETURN 返回函数所需的变量值,并停止此函式的执行。

回传单一值

MAIN

DEFINE var1 CHAR(10)

DEFINE var2 CHAR(2)

LET var1 = foo()

DISPLAY “var1 = ” || var1 — var1 = Hello

CALL foo() RETURNING var2

DISPLAY “var2 = ” || var2 — var2 = He

DISPLAY “foo() = ” foo() — foo() = Hello

END MAIN

FUNCTION foo()

RETURN “Hello”

END FUNCTION

回传单一值(布尔):

MAIN

IF foo() THEN

DISPLAY “Choice is OK!”

END IF

END MAIN

FUNCTION foo()

RETURN TRUE

END FUNCTION

回传多个值: 可用 RETURNING 接收

MAIN

DEFINE var1 CHAR(15)

DEFINE var2 CHAR(15)

CALL foo() RETURNING var1, var2

DISPLAY var1, var2

END MAIN

FUNCTION foo()

DEFINE r1 CHAR(15)

DEFINE r2 CHAR(15)

LET r1 = “return value 1”

LET r2 = “return value 2”

RETURN r1, r2

END FUNCTION

文件之间互相调用:test1.4gl 调用 test2.4gl 中的函数,并且用命令行执行 test3.4gl

test1.4gl

MAIN

DISPLAY “MAIN FUNCTION”

CALL a1()

CALL a2()

RUN “fglrun test3” # 利用RUN执行命令行

END MAIN

FUNCTION a1()

DISPLAY “SUB FUNCTION a1()”

END FUNCTION

以上程序段会呼叫另外两个 Function,并且利用 RUN 指令执行一道 unix 指令

test2.4gl

FUNCTION a2()

# a2 function

DISPLAY “SUB FUNCTION a2()”

END FUNCTION

test3.4gl

MAIN

DISPLAY “This is test3.4gl”

END MAIN

报表结构 REPORT 函数(跳过)

这是一种专门用来设定报表打印格式的函数,后续章节有详细的介绍。

IF

语法:??????MATCHES 支持正则表达式?

IF condition THEN

statement

[…]

ELSE

statement

[…]

END IF

MAIN

DEFINE name CHAR(20)

LET name = “John Smith”

IF name MATCHES “John*” THEN

DISPLAY “The first name is too common to be displayed.”

IF name MATCHES “*Smith” THEN

DISPLAY “Even the last name is too common to be displayed.”

END IF

ELSE

DISPLAY “The name is ” , name , “.”

END IF

END MAIN

CASE

语法1格式:适用于判断式比较简单,如只需判断1个数字

CASE expression-1

WHEN expression-2

{ statement | EXIT CASE }

[…]

OTHERWISE

{ statement | EXIT CASE }

[…]

END CASE

MAIN

DEFINE v CHAR(10)

LET v = “C1”

CASE v

WHEN “C1”

DISPLAY “Value is C1”

WHEN “C2”

DISPLAY “Value is C2”

WHEN “C3”

DISPLAY “Value is C3”

OTHERWISE

DISPLAY “Unexpected value”

END CASE

END MAIN

语法2格式:适用于判断式较复杂

CASE

WHEN boolean-expression

{ statement | EXIT CASE }

[…]

OTHERWISE

{ statement | EXIT CASE }

[…]

END CASE

MAIN

DEFINE v CHAR(10)

LET v = “C1″

CASE

WHEN ( v=”C1″ OR v=”C2” )

DISPLAY “Value is either C1 or C2″

WHEN ( v=”C3″ OR v=”C4” )

DISPLAY “Value is either C3 or C4”

OTHERWISE

DISPLAY “Unexpected value”

END CASE

END MAIN

语法2注意:若有两种情况成立,系统仅会走第一条符合条件的路径。

下列代码只会显示:a is ok

MAIN

DEFINE a,b INTEGER

LET a = b := 10

CASE

WHEN a = 10 DISPLAY ” a is ok ”

WHEN b = 20 DISPLAY ” b is ok ”

OTHERWISE DISPLAY ” nothing is ok ”

END CASE

END MAIN

FOR

语法:默认情况 STEP = 1

FOR counter = a TO b [ STEP value ]

statement

[…]

END FOR

MAIN

DEFINE i, i_min, i_max INTEGER

LET i_min = 1

LET i_max = 10

 

DISPLAY “Look how well I can count from ” , i_min , ” to ” , i_max

DISPLAY “I can count forwards…”

 

FOR i = i_min TO i_max # 正序

DISPLAY i

END FOR

 

DISPLAY “… and backwards!”

 

FOR i = i_max TO i_min STEP -1 #反序

DISPLAY i

END FOR

END MAIN

WHILE

语法:执行程序直到条件不成立为止。

WHILE b-expression

statement

[…]

END WHILE

MAIN

DEFINE a,b INTEGER

LET a = 20

LET b = 1

 

WHILE a > b

DISPLAY a , ” > ” , b

LET b = b + 1

END WHILE

 

END MAIN

CONTINUE

语法:跳出本次循环。

CONTINUE { FOR | FOREACH | MENU | CONSTRUCT | INPUT | WHILE }

MAIN

DEFINE i INTEGER

LET i = 0

WHILE i < 5

LET i = i + 1

DISPLAY “i = ” || i

CONTINUE WHILE

DISPLAY “This will never be displayed !”

END WHILE

END MAIN

EXIT

语法:离开控制段。

EXIT { CASE | FOR | MENU | CONSTRUCT | FOREACH | REPORT | DISPLAY | INPUT | WHILE | PROGRAM }

MAIN

DEFINE i INTEGER

LET i = 0

 

WHILE TRUE

DISPLAY “This is an infinite loop. How would you get out of here ?”

LET i = i + 1

IF i = 100 THEN

EXIT WHILE

END IF

END WHILE

 

DISPLAY “Well done.”

END MAIN

TRY…CATCH

针对重要 SQL 指令可以预先设置专用的错误处理指令。

语法:

TRY

[待侦测是否会发生问题的程序段落]

CATCH

[处理问题或回报讯息的程序段落]

END TRY

示例:

MAIN

LET lc_a = ARG_VAL(1)

TRY

DATABASE lc_a

CATCH

DISPLAY lc_a,’ not in fglprofile, number:’, SQLCA.SQLCODE

END TRY

END MAIN

SLEEP

语法:程序依指定秒数暂停。

SLEEP seconds

注意:如果 seconds < 0 或 seconds IS NULL,则程序不会停止。

MAIN

DISPLAY “Please wait 5 seconds…”

SLEEP 5 #暂停5秒

DISPLAY “Thank you.”

END MAIN

LABEL 和 GOTO()

为了程序的易读性和结构性,请不要使用该指令。

MAIN

DISPLAY “Before GOTO”

GOTO: label_id1

DISPLAY “Never Been Displayed”

LABEL label_id1:

DISPLAY “After GOTO”

END MAIN

常用的内置函数(built-in functions)

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_43734095/article/details/112761278

 

转载请注明:赫非域 » 【实习之T100开发】Genero FGL (TIPTOP4GL) 学习笔记1