如果一个系统已经设计开发成型,现在用户要求在这个系统上增加档案信息管理部分,主要功能包括归档、归档保管、信息检索查询、销毁以及审核等功能,该怎样设计和实现呢? 一般的做法是在更改原来的系统表结构,增加相关的档案系统的字段,然后再编程实现,这样的做法需要对原来系统进行比较大的改造,原系统或者档案信息系统的更改都会引起连锁反应,无疑这样做的工作量会很大。 经过思考,我的做法是不对原系统进行任何改动,只是单独增加有关档案信息的表,通过对归档的表的灵活处理来实现归档和查询,这样一来,很大程度上增加了系统的灵活性。 一、设计思路 ⒈建立了一个档案目录表,在知道档案目录表下要归档的原数据表后,用数据窗口装载该表的记录,根据归档要求进行筛选,具体归档时,在档案列表里插入一条记录,对满足要求的记录进行打包,然后根据查询要求更新查询索引表(档案号码与相关查询字段的关系表),填写归档记录的相关属性,并把打包后的二进制文件更新至该记录。 ⒉具体查询时,根据查询字段,提出具体的档案号码,进而提出具体的档案记录,然后把该二进制文件释放到本地硬盘,用数据窗口装载,根据查询要求定位到具体记录。 具体流程如下:
●需要着重考虑的问题: ⑴、如何避免重复归档? 因为归档记录已经打包,与原表无关了,我们的解决方法是:根据归档二进制文件对应的数据表名称以及相关主关键字段设置,把已经归档的记录从原表中删除(这里只是在归档显示时删除,对原表记录不做任何改动)。 ⑵、如何存储归档的实际记录? 在PB里,数据窗口的数据可以另存为一种以PSR结尾的报表文件格式,程序里用读取该文件内容后在存入档案列表的Image字段,在还原数据记录时,只需要把Image字段还原为本地的PSR文件,并装载入数据窗口,那么存储的原数据就会显现出来。 二、数据表设计 ⑴ 在档案系统里增加表来对原系统所用的表及字段进行登记,相当于在档案系统里把要归档表的情况做了个快照,在具体实现时的表名称依次是:DaTableAll(记录所要归档的表的英文名称和汉字名称)、DaTableFieldSet(记录归档原表的主关键字段设置),还有筛选表及字段设置表DaFilter_TableField,索引表及字段设置Dasy_Tablefiledset。 ⑵ 档案计划表(DaJH)。 ⑶ 建立档案目录表(Daml)以及具体目录下归档所对应的表(DaTableSet)。 ⑷ 为了加快查询档案速度,必须建立依据具体查询所对应的检索记录表,比如为了在档案系统部分里依据人员姓名或者身份证号码快速查询到具体档案号码进而调出具体电子档案,需要建立人员姓名、身份证号码、档案号码这三个字段的索引记录表(DaIndex_Member),等等. 这一部分可依据查询要求进行相应表的建立,具体编程可以用动态游标来处理初始没有考虑而其后又增加的归档要求。 ⑸ 建立档案记录列表(DaList),用于保存具体的归档记录。
三、程序实现界面
四、核心部分代码
//【选择所属归档目录】按钮的代码:
long LDAMLID,L1,LParent
string S3,S1,S2
//打开档案目录窗口,选择一个归档目录
open(w_select_da_gdml)
LDAMLID=long(message.stringparm)
if LDAMLID>0 then
//寻找它的上级目录
ddlb_1.reset()
//找到编码
select c10,c07 into :S1,:LParent from daml where c06=:LDAMLID using NowDB;
S2=S1
do while LParent-1
select c10,c07 into :S1,:LParent from daml where c06=:LParent using NowDB;
S2=S1+S2
loop
SDACODE=S2
sle_daml.text=S2
//提出所归档的数据表
declare c1 cursor for select c03,c04 from datableset where c01=:LDAMLID using NowDB;
open c1;
fetch c1 into :S1,:S2;
do while NowDB.sqlcode=0
//加入到要选择归档的电子表列表中
ddlb_1.additem(S2+fill(" ",200)+S1)
fetch c1 into :S1,:S2;
loop
close c1;
if not ddlb_1.totalitems()>0 then
cb_gd.enabled=false
else
cb_gd.enabled=true
end if
end if
//【提取数据】按钮的代码:
blob b_1
long LFOR,JFOR,KFOR,LFINDROW,LTEMP,LJSCOUNT
string S1,SFIND,STEMP,SField,SType,SPSP
datetime DT_TEMP
decimal DEC_TEMP
wf_setstatus("请稍候......正在提取数据")
tab_1.tabpage_1.dw_1.settransobject(NowDB)
tab_1.tabpage_1.dw_1.retrieve()
//检查已经归档数据
wf_setstatus("请稍候......正在检查归档数据,这可能需要比较长的时间!!!")
if tab_1.tabpage_2.dw_2.rowcount()>0 then
//提取检索字段
dw_datablefieldset.reset()
s1=gf_getoriginalsql(dw_datablefieldset)
S1=S1+" where c01='"+SCurrentTable_English+"'"
dw_datablefieldset.setsqlselect(S1)
dw_datablefieldset.retrieve()
wf_setstatus("请稍候......正在检查归档数据【"+string(tab_1.tabpage_2.dw_2.rowcount())+"】")
for LFOR=1 to tab_1.tabpage_2.dw_2.rowcount()
SPSP=tab_1.tabpage_2.dw_2.getitemstring(LFOR,"c25")
SPSP=left(SPSP,len(SPSP) - 4)
if SPSP=SDACODE then
//生成档案数据
S1=tab_1.tabpage_2.dw_2.getitemstring(LFOR,"c01")
selectblob c19 into :b_1 from dalist where c01=:S1 using NowDB;
wf_setstatus("请稍候......正在检查归档数据"+string(tab_1.tabpage_2.dw_2.rowcount())+"/"+string(string(LFOR)))
//将二进制文件解压至本地硬盘
if fileexists("c:\PSP.PSR") then
filedelete("c:\PSP.PSR")
end if
//写至内存
gf_write_mb("c:\PSP.PSR",b_1)
//装载至数据窗口
dw_PSP.reset()
dw_PSP.setredraw(false)
dw_PSP.dataobject="c:\PSP.PSR"
dw_PSP.setredraw(true)
//逐条记录检查
LJSCOUNT=dw_PSP.rowcount()
if LJSCOUNT>0 then
for JFOR=1 to LJSCOUNT
wf_setstatus("请稍候......正在检查归档数据"+string(LJSCOUNT)+"/"+string(string(JFOR)))
yield()
SFind=""
for KFOR=1 to dw_datablefieldset.rowcount()
yield()
SField=dw_datablefieldset.getitemstring(KFOR,"c02")
SType =dw_datablefieldset.getitemstring(KFOR,"c04")
//生成检索语句
STEMP=""
choose case upper(SType)
case "STRING"
STEMP=dw_psp.getitemstring(JFOR,SField)
STEMP=SField+"='"+STEMP+"'"
case "INTEGER"
LTEMP=dw_psp.getitemnumber(JFOR,SField)
STEMP=SField+"="+string(LTEMP)
case "DECIMAL"
DEC_TEMP=dw_psp.getitemdecimal(JFOR,SField)
STEMP=SField+"="+string(DEC_TEMP)
end choose
if SFind="" then
SFind=STEMP
else
SFind=SFind+" and "+STEMP
end if
next
LFINDROW=tab_1.tabpage_1.dw_1.find(SFind,1,tab_1.tabpage_1.dw_1.rowcount())
if LFINDROW>0 then tab_1.tabpage_1.dw_1.deleterow(LFINDROW)
next
end if
end if
next
end if
wf_setstatus("提取数据完毕!")
//【执行归档】按钮的代码:
boolean CanGD
string SFalse,S1,S2,S3,SDACODEPPP
long L1,L2,LMAX,LFOR,LDAJHID
string SDAMC,SDAJHMC,SDAMEMO,SGJC
long LVALUE
blob B_PSR
datetime DT_NOW,DT_NULL
setnull(DT_NULL)
CANGD=true
DT_NOW=gf_getservernowtime()
SDAMC=trim(sle_damc.text)
if SDAMC="" then
CanGD=false
SFalse="档案名称为空,不能归档案!"
end if
LDAJHID=long(left(sle_dajh.text,5))
SDAJHMC=trim( right(sle_dajh.text,len(sle_dajh.text) - 5) )
if trim(sle_dajh.text)="" then
CanGD=false
SFalse="档案计划名称为空,不能归档案!"
end if
if trim(sle_daml.text)="" then
CanGD=false
SFalse="选择的档案目录为空,不能归档案!"
end if
if not dw_1.rowcount()>0 then
CanGD=false
SFalse="没有对应的电子数据,不能归档案!"
end if
if CanGD then
openwithparm(w_ask,"确定要执行归档案吗?")
if message.stringparm="YES" then
//归档的备注字段
SDAMEMO=trim(mle_MEMO.text)
if len(SDAMEMO)>200 then
SDAMEMO=left(SDAMEMO,200)
end if
//检索关键词
SGJC=trim(Sle_GJC.text)
//生成档案编号
//取档案编码
SDACODE=trim(left(sle_daml.text,40))
L2=len(SDACODE)
wf_setstatus("请稍候......正在生成档案编号")
LMAX=0
declare CCODE cursor for select c01 from aindex_dacode using NowDB;
open CCODE;
fetch CCODE into :S1;
do while NowDB.sqlcode=0
if left(S1,l2)=SDACODE then
L1=long(right(S1,4))
if LMAX1 then
dw_1.selectrow(LFINDROW,true)
dw_1.scrolltorow(LFINDROW)
end if
next
end if
select c24 into :S1 from dalist where c01=:SDACODE using NowDB;
S1=UPPER(S1)
select c02 into :S1 from ostasystemvalue where c01=:S1 using NowDB;
if isnumber(S1) then
LPPP=long(S1)
if LPPP>0 then
for LFINDROW=1 to LPPP
if LFINDROW0 then
cb_new.visible=true
cb_del.visible=true
cb_save.visible=true
cb_new.enabled=true
cb_save.enabled=true
if LPPP>0 then
for LFINDROW=1 to LPPP
if LFINDROW
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?