读书人

delphi7数据无关性接口设计解决办法

发布时间: 2012-03-24 14:00:46 作者: rapoo

delphi7数据无关性接口设计
题目:实现EXCEL导入数据库功能
要求:1、定义class结构ClassC表示对应的表结构;该类包含表的属性,以及属性值的合法性验证方法check()和保存方法savedata()
2、InterfaceB定义接口,有两个未实现方法check()、savedata();
3、定义类ClassA包含InterfaceB动态数组
实现效果满足:
1、调用ClassA能够实现对应ClassC的check和savedata;
2、增加了ClassD表结构,不需要修改InterfaceB和ClassA,可以直接使用该结构


不知道我描述的是否清楚。
请大家帮我设计下?
我实现了一部分,ClassA有多条记录的时候,调用ClassC的savedata、check方法总报地址错误。困惑中
描述的越具体越好

[解决办法]
感觉像Java程序员转过来的,哈哈。
这么做这么能体现Delphi在R&D方面的优越性呢?

Delphi(Pascal) code
uses Systemvar excelTemp, sheetTemp: OleVariant; stemp: string;     excelTemp.WorkBooks.Open(sFileName);  sheetTemp := excelTemp.WorkBooks[1].WorkSheets[1];  stemp := Trim(sheetTemp.cells[1, 1]);  if Pos('日期', stemp) = 0 then  //检查待导入的Excel格式是否正确  begin    Result := -1;    Exit;  end;   stemp := Trim(sheetTemp.cells[2, 1]);  if Pos('订单号', stemp) = 0 then  begin    Result := -1;    Exit;  end;       I := 3;  //第3行开始读取  while True do  begin    PayWay := GetLastValue(PayWay,Trim(sheetTemp.cells[I, 20]));    TemBankOrderNo := GetLastValue(TemBankOrderNo, Trim(sheetTemp.cells[I, 1]));    if Pos('总计',TemBankOrderNo) >0 then   //读到“总计”代表到了最后一行,最后一行不导入      Break;       PayWay := GetLastValue(PayWay,Trim(sheetTemp.cells[I, 20]));    TemBankOrderNo := GetLastValue(TemBankOrderNo, Trim(sheetTemp.cells[I, 1]));    if Pos('计',TemBankOrderNo) >0 then      Break;       if not(Pos('退款',PayWay) > 0) then  //该行是退款,不导入,跳到下一航    begin      Inc(I);                    Continue;    end;              SQL := 'insert into table(PayWay,BankOrderNo)values('''+PayWay+''','''+TemBankOrderNo+''')';    ADOCommand.CommandText := SQL;      ADOCommand.Execute;       end;
[解决办法]
“ PayWay := GetLastValue(PayWay,Trim(sheetTemp.cells[I, 20]));
TemBankOrderNo := GetLastValue(TemBankOrderNo, Trim(sheetTemp.cells[I, 1]));
if Pos('计',TemBankOrderNo) >0 then
Break;

这几行重复了,你懂的。。。

楼主,不一定是你的类有问题,可能是基本的读取,导入就已经出了问题。
按上面提的方式,先实现导入,然后再根据需要修改为类的方式。

个人意见哈:如果不是为了特定的目的,几行代码能搞定的事情,就不要搞复杂了。。。
[解决办法]
哈哈,那就木有办法了。抽象的不够时,用类来完成不见得减少工作量。
有时候还限制扩展。。。

以我的愚见,这个类就实现读取的功能即可。
check()、savedata()这些功能用其他类或者函数实现就可以了。
这样扩展性会好很多,调试也方便。 :)

探讨
需要导入的表太多了

[解决办法]
类的设计思路有问题:)
要导入到数据表中,只需要确定表的列与Excel的列的对应关系即可。曾经做过一个导入100+种Excel表,每种表大约对应同类表20个左右的程序,写了一个TImport类,一个TImportOptions类,跟表的固化半点关系都木有。

1.一个内存表读取要导入的表结构,(以下拉框选取要导入的表)内存表就用TClientDataSet足够,注意每个字段是一条记录。
2.以一个三方的能读excel文件的组件读取Excel,如果没有什么界面美观等等的要求,就oledb jet就成。
3.选取某条记录(表字段),双击Excel某一列,即找到对应的字段建立相应的对应关系。
4.能够将对应关系保存下来,并且装载。
5.设置好导入的起始行、终止行,导入即可:)
6.注意:把日期、字串等需要特殊处理的字段搞到一个Tstringlist中,导入之前先Valid一下,会省好多麻烦:)
[解决办法]
个人理解:
从功能目的本身出发,仅仅是为了实现导入数据而已。定义这些表类,可重用性上并不高;而且一个表就需要对应一个类。如果表结构发生变法,对应的类也要改动(也就是代码也要相应修改)。不见得有多好。

可以这么处理:1、excel表与数据库中表应有对应关系,可以先将此关系放在文件中描述;
2、写一个excel文件读取类(有什么读什么),先读取excel表头,
查询步骤1中的对应关系,确定数据库中的表以及字段,然后依据分析结果,执行...
这样的代码工作量就少很多了,要增加处理某个表,只需维护“关系”文件即可...

[解决办法]
对于一些字段的合法性检查,也可以在“关系”文件标识出来。到时可以建立一个TValidatorList管理检查,依据标识,调用相应的TValidator。因为这块,在程序的其他位置可能也会用到。
[解决办法]
COM接口太慢了,我是自己实现xlsx的解析。
http://www.ecma-international.org/publications/standards/Ecma-376.htm
[解决办法]
30行数据*260列,16个sheet大概1分钟导入导出。
[解决办法]
30万行数据*260列,16个sheet大概1分钟导入导出。
少写个万留下笑柄

读书人网 >.NET

热点推荐