鼎捷 T100Genero FGL开发界面解读你截图是鼎捷 T100 ERP 开发设计器程序代号cxmt300举例使用Genero FGL4GL语言是 T100 标准的单档 / 查询类程序框架。左侧程序函数树中间FGL 源码右侧代码搜索窗口查找cxmt300_filter命中 38 处1. 代码结构拆解画面里的代码① 函数树左边T100 标准程序固定函数清单MAIN程序入口cxmt300_init程序初始化cxmt300_filter查询条件处理核心过滤条件解析cxmt300_filter_show带出查询条件画面你代码里大量CALL cxmt300_filter_show(xxx)用来弹出不同查询条件页签cxmt300_query执行查询把数据捞到 browser 列表cxmt300_fetch抓取单笔明细数据cxmt300_insert/modify/delete增删改标准函数cxmt300_detail_show明细画面显示② 中间代码片段解读CALL cxmt300_filter_show(xmbfucstus) CALL cxmt300_filter_show(xmbfuc037) ...cxmt300_filter_show(条件代号)用来切换不同的查询条件区块多条件页签T100 查询画面多个页签就是靠这个函数控制渲染。IF g_browser_cnt 0 THEN INITIALIZE g_errparam TO NULL LET g_errparam.extend LET g_errparam.code -100 LET g_errparam.popup TRUE CALL cl_err() ELSE CALL cxmt300_fetch(F) #顯示單身筆數 CALL cxmt300_idx_chk() END IF逻辑判断列表有没有查到数据g_browser_cnt全局变量browser 列表返回的资料笔数等于 0调用cl_err()弹出错误提示无资料不为 0cxmt300_fetch(F)抓取第一笔数据显示明细cxmt300_idx_chk索引校验PRIVATE FUNCTION cxmt300_fetch(p_flag) RETURNS ()PRIVATE FUNCTION私有函数仅当前程序内部调用fetch函数是 T100 标准负责根据 PK 主键抓取单条资料。#add-point:是 T100补丁预留标记点客户客制化修改代码会放在 add-point 区块升级系统时不会覆盖客制代码非常重要不要删除#add-point注释。2. T100 FGL 开发要点语言Genero FGL源自 4GL语法接近 Basic搭配 xml 画面定义标准程序三板斧filter接收用户查询条件拼接 where 条件query执行 SQL回写到 browser 列表fetch选中行抓取单档明细到画面字段全局变量g_browser_cnt、g_errparam、g_master都是 T100 系统内置全局变量cl_err()系统标准函数弹出提示窗口g_errparam.code是错误代------------------------------------------------------------------------------------------鼎捷 T100 FGLGenero 4GL开发要点T100 底层是Genero FGL4GL配套 4fd 画面文件标准程序有固定函数框架客制开发优先使用 #add-point禁止直接修改标准源码这是最重要的准则。一、标准程序固定架构单档 / 双档通用就是你截图 cxmt300 这套表格函数核心作用MAIN程序入口初始化、调用 initxxx_init程序初始化变量重置、画面初始、权限加载xxx_filter查询条件解析核心拼接 SQL where 条件xxx_filter_show调出查询条件页签你截图大量 call 这个xxx_query执行 SQL把结果载入 browser 列表赋值g_browser_cntxxx_fetch根据主键 PK抓取当前选中行的明细数据到画面字段xxx_insert新增保存xxx_modify修改保存xxx_delete删除xxx_input进入编辑模式字段可输入xxx_show/xxx_detail_show明细画面渲染展示xxx_browser_fillbrowser 列表填充数据核心业务流程打开程序 → init → filter(组装查询条件) → query(查列表) → fetch(取单笔明细) → insert/modify/delete(保存)二、变量命名规范强制约定T100 全系统统一g_xxx全局变量GLOBALS 块整个程序共享系统内置常用g_browser_cnt列表查询笔数、g_enterprise企业号、g_site营运据点、g_errparam错误提示结构体、g_master主档记录l_xxx局部变量仅当前 function 内部使用p_xxx函数入参传入参数s_xxx画面 screen 数组变量4fd 画面browser、单身数组DEFINE l_cnt INTEGER; --局部变量 FUNCTION cxmt300_fetch(p_flag) --p_flag 传入参数三、#add-point 客制化规则【重中之重】T100 标准程序预留#add-point:xxx namexxx客制区块所有客制代码只能写在 add-point 内部绝对不要修改 add-point 以外的标准源码好处系统版本升级打补丁时add-point 内客制代码不会被覆盖直接修改标准代码升级会丢失后期维护灾难。常见 add-point 位置filter.pre_function查询前逻辑修改查询条件fetch.pre_function抓取明细前校验 / 赋值insert.pre_save/modify.pre_save保存前校验insert.after_save/modify.after_save保存后抛转、写日志#add-point:Function前置處理 namefetch.pre_function --在这里写客制代码不要删除#add-point注释标记 LET l_xxx test #end add-point四、常用系统内置全局变量g_browser_cntquery 执行后返回的资料笔数0 代表无数据你截图里判断无资料就是这个g_errparam错误提示结构体搭配CALL cl_err()弹窗INITIALIZE g_errparam TO NULL LET g_errparam.code -100 LET g_errparam.extend 查无资料 LET g_errparam.popup TRUE CALL cl_err()g_today系统当日日期g_prog当前程序代号g_enterprise / g_site企业 营运据点T100 多组织隔离主键五、常用系统标准函数cl_err()弹出错误提示窗口最常用FGL_SET_ARR_CURR(n)设置 browser 数组当前行截图第一行就是这个cl_msg()普通信息提示非报错cl_confirm()确认弹窗是 / 否选择cl_open()开窗调用其他 T100 程序程序间跳转传参六、FGL 语法重点Genero 4GLRECORD结构体对应数据库表结构LIKE直接引用表字段类型DEFINE g_master RECORD LIKE cxmt_t.* --直接继承cxmt_t全部字段类型 END RECORDSQL 写法SELECT ... INTO 变量FGL 支持嵌入式 SQLSELECT xm001,xm002 INTO g_master.xm001,g_master.xm002 FROM cxmt_t WHERE ...PRIVATE FUNCTION私有函数仅当前 4gl 文件内调用PUBLIC FUNCTION外部可调用INITIALIZE 变量 TO NULL清空结构体 / 变量T100 开发高频操作七、开发流程新建 T100 程序标准步骤azzi900 建立程序代号如 cxmt300azzi910 建立作业代号配置菜单、权限规格设计器建表、画面 4fd 设计、拖放字段、browser 布局生成标准 FGL 程序框架系统自动生成整套 filter/query/fetch 模板在对应 add-point 内增加客制业务逻辑编译、生成 r42r 执行档测试权限分配、发布八、避坑 开发规范实战踩坑要点✅ 多组织查询 SQL必须带上 g_enterprise、g_site否则跨据点查错数据集团项目重大 bug✅ 不要在循环内写大量 SQL性能差尽量一次性查询✅ 数据库操作新增 / 修改 / 删除业务单据一定要加事务BEGIN WORK / COMMIT / ROLLBACK防止数据不一致✅ 字符串拼接 where 条件要处理单引号防止 SQL 注入T100 有标准处理函数❌ 禁止修改 #add-point 外面的标准代码升级补丁会覆盖丢失❌ 变量使用前尽量 INITIALIZE 清空避免上一笔残留脏数据❌ 直接写 SELECT 不带企业 据点多集团环境数据串掉九、常见业务开发场景新增查询条件4fd 增加查询字段 → filter 函数 add-point 追加 where 条件保存前校验insert.pre_save/modify.pre_save add-point校验不满足直接 cl_err 中断保存保存后抛转after_save 里调用 cl_open抛转到其他单据开窗选择基础资料cl_open 开窗带回料号 / 客户编号报表开发Q 查询程序b_fill 段填充自定义字段十、调试手段$FGLSQLDEBUG9开启 SQL 日志打印所有执行 SQL排查查询异常DISPLAY 变量值, l_xxx打印变量调试用正式版本删除设计器内断点调试单步跟踪 filter、query、fetch 流程查看g_browser_cnt判断 SQL 有没有返回数据-------------------------------------------------------------------------------------鼎捷 T100 FGL 客制开发完整指南核心原则标准程序客制一律写在#add-point区块内严禁修改 add-point 以外的原始标准代码保证版本升级打补丁时客制代码不会被覆盖。 T100 底层是 Genero FGL4GL开发分为【原有标准程序客制改造】和【全新开发客制程序】两大类。一、开发前准备1. 开发工具T100 设计器GDC编写 FGL 源码、4fd 画面设计、规格维护、编译、版本签入签出数据库工具查询表结构、执行 SQL 调试版本管控adzp050 规格签出、adzp060 程序签出开发前必须签出规格 程序开发完成签入多人开发避免代码冲突2. 基础资料维护新建程序才需要改原有程序不用azzi900登记程序代号如 cxmt300azzi910登记作业代号配置菜单、权限、参数数据库如有新增字段 / 新增表在规格里新增表 / 字段定义二、标准程序客制最常用比如你截图 cxmt300场景在系统自带标准单据 / 查询程序上增加业务逻辑新增查询条件、保存校验、自动赋值、单据抛转等步骤 1签出规格和程序打开 adzp050 → 搜索程序代号 → 勾选下载规格 同时签出程序进入 T100 设计器打开程序.4gl源码就是你截图的代码编辑器⚠️ 没有签出直接修改无法保存、提交版本步骤 2找到对应 #add-point 客制点位最重要标准程序内置大量预留客制区块不同业务写在不同点位表格add-point 名称使用场景filter.pre_function查询前追加查询 where 条件、修改查询参数新增查询条件放这里fetch.pre_function抓取单笔明细数据前字段赋值、额外查询fetch.post_functionfetch 抓取数据完成后画面字段回填、计算insert.pre_save新增保存之前业务校验校验失败直接报错阻止保存insert.after_save新增保存成功之后抛转单据、写日志、触发其他业务modify.pre_save修改保存前校验modify.after_save修改保存后业务逻辑delete.pre_delete删除前校验ui.pre_dialog画面初始化、按钮控制、字段只读 / 隐藏示例模板固定格式不要删除首尾标记#add-point:Function前置處理 namefilter.pre_function -- 客制代码写在这里 DEFINE l_where STRING LET l_where AND xmstatusY LET g_where_clause g_where_clause , l_where -- #end add-point步骤 34FD 画面客制界面新增字段、查询条件在规格设计器打开 4fd 画面在查询区 / 明细区拖放新增字段绑定表字段新增查询条件在CONSTRUCT区块增加字段搭配上面filter.pre_function拼接 where 条件保存规格步骤 4编译 测试设计器编译程序生成 r42r 执行档打开 T100 前台执行作业测试场景调试手段DISPLAY 变量, l_test打印变量测试完删掉开启FGLSQLDEBUG9打印完整 SQL排查查询问题断点调试单步跟踪 filter/query/fetch 流程步骤 5签入版本测试无误adzp050 签入规格adzp060 签入程序提交版本记录。三、全新客制程序开发从零开发新程序azzi900 注册程序代号 → azzi910 注册作业adzp050 新建规格定义数据库表、画面字段画面产生器r.a生成标准 4gl 程序框架自动生成整套filter/query/fetch/insert/modify函数在 add-point 点位编写业务逻辑编译、权限分配、测试、签入版本四、FGL 客制开发核心代码示例直接复制到 add-point 使用示例 1filter.pre_function 追加查询条件#add-point:Function前置處理 namefilter.pre_function --只查询启用状态的资料 LET g_where_clause g_where_clause CLIPPED, AND xmstatus 1 #end add-point示例 2insert.pre_save 保存前校验不满足弹出报错阻止保存#add-point:Function前置處理 nameinsert.pre_save IF g_master.xmqty 0 THEN INITIALIZE g_errparam TO NULL LET g_errparam.code -100 LET g_errparam.extend 数量必须大于0 LET g_errparam.popup TRUE CALL cl_err() RETURN --中断保存 END IF #end add-point示例 3cl_open 开窗调用其他 T100 程序带回参数#add-point:Function前置處理 nameui.pre_dialog DEFINE l_ret RECORD LIKE cxmt_t.* END RECORD --开窗传入参数选择后带回数据到l_ret CALL cl_open(cxmt100,g_enterprise,g_site,,g_master.xm001) RETURNING l_ret.* #end add-point五、强制开发规范 避坑红线✅ 必须遵守多组织查询 SQL必须带上 g_enterprise、g_site防止不同据点数据串号新增 / 修改 / 删除单据业务操作要使用事务BEGIN WORK / COMMIT / ROLLBACK变量使用前尽量INITIALIZE xxx TO NULL清空避免上一笔脏数据残留所有客制代码写在#add-point内部注释写清楚需求、作者、日期❌ 绝对禁止❌ 修改 add-point 以外的标准源码系统升级补丁会直接覆盖代码造成重大故障❌ 拼接 SQL 字符串不处理单引号引发 SQL 注入风险❌ 在循环体内频繁执行 SELECT造成性能低下❌ 调试用的 DISPLAY 语句直接留在正式版本代码中❌ 忘记签出版本多人开发代码覆盖丢失六、常见客制场景对应点位速查表查询画面增加查询栏位 → 4fd 增加字段 filter.pre_function拼接 where 条件保存前检查字段合法性、提示报错 →insert.pre_save / modify.pre_save保存成功自动抛转生成其他单据 →insert.after_save / modify.after_save打开画面时自动带入默认值 →fetch.post_function/ui.pre_dialog字段根据条件只读 / 隐藏、按钮控制 →ui.pre_dialog删除单据前校验关联资料 →delete.pre_delete七、版本与发布管理要点每次修改必须在版本备注写明需求单号、修改内容测试环境充分测试后再发布到正式环境正式环境更新需要同步更新规格 程序重新编译 r42r留存客制开发文档需求、修改点位、逻辑说明------------------------------------------------------------------------------T100 FGL 常用代码片段模板查询条件、弹窗、事务、开窗鼎捷 T100 FGL 常用代码片段模板全部代码只能放在#add-point区块内适配 Genero FGL 语法T100 标准函数可直接复制使用 约定g_errparam、g_where_clause、g_enterprise、g_site为 T100 内置全局变量一、查询条件相关filter.pre_function适用场景追加固定查询条件、根据画面查询栏位拼接 where放在filter.pre_function模板 1追加固定 WHERE 条件最常用#add-point:Function前置處理 namefilter.pre_function -- 客制只带出状态1的资料 LET g_where_clause g_where_clause CLIPPED, AND xmstatus 1 #end add-pointCLIPPED去掉前后空格防止拼接多余空格T100 拼接 where 推荐写法模板 2根据用户输入的查询条件动态拼接假设 4fd 查询区增加栏位p_xm001单号#add-point:Function前置處理 namefilter.pre_function DEFINE l_str STRING -- 判断画面查询栏是否有输入有值才追加条件 IF NOT p_xm001 IS NULL AND p_xm001 THEN LET l_str AND xm001 , p_xm001, LET g_where_clause g_where_clause CLIPPED, l_str END IF #end add-point模板 3模糊查询LIKE#add-point:Function前置處理 namefilter.pre_function IF NOT p_xmname IS NULL AND p_xmname THEN LET g_where_clause g_where_clause CLIPPED, AND xmname LIKE , p_xmname, % END IF #end add-point二、弹窗提示模板cl_err /cl_msg/cl_confirm模板 1错误弹窗阻止后续流程保存校验首选cl_err常用于insert.pre_save/modify.pre_save报错后直接中断保存动作#add-point:Function前置處理 nameinsert.pre_save -- 校验数量不能0 IF g_master.xmqty 0 THEN INITIALIZE g_errparam TO NULL LET g_errparam.code -100 -- 固定-100代表自定义提示 LET g_errparam.extend 数量必须大于0 LET g_errparam.popup TRUE -- true弹出窗口false只在状态栏提示 CALL cl_err() RETURN -- 返回终止后续保存逻辑 END IF #end add-point模板 2普通信息提示不中断流程cl_msgDEFINE l_msg STRING LET l_msg 当前单据单号,g_master.xm001 CALL cl_msg(l_msg)模板 3确认弹窗是 / 否选择 cl_confirmDEFINE l_ret INTEGER CALL cl_confirm(确认要执行此操作吗, l_ret) IF l_ret 1 THEN -- 用户点【是】写业务逻辑 ELSE -- 用户点【否】直接返回退出 RETURN END IF三、数据库事务模板新增 / 修改 / 删除保障数据一致性适合保存后自动抛转、多表同时写入必须处理异常回滚推荐放在insert.after_save/modify.after_save#add-point:Function後續處理 nameinsert.after_save DEFINE l_sql_err INTEGER BEGIN WORK -- 开启事务 -- 这里写多表新增/更新SQL UPDATE cxmt_t SET xmstatus2 WHERE enterprise g_enterprise AND site g_site AND xm001 g_master.xm001; INSERT INTO cxmt_log_t(enterprise,site,xm001,create_time) VALUES(g_enterprise,g_site,g_master.xm001,g_today); -- -- 判断SQL执行错误码 IF SQLCA.SQLCODE 0 THEN COMMIT WORK -- 无异常提交 CALL cl_msg(操作成功) ELSE ROLLBACK WORK -- 出错回滚撤销所有操作 LET l_sql_err SQLCA.SQLCODE INITIALIZE g_errparam TO NULL LET g_errparam.code -100 LET g_errparam.extend 数据库异常错误码,l_sql_err LET g_errparam.popup TRUE CALL cl_err() END IF #end add-point⚠️ T100 主档本身的 insert/modify 自带事务客制额外新增多张表才需要自己写 BEGIN WORK四、开窗 cl_open 模板调用其他 T100 程序参数传递 带回返回值cl_open(程序代号,企业,据点,传入画面参数,主键,RETURNING 返回记录)模板 1开窗选基础资料带回单笔资料最常用#add-point:Function前置處理 nameui.pre_dialog -- 定义接收返回值的记录和目标程序主档表一致 DEFINE l_ret RECORD LIKE cxmb_t.* END RECORD -- 开窗 cxmb100 客户资料程序 CALL cl_open(cxmb100,g_enterprise,g_site,,) RETURNING l_ret.* -- 开窗关闭后带回的值赋值到当前画面字段 IF NOT l_ret IS NULL THEN LET g_master.xmcusno l_ret.xmcusno LET g_master.xmcusname l_ret.xmcusname END IF #end add-point模板 2开窗带入参数直接定位到指定单据#add-point:Function前置處理 nameui.pre_dialog DEFINE l_ret RECORD LIKE cxmt_t.* END RECORD -- 第5个参数传入单号打开cxmt300直接定位到该笔单据 CALL cl_open(cxmt300,g_enterprise,g_site,,g_master.xm001) RETURNING l_ret.* #end add-pointcl_open 参数说明CALL cl_open(prog_code,ent,site,para_str,key_value) RETURNING rec.*prog_code目标程序代号ent企业号固定传g_enterprisesite营运据点固定传g_sitepara_str程序参数一般填空 key_value要带入的主键值RETURNING关闭开窗后带回的记录五、额外高频小片段附加常用1. 清空结构体INITIALIZE g_master TO NULL2. 单条 SELECT 查询DEFINE l_name STRING SELECT xmname INTO l_name FROM cxmb_t WHERE enterprise g_enterprise AND site g_site AND xmcusno g_master.xmcusno; IF SQLCA.SQLCODE 0 THEN CALL cl_msg(查无对应客户名称) END IF3. 控制字段只读ui.pre_dialog#add-point:Function前置處理 nameui.pre_dialog -- 画面字段 xmqty 设置为不可编辑 CALL FGL_SET_FIELD_ATTR(g_master.xmqty,readonly,1) #end add-point4. 循环读取 browser 列表数据DEFINE l_idx INTEGER FOR l_idx 1 TO g_browser_cnt -- s_browser为browser数组 IF s_browser[l_idx].xmstatus 1 THEN -- 逻辑 END IF END FOR使用注意事项所有代码必须放在#add-point区块内禁止修改标准行写 SQL 必须带上enterprisesite多组织隔离否则跨据点串数据调试用DISPLAY xxx,变量正式上线务必删除字符串拼接注意单引号避免 SQL 注入风险------------------------------------------------------------------------------封装的标准函数 在哪里查 都有哪些鼎捷 T100 标准封装公共函数查看位置 常用清单T100 的公共函数分两大类T100 平台封装公共子程序cl_、s_、q_开头业务开发最常用Genero FGL 原生内置函数语言自带不是鼎捷写的字符串 / 日期 / 数学一、去哪里查看标准函数源码重点1. 服务器目录Linux$TOP/com/lib/ # cl_xxx 核心公共函数弹窗、报错、开窗 cl_err / cl_msg / cl_open $TOP/com/sub/ # s_xxx 通用子程序事务、栏位处理、编号生成 $TOP/com/qry/ # q_xxx 查询开窗公用程序 $TOP/com/inc/ # 全局GLOBALS定义g_errparam、g_enterprise等结构体定义cl_err.4gl、cl_open.4gl就在com/lib可以直接打开看源码、入参、返回值。$TOP是环境变量代表 T100 环境根目录测试区toptst、正式区topprd、标准区topstd2. 在【T100 规格设计器】内直接查找你现在用的工具推荐就是你截图这个代码编辑器搜索框直接搜函数名例如搜cl_open搜索范围选择标准文件就能打开公共库的 4gl 源码直接看定义、参数、注释✅ 技巧想知道cl_confirm参数怎么写直接在设计器打开cl_confirm.4gl看源码。3. 文档获取鼎捷内部《T100 4GL 开发手册》包含公共函数说明鼎捷智客中心 / E-service 服务云可以下载官方开发文档注意官方不会把全部函数放公开网页大多需要鼎捷顾问账号。4. 开发小技巧写代码时不知道参数顺序可以打开对应 cl_xxx.4gl 看FUNCTION cl_open(...)的入参定义看其他标准业务程序例如 axmt、cxmt 系列怎么 CALL 这个函数参考现成写法二、T100 平台封装公共函数清单高频 cl_* 系列最常用com/lib表格函数名称用途调用示例cl_err()弹出错误提示中断业务流程搭配g_errparamCALL cl_err()cl_msg()普通信息提示不中断流程CALL cl_msg(保存成功)cl_confirm()确认弹窗【是 / 否】返回选择结果CALL cl_confirm(确定删除,l_ret)cl_open()开窗调用其他 T100 程序可传入 / 带回数据CALL cl_open(cxmt100,...) RETURNING rec.*cl_ask()弹出输入框让用户输入文字CALL cl_ask(请输入备注, l_note)cl_authority()权限校验检查用户有无作业权限CALL cl_authority(p_prog)cl_getuser()获取当前登录用户代号、名称CALL cl_getuser(l_user,l_username)cl_getdate()弹出日历选择日期CALL cl_getdate(l_date) s_* 系列com/sub业务辅助、事务、编号表格函数名称用途s_transaction_end()T100 标准事务封装推荐替代手写 BEGIN WORKCALL s_transaction_end(Y,0)Y 提交 N 回滚s_auto_docno()自动生成单据单号取单号流水s_getname()根据编号带出名称例传入部门号带出部门名称s_chk_enter()多组织校验 enterprisesites_convert_chinese()中文大小写、繁简转换s_trim()字符串去除前后空白T100 封装替代原生 q_* 系列com/qry查询公用开窗q_item品号查询开窗q_cus客户查询开窗q_sup供应商查询开窗直接 CALL q_xxx弹出基础资料选择画面带回主键和名称三、Genero FGL 原生内置函数语言自带不是鼎捷 cl 库字符串类SUBSTR(str,start,len)截取字符串LENGTH(str)字符串长度CLIPPED关键字去掉前后空格拼接 where 必用TO_CHAR()转字符串日期类ADD_MONTHS(date,n)月份加减DAY() / MONTH() / YEAR()取年月日DATE()字符串转日期数值ROUND(num,scale)四舍五入ABS()绝对值⚠️ 区分这是 Genero 语言自带不是 T100cl_公共函数。四、重点说明优先用s_transaction_end而不是手写 BEGIN WORKT100 标准程序统一用这个事务函数内部会处理日志、锁、异常比原生 SQL 事务更适配 T100。-- 提交 CALL s_transaction_end(Y,0) -- 回滚 CALL s_transaction_end(N,0)cl_open 是开发最常用跨程序开窗函数前面模板已经演示不要修改 com/lib、com/sub 下面的公共函数源码属于平台标准库一旦修改全系统所有程序都会受影响升级直接覆盖。只能调用不能改。五、快速排查示例想查cl_confirm设计器搜索cl_confirm范围【标准文件】打开cl_confirm.4gl看函数定义FUNCTION cl_confirm(p_msg STRING, OUT p_ret INTEGER)可以直接看到第 2 个参数是 OUT 输出参数接收用户选择结果。