问题简单描述:
    现在有两张大数据量的excel表,一张是我们单位的物资管理台帐,大概有5万行,50列。里面记录物资采购的一些信息,例如物资名称,入库金额,入库日期,计划编号等。每有一种物资入库,根据计划号和物资名称找到对应的记录,填上入库金额和入库日期。每次一来几千张入库单,人工干很累。其实这些信息在单位的数据库中都有记录,为了能自动的填充这些信息,我们现在的想法是:从数据库下载数据,导出为excel表,比较两张表,计划号和物资相一致的就把导出的入库金额和入库日期填到我们的台帐里去。当然两张表结构不会完全一样,要不我们也没有这么做的必要了。我现在的做法:
    1.最开始用最傻的办法:先从我们的台帐第一条记录开始,去第二张表从头到尾扫描,找到了才退出。这样可想而知,速度很慢,运行1000 对1000条的要30分钟,5万对5万2个月都运行不完。
    2.在导出的表中添加三列辅助列,因为计划号中含有单位代码、月份、和物资类别,这些都是小于100的数字,分别抽出来填充三列辅助列,按他们三列排序。这样三列中数据完全一样的会在一起,在程序中用三维数组记录他们的开始行和结束行,相当于将一张大表分成很多小表。例如:单位12,月份10,物资类别55,那么数组POSITION(12,10,55).startrow记录开始行,POSITION(12,10,55).lastrow记录结束行。现在首先从我们的台帐中根据计划号,读出单位、月份、物资类别,就可以较快的正确定位,不用扫描整张导出的参照表了。这样速度能提高很多。可是还是一需要长的时间,P42.4G的都要5个小时。问题:
    1.谁还有更好的算法?我看从我们的数据库里导数据到excel里,几万行也就是3秒钟的问题,他是不是不是用每个单元格赋值的方法?该怎么做?
    2.现在编的程序虽然还是很慢,但是比人要好,晚上运行一个晚上,基本能完。但是问题又出现了,有时候会出现“部件忙”的消息框,必须人工按“切换到”,然后程序才能继续运行。因为是在晚上我们睡觉运行,所以一出现这种问题,第二天还是不能完成任务。想亲问:能不能让他忽略这个消息框,自动再次重试?相当于遇到这种问题就我们按了“切换到”按钮,继续运行。一下说了这么多,各位高手帮忙!很急,谢谢!

解决方案 »

  1.   

    首先使用jet访问excel,将数据导入数据库,比如sql server,
    然后你要怎么做就怎么做咯!
    用jet访问的话,速度是很快的。但是有一些副作用,
    就是有些字符是没有办法正确读取的。Dim myOleDbConnection As OleDbConnection = New 
       OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
       "Data Source=c:\test.xls;" & _
       "Extended Properties=""Excel 8.0;""")
    Dim myOleDbCommand As OleDbCommand = New OleDbCommand("SELECT * 
       FROM [Sheet1$]",myOleDbConnection) '如果你想读出Sheet2的内容
       ,把Sheet1$改成Sheet2$即可
    Dim myData As OledbDataAdapter= New 
       OledbDataAdapter(myOleDbCommand)
      

  2.   

    或者直接导入sql server
    select * from OpenRowSet('microsoft.jet.oledb.4.0','Excel 8.0;HDR=yes;database=c:\book1.xls;','select * from [Sheet1$]') where c like '%f%'
    这条语句是读出excel内容的,你可以直接插入数据库啊!
      

  3.   

    在Excel中处理这类问题有两个函数:vLookup、hLookup,你的问题他们能解决,速度根本不是问题,也不用编程。
      

  4.   

    你原先那种枚举比较的思路没有错,效率低是因为Excel对象本身一个一个单元格访问的效率低造成的,你可以试一下,对这个5w行的Exscel一个一个单元格的扫描一遍要多长时间?
    我不知道上面有一位提到用ADO访问Excel的效率怎么样,我虽然知道这种方法,但从来没有用过,所以提另外两个解决办法吧。
    第一个办法是,在SQL中建立一张临时表,比较时将Excel的内容写到数据库中,在从两边进行比较,到时候是使用SQL语句直接比较,还是逐条的比较都可以,效率多少会高一些;
    另一个是,采用一些算法,但肯定也不是在Excel中比较,内存要够的话,可以直接将关键的几个字段读到数组当中,然后在两个数组之间进行比较。当然,最重要的还是算法,有两个方法你可以考虑,一个找到一条匹配的,就把它从比较的列表中删掉,另外记录到一个数组中,这样,需要比较的数据逐渐减少,效率会好一点;另一个是利用数据库或listview控件,即对要比较的两批数据先对关键字段进行排序,这样,可以用下面的算法去判断:首先比较两边的第一条,如果匹配,则比较下两条;如果左边的小于右边,则把左边的指针加1,然后继续比较;如果左边大于右边,则右边的指针加1,然后左右对调继续比较。
      

  5.   

    看了这么多回帖,收获不少。用ADO访问我一直在考虑,不过我看光是从excel表导5万行50列的数据到数据库,也得一个小时,我也是用单元格赋值的方法,谁能在5秒之内完成,方法是什么?我用软件公司给我们单位做的系统导台帐到excel表中,只需要不到5秒就能完成,肯定不可能 是单元格赋值的方法,到底是什么方法?还有楼上这位大哥说的方法,给我提供了一种新的思路,不过现在的具体情况套来套去觉得还是不适合用,至于为什么,一下也说不清楚,因为你对我们的实际情况并是完全了解,不过还是得谢谢你,揭贴的时候少不了你的分;-)