再论代码的艺术性

最近客户的医保系统增加一张报表,其他人比较忙,我就接手此项工作,看到代码,晕了。

医保的报表都要导入到dbf文件,我看到十几张报表都是这样写的:

procedure TMainFrame.actTjExecute(Sender: TObject);
begin
  case PageControl1.ActivePageIndex of
    0:QueryData_Flgf;
    1:QueryData_CzMJz;
    2:QuereyData_CzZy;
    3:QueryData_CzMJzTsry;
    4:QueryData_CzZyTsry;
    5:QueryData_GbMjz;
    6:QueryData_GbZy;
    7:QueryData_JbMJz;
    8:QueryData_JbZy;
    9:QueryData_Hzbkjs;
    10:QueryData_XczMjz;
    11:QueryData_XczZy;
    12:QueryData_GsMjz;
    13:QueryData_GsZy;
  end;
end;


procedure TMainFrame.QueryData_GbMjz;
var
  cds:TClientDataSet;
  ModelName,FileName,ProcName,FieldGuID:string;
  fra:TFraDataView;
  Sby:string;
begin
  ModelName:='城镇自由职业人员和个保人员门急诊费用结算库.DBF';
  SBY:=Get_SBY;
  FileName:='ZNE9'+FormatDateTime('YY',StartDt.DateTime)+Sby+'1'+'.DBF';
  ProcName:='SHYB_GbMjzjs_Insert';
  fra:=fraGbMjz;
  FieldGuID:='{754C6AE0-0F6C-4805-8C39-9A047CA639F4}';
  PubQuery(ModelName,FileName,ProcName,fra,FieldGuID);
  cds:=fraGbMjz.cdsData;
  if cds.IsEmpty then Exit;
end

  cds.First;
  cds.DisableControls;
  while not cds.Eof do
  begin
    ShowStep(cds.RecNo,cds.RecordCount);
    SQL:='Insert into '+FileName+' (Name,BxID,YBID,KsID,KsNA,JzDate,JzNum,Grxz ,Jytotfy,Grxj,Grzfd,Grzfl,'
        +'Fjbx,Totfy,Fy00,Fy01, Fy02,Fy03,Fy04,Fy05, Fy06,Fy07, Fy08, Fy09,Fy10,Flgrzf,'
        +'Fy20,Fy21, Fy22,Fy23,Fy24,Fy25,Fy26,Fy27,Fy28,Fy29,'
        +'Fy30,Zf ,ZdICD,ZdName,Bjqk,Daa,YyID ,Lsh)'
        +' values ('
        +' '+Quotedstr(cds.FieldByName('Name').AsString)+','
        +' '+Quotedstr(cds.FieldByName('BxID').AsString)+','
        +' '+Quotedstr(cds.FieldByName('YBID').AsString)+','
        +' '+Quotedstr(cds.FieldByName('KsID').AsString)+','
        +' '+Quotedstr(cds.FieldByName('KsNA').AsString)+','
        +' '+Quotedstr(cds.FieldByName('JzDate').AsString)+','
        +' '+cds.FieldByName('JzNum').AsString+','
        +' '+Quotedstr(cds.FieldByName('Grxz').AsString)+','
        +' '+cds.FieldByName('Jytotfy').AsString+','
        +' '+cds.FieldByName('Grxj').AsString+','
        +' '+cds.FieldByName('Grzfd').AsString+','
        +' '+cds.FieldByName('Grzfl').AsString+','
        +' '+cds.FieldByName('Fjbx').AsString+','
        +' '+cds.FieldByName('Totfy').AsString+','
        +' '+cds.FieldByName('Fy00').AsString+','
        +' '+cds.FieldByName('Fy01').AsString+','
        +' '+cds.FieldByName('Fy02').AsString+','
        +' '+cds.FieldByName('Fy03').AsString+','
        +' '+cds.FieldByName('Fy04').AsString+','
        +' '+cds.FieldByName('Fy05').AsString+','
        +' '+cds.FieldByName('Fy06').AsString+','
        +' '+cds.FieldByName('Fy07').AsString+','
        +' '+cds.FieldByName('Fy08').AsString+','
        +' '+cds.FieldByName('Fy09').AsString+','
        +' '+cds.FieldByName('Fy10').AsString+','
        +' '+cds.FieldByName('Flgrzf').AsString+','
        +' '+cds.FieldByName('Fy20').AsString+','
        +' '+cds.FieldByName('Fy21').AsString+','
        +' '+cds.FieldByName('Fy22').AsString+','
        +' '+cds.FieldByName('Fy23').AsString+','
        +' '+cds.FieldByName('Fy24').AsString+','
        +' '+cds.FieldByName('Fy25').AsString+','
        +' '+cds.FieldByName('Fy26').AsString+','
        +' '+cds.FieldByName('Fy27').AsString+','
        +' '+cds.FieldByName('Fy28').AsString+','
        +' '+cds.FieldByName('Fy29').AsString+','
        +' '+cds.FieldByName('Fy30').AsString+','
        +' '+cds.FieldByName('Zf').AsString+','
        +' '+Quotedstr(cds.FieldByName('ZdICD').AsString)+','
        +' '+Quotedstr(cds.FieldByName('ZdName').AsString)+','
        +' '+Quotedstr(cds.FieldByName('Bjqk').AsString)+','
        +' '+Quotedstr(cds.FieldByName('Daa').AsString)+','
        +' '+Quotedstr(cds.FieldByName('YyID').AsString)+','
        +' '+Quotedstr(cds.FieldByName('Lsh').AsString)+''
        +' )';
    ExecSQL(sql,query);
    cds.Next;
  end;
  Result:=True;
  cds.EnableControls;
end

14张报表,每张都是这么写的,我超级佩服这个程序员,好有毅力,但是,我不喜欢这样的代码,这种代码就是在拼体力,经过观察,发现,报表的参数都一样,返回的字段不相同,dbf也不相同,这样看起来,其实可以写一个通用代码,存储过程和字段作为配置信息,这样新增报表,只要写配置文件就可以了,于是这么做:

1.首先报表的配置用XML实现,例如:

<?xml version="1.0" encoding="gb2312"?>
<root version="1">
<rep ModelName="异地参保人员住院费用结算库.DBF" FileName="YNE9YYMX.DBF" ProcName="SHYB.YDJS_Zyfyjs" FieldDefineGUID="{B993A6D9-53B1-4F28-B2BA-E38B54B38BEA}">
 <dbf fields="ZYID=S(10),NAME=S(32),BXID=S(18),YBID=S(10),CYDATE=S(8),ZYDNUM=N,ZYJGBZ=S(1),KSID=S(5),KSNA=S(10),GRXZ=S(1),JYTOTFY=N,GRXJD=N,GRXJQ=N,TCZF=N,TOTFY=N,FY01=N,FY02=N,FY03=N,FY04=N,FY05=N,FY06=N,FY07=N,FY08=N,FY09=N,FY10=N,FY11=N,FY12=N,FY13=N,FY14=N,FY15=N,FLGRZF=N,FY20=N,FY21=N,FY22=N,FY23=N,FY24=N,FY25=N,FY26=N,FY27=N,FY28=N,FY29=N,FY30=N,FY31=N,FY32=N,FY33=N,FY34=N,ZF=N,ZDICD=S(11),ZDNAME=S(20),BJQK=S(1),DAA=S(7),YYID=S(11),LSH=S,GRZFLD=N,GRZFLQ=N,FJBX=N"/>
</rep>
<mark hint="FileName YNE9YYMX.DBF  YYM 年和月 M用16进制表示" />
  <rep.a name="上海市异地就医人员住院费用医疗机构结算表(国家平台A)" tableid="沪异地3号表(A)" section="异地结算住院A表" modelname="上海医保\上海市异地住院费用医疗机构结算表a.ost">
    <colfield colfield="1=F01,2=YYID,3=Name,4=YBID,5=CyDate,6=ZydNum,7=xm,8=ksna,9=totfy,10=Grxjq,11=Grzfhj,12=Tczf,13=zdName" mark="定义字段和列的关系"/>
    <sumfield sumfield="9=totfy,10=Grxjq,11=Grzfhj,12=Tczf" mark="定义哪些字段需要求和"/>     
  </rep.a>
  <rep.b name="上海市异地就医人员住院费用医疗机构结算表(国家平台B)" tableid="沪异地3号表(B)" section="异地结算住院B表" modelname="上海医保\上海市异地住院费用医疗机构结算表b.ost">
    <colfield colfield="1=F01,2=BXID,3=Fy01,4=Fy02,5=Fy03,6=Fy04,7=Fy05,8=Fy06,9=Fy07,10=FY08,11=FY09,12=Fy10,13=FY11,14=FY12,15=FY13,16=FY14,17=FY15,18=grxjq,19=totfy" mark="定义字段和列的关系"/>
    <sumfield sumfield="3=Fy01,4=Fy02,5=Fy03,6=Fy04,7=Fy05,8=Fy06,9=Fy07,10=FY08,11=FY09,12=Fy10,13=FY11,14=FY12,15=FY13,16=FY14,17=FY15,18=grxjq,19=totfy" mark="定义哪些字段需要求和"/>     
  </rep.b>
</root>

xml定义了所需的存储过程,以及dbf的字段,及字段类型,colField定义导出报表时,各列对应哪个字段。

2.Delphi就简单了

//获取报表配置信息
  dicRepList.FindData('RepID',fra.RepID,false);
  xml:= dicRepList.cdsData.FieldByName('Define').AsString;
  doc:= T_XMLDOc.Create;
  doc.Open(XML);
  iNode:=doc.root.ChildNodes.FindNode('rep');

  ModelName:= iNode.Attributes['ModelName'];   
  Sby:=Get_Sby;
  FileName:= iNode.Attributes['FileName'];
  YYM:= FormatDateTime('YY',StartDt.DateTime)+Sby;
  FileName:= StringReplace(FileName,'YYM',YYM,[]);
  ProcName:= iNode.Attributes['ProcName']; //'SHYB.CzZyfyjs_Tsry';
  FieldGuID:= iNode.Attributes['FieldDefineGUID'];// '{D047B3A9-0BCA-4392-B0AF-3CF3E1E10B94}';
 
  PubQuery(ModelName,FileName,ProcName,fra,FieldGuID);
  cds:=fra.cdsData;
  if cds.IsEmpty then Exit;
  //if Dbf.CzZyjs_Tsry(cds,q1,FileName) then
  {DBF公用导出函数;
  FieldNames:=Node.Attributes['fields'];
  doc.Free;

  sList:=TStringList.Create;
  ExtractStrings([','],[],Pchar(FieldNames),sList);
  

  Result:=False;
  cds.First;
  cds.DisableControls;
  while not cds.Eof do
  begin
    Ins:='';
    Vals:='';

    for i:=0 to sList.Count-1 do
    begin
      iPos:=pos('=',sList[i]);
      FieldName:= copy(sList[i],1,iPos-1);
      ins:=ins+','+FieldName;//获取字段名
      sVal:=trim(cds.FieldByName(FieldName).AsString);
      str:=copy(sList[i],iPos+1,1);
      if str='S' then
        sVal:= QuotedStr(sVal);
      Vals:=Vals+', '+sVal;
    end;
    Delete(ins,1,1);
    delete(Vals,1,1);
    sql:='insert into '+FileName+' ( '+ins+' ) values( '+Vals+' )';

    ShowStep(cds.RecNo,cds.RecordCount);
    ExecSQL(sql,query);
    cds.Next;
  end;
  Result:=True;
  cds.EnableControls;
  sList.Free;


从此,只要定义XML就可以完成报表的查询和导出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值