ERP中要实现界面多语言的功能,则要对各种情况的字符串进行处理并作出翻译。有些字符串的翻译是有规律可行的,遵循相应的模板模式,解析字符串,可以实现机器翻译的效果。
请看帐套数据库表的设计ADCOMP
CREATE TABLE dbo.ADCOMP( RECNUM DECIMAL (28) IDENTITY NOT NULL, COMPANY_CODE NVARCHAR (10) CONSTRAINT DF__ADCOMP__COMPANY___0E391C95 DEFAULT ('') NOT NULL, COMPANY_NAME NVARCHAR (50) CONSTRAINT DF__ADCOMP__COMPANY___0F2D40CE DEFAULT ('') NOT NULL, SUSPENDED NVARCHAR (1) NULL, DB_SERVER NVARCHAR (128) NULL, DB_DATABASE NVARCHAR (128) NULL, DB_USER NVARCHAR (128) NULL, DB_PASSWORD NVARCHAR (128) NULL, DB_DRIVER NVARCHAR (20) NULL, DB_REPT_DRIVER NVARCHAR (20) NULL, CREATED_DATE DATETIME NULL, CREATED_BY NVARCHAR (10) NULL, REVISED_DATE DATETIME NULL, REVISED_BY NVARCHAR (10) NULL)
在界面上,它的实现方法,如下图所示
数据表ADCOMP的COMPANY_CODE在界面上翻译成Company Code,字段COMPANY_NAME翻译成Company Name,这种翻译方法有规律可遵循,可以实现由程序自动翻译。
下面列举几种常见的情况,分析如何实现程序解析并翻译。
模式1 下划线分割单词 COMPANY_CODE
这种模式的特点是有含义的单词,全部以下划线分隔,有含义的单词可以是英语中的名词,也可以是自造的缩写,词与词之间用下划线分隔。下面再举几个例子分析
ITEM_NO –> Item No 物料编号, NO是Number的缩小
ITEM_CODE –> Item Code 物料编码
MAIN_LOC –> Main Loc 物料主档中的设定物料的主仓库
FG_LOC –> Fg Loc 车间控制中的参数,设定完工成品默认进仓的仓库 FG是对成品Finished Good的缩写
处理算法:先去掉下划线,以空白符号隔开,再把首字母大小,其余字母小写
模式2 多余的前缀去除 tbl_User
我一直觉得,这种命名方法有待于商议,给数据库对象加前缀。比如给所有的表加tbl,所有的视图加vw-,存储过程加sp_, 触发器加tr_,这样,形成了一套很有规律的数据库命名方案。
tbl_User 用户数据库 sp_ItemNoWhereUsed 存储过程,查询物料编号在哪些物料清单中用到
vw_User 用户视图 tr_UserNew 当增加新用户时,自动写入创建当前的用户的时间和IP地址
这种方法好处理,去掉固定的前缀即可。tbl_User变成User,然后可以自动翻译成用户。
这也产生了一个问题,经过去除前缀处理,上面有2个数据库对象均是User(tbl_Ueer,vw_User) ,这2个最终都被翻译成了User,在有些场合,这会造成语意不明。举例说明
Style 在服装生产行业,常用来指款式。一套衣服,有2个系列,3种款式,4种颜色,这样生产一个系列的衣服,就会产生2*3*4=24,一共有24件衣服。
在程序中,为了让窗体看起来美观,经常加一些漂亮的皮肤,比如Office 2007的蓝色,Office 2010的银色,形容程序的外观,也是用的Style这个词。
于是,同一个词语有2个地方用到,但是它们的含义完全不同。争对这种情况,为了实现翻译自动化,我的处理方法是把后一种情况(界面外观)的用词改成Application Style,这样可以与前一种衣服的Style区分开来。
模式3 程序类型定义,数据库表对应的内存对象 UserEntity
LLBL Gen 会给生成的表加上Entity后缀,以表示它是数据库的内存对象表示,这样,我们自己给对象定义名称时,绕开这个规定,避免给对象名加Entity后缀。
这个界面,是采用翻译自动化实现的。Source Table Name是数据库中的表定义,比如UserGroup表的定义如下
CREATE TABLE dbo.UserGroup ( UserGroup NVARCHAR (10) DEFAULT ('') NOT NULL, Description NVARCHAR (30) DEFAULT ('') NOT NULL, Suspended NVARCHAR (1) NULL, CreatedDate DATETIME NULL, CreatedBy NVARCHAR (10) NULL, RevisedDate DATETIME NULL, RevisedBy NVARCHAR (10) NULL, OwnerBranch NVARCHAR (4) NULL, SourchBranch NVARCHAR (4) NULL, Email NVARCHAR (100) NULL, CONSTRAINT PK_UserGroup PRIMARY KEY (UserGroup) ) GO
定义表之后,借助于实体生成工具,或是LLBL Gen代码生成器,生成了实体对象UserGroupEntity。
我取数据表名时,只需要把Entity去掉,就可以知道这个实体对象对应的表名。Table Name这一列是方便于阅读的,根据表的定义自动生成,没有实际的存储在数据库。
4 数据表关系,实体对象关系(一对一,一对多)的命名 BranchDetails
这个灵感来源于LLBL Gen Pro的设计器配置属性,请看下图
这几个部分节专门是设置命名规则的,Strip patterns剔除模式,Name pattern命名方法。
来看看关系的命名,文档中是这样写的
{$StartEntityName} for the name of the start entity, {$EndEntityName} for the name of the end entity, $P or $S suffix to entity name macros to pluralize or singularize them
singularize ['siŋgjulәraiz]
vt. 使显著, 使成为唯一, 使成为单数
pluralize ['pluәrәlaiz]
vt. 使成复数
vi. 兼职, 成复数形式
$P 复数表达形式,比如下图中的BranchDetail在关系中表示成了复数形式BranchDetails, 这是默认的生成方法,不源于这里的设置,也可以修改。
这其实也解释了系统中,实现一种通用的命名方案的好处,统一的命名方案,有利于界面翻译处理,也可以让程序望文生义,简单直观。