今天有个在工商银行工作的哥们,打电话告诉我,他有一个Excel文件,有一些行重复了,需要把那些重复的行删除掉。虽然我不是很喜欢干OA的活,但是哥们的忙还是要帮的,接!
发给我的是一个csv文件,里面有45000多条记录,大概的样子是这样:

BILLNO BUNDLE ACCEPTBANK HOLDER BUYTYPE AMOUNT
AA0100003443 2.00E+11 87647 87649 2 10000000
AA0100003444 2.00E+11 87647 87649 2 10000000

有些记录的BILLNO重复了,重复的据说大概有几百条,所有BILLNO重复的记录只要留一条就可以了。其余的要删除掉。

看着这个记录这么整齐,我最先想到的就是关系型数据库(没办法,谁让J2EE,UML,VC,DB是我们的饭碗课程呢?),心里面已经开始默默念叨SQL语句了,“万幸”我的机器上还装了个Access 2003,虽然不咋地,也凑合着用吧。好,打开Acesss,把CSV倒入到Access中,感谢Access的强大功能,我非常顺利的得到了数据表a。下面,就容易了,我最先想到的是建立一个新表,然后把BILLNO设成Primpary Key,这样就可以保证唯一了。结果结果,后来我发现在Acess里面,这么做还真不简单:Access会自己建立一个Integer型的索引,不理我的索引,然后,插入据怎么插,失败了怎么办,都麻烦,所以就放弃了这个打算。后来想,用SQL语句直接把一个表的内容选择到另外一个标,不就OK了么,好,新建一个空白的数据表b,其结构与a完全一致。然后写SQL:

INSERT INTO b
SELECT * FROM a
WHERE a.BILLNO in
(
SELECT max(a.BILLNO) FROM a GROUP BY a.BILLNO
)

结果,执行的结果让我大跌眼镜,我P3 1G的本本,一运行这段代码,CPU立即100%,经过了5分钟都没有停的迹象。后来想也是,Access本来数据处理就不强,如果不加优化,这段SQL相当于一个两重循环,即使优化了,外层SQL也要在几万条数据里面找东西。的确效率不高,我使用数据库的尝试以失败告终。。。

后来,我想到了Office里面不是本来就可以用VBA写程序么,虽然功能不咋地,但是毕竟有阿,为啥要舍近求远呢?好,打开Visual Basic编辑器,鼠标在form上拖一个Button(寒假里面我已经教会我爹在form上拖button了),double click,开始coding。再次感谢Office的强大的帮助,很快我就找打了如何引用单元格的数据。首先,先把Excel按照BILLNO来排个序,然后用阔别N年的Visual Basic代码Coding道:

Private Sub CommandButton1_Click()

Dim i

For i = 2 To 47522  
    If Sheet1.Cells(i, 1).Value = Sheet1.Cells(i + 1, 1).Value Then  
        Sheet1.Cells(i, 1).Value = "AA"  
    End If  
Next i

End Sub

按F5,执行,果然,所有重复的行的BILLNO都被换成了"AA",只保留了一行。哈哈,然后再对BILLNO拍个序,手动选择所有都是AA的行,删除,搞定!!

像所有程序员和妓女一样,工作的时候精神高度紧张,干完了,感受到了无与伦比的乐趣……乐趣完了,应该考虑一下这次有些什么经验教训:

首先,客户的要求真是无奇不有,但是,俺们要始终坚持一点:程序员的事“只要想不到,没有做不到”。

第二:惯性思维还挺害人的,对于人到中年(嘻嘻,指的是有一定经验)的程序员来说,更是会情不自禁的这样。

第三:虽然好久没Coding,偶还没老….