如何在多个文件中查找需要的信息

 

1.       问题描述

现在的信息系统,虽然很多都是使用数据库保存其信息,因此,内容的搜索查找实现一般都比较容易,但也有部分系统,或者某些情况需要在一些文件中查找需要的信息。
本文需要解决的问题就是这样一个问题。有一系列相同格式的2进制文件,压缩保存在不同的文件中,此二进制文件可以应用一个通用程序转化为相同文本文件(如下所示);
######    ######    ######    ######    ######
######    ######    ######    ######    ######
现在需要编制一个程序从这些文件中查找符合某些条件的行,然后保存在另一个文本文件中。

2.       解决思路

对于这样的问题,我不知道别人会怎么做,要是以前,自己肯定会自然而然的想着使用C或者C++做(因为这是自己最先学习的编程语言),或者使用VB开发(比较熟悉),而考虑如何设计一个文件读取功能,如何将文件内容保存在一个数组或者其他数据结构中,如何设计查找算法,等等。
或者可以考虑使用一个简单的桌面数据库,将数据全部读入数据库,然后再进行操作。
本文介绍的方法是使用Microsoft Excel + VBA实现所需要的功能,原因如下:
  • 文件读取等操作可以交给Excel去做;
  • 数据可以自然的保存在Excel中;
  • 查询可以调用Excel的方法,也可以自己写一个简单的顺序查找。
对于使用Excel,可以有两种考虑,或者使用VB或者其他支持COM自动化的程序调用Excel,或者在Excel中使用VBA编写需要的代码,在Excel下执行。前者可以在其他程序中嵌入使用,而Excel可以完全在后台执行,后者无需其他程序开发环境,选取完全取决于要求。
因此,程序的流程大概为:
1)        调用外部程序解压缩并转化相应的文件;
2)        逐个打开转换后的文本文件,在Excel中查找;
3)        完成操作,清理。

3.       关键代码

3.1.    调用外部程序

在VBA中,同VB一样,调用外部程序的函数为“Shell”。
Shell(pathname[,windowstyle])
执行一个可执行文件,返回一个 Variant (Double),如果成功的话,代表这个程序的任务 ID,若不成功,则会返回 0。Shell 函数是以异步方式来执行其它程序的。也就是说,用 Shell 启动的程序可能还没有完成执行过程,就已经执行到 Shell 函数之后的语句。
对于需要同步执行的程序,可以使用以下代码:
 
Private Declare Function WaitForSingleObject Lib "kernel32" _
   (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
 
Private Declare Function CloseHandle Lib "kernel32" _
   (ByVal hObject As Long) As Long
  
Private Declare Function OpenProcess Lib "kernel32" _
   (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long
 
Private Const INFINITE = -1&
Private Const SYNCHRONIZE = &H100000
 
Private Sub ShellTest()
    Dim iTask As Long, ret As Long, pHandle As Long
    iTask = Shell("notepad.exe", vbNormalFocus)            ‘开始执行
    pHandle = OpenProcess(SYNCHRONIZE, False, iTask)
    ret = WaitForSingleObject(pHandle, INFINITE)
    ret = CloseHandle(pHandle)                         ‘执行结束
    MsgBox "Process Finished!"
End Sub
 

3.2.    文件操作

程序使用的文件操作包括如何打开文件、关闭文件,在打开的文件之间切换等操作。
 
打开文件:
Application.Workbooks.OpenText        用于打开文本文件
Application.Workbooks.Open                     用于打开Excel文件
对于文件打开操作,可以使用宏录制功能,以便实现格式转化,定制列的格式等操作。
 
关闭文件:
Application.Workbooks(文件名).Close        关闭文件
Close方法参数可以是True或者False,分别表示是否保存文件。
 
切换当前文件:
Application.Workbooks(文件名). Activate
 
需要注意的是,使用Workbooks集合返回Workbook对象时,使用的文件名必须是不包括路径但包括扩展名的文件名,例如“abc.txt”,或者“xyz.xls”。

3.3.    查询操作的实现

逐个打开各个文件,就可以进行查询操作了,查询结果可以写入一个临时的Excel文件,然后保存之。
查询操作可以调用Excel的函数实现,Excel有数十个查找引用函数,例如HLookUP,VLookUP等,在VBA中使用这些函数的方法是,Application.函数名。
对于本文的情况,可以直接编写一个顺序查找,要获取各个单元格的值,最简单的方法就是使用Range对象,例如,Range(“A1”).Value,返回当前工作表活动Sheet,单元格A1的值。对于有多个打开工作表的情况,可以使用Windows(文件名).Sheets().Range,或者Workbooks(文件名). .Sheets().Range来获得Range对象。
需要说明的是,使用Range对象虽然方便,可控制性强,但Range对象的操作是非常耗时的一项操作,最好不要频繁访问,具体优化方法可以通过转化为数组等操作来进行,有兴趣者可参考笔者的“在Excel中使用VBA来筛选数据”一文(http://www.cnblogs.com/maweifeng/archive/2004/12/01/71504.html)。
一般来说,可以直接调用Excel函数和功能的,最好调用其实现,因为效率和速度都相对比使用VBA完成的代码要好。

3.4.    编写界面

在Excel下,一个VBA程序的发布形式有2种,基于Excel文件发布或者发布为一个Excel加载宏程序。对于应用界面,可以在Excel已有的菜单、工具条上增加新的内容,也可以直接在Excel图表中增加控件,或者使用自定义窗体,不同的方式有不同的应用领域。
对于增加的工具条和按钮等界面内容,一般的编程方式是,当你的加载宏或者Excel文件打开运行时,将界面内容增加到Excel中,而结束或退出时,删除其内容,因此相关代码一般写在VBA项目(工程)的ThisWookbook对象下,在此对象中,选择Workbook_Open,以及Workbook_BeforeClose事件,在其中添加工具按钮的增加,删除操作;对于加载宏,有Workbook_AddinInstall,Workbook_AddinUninstall事件。

4.       总结

使用VBA和Excel实现在多个文件中查找所需要的数据,相对于使用其他编程语言直接编写实现,要高效迅速的多,而且程序的可维护性也好很多,因此,在可以利用Office等已有资源的时候,应该优先考虑使用此类资源实现程序的有关功能。

posted on 2005-02-19 16:59  马维峰  阅读(9413)  评论(2)    收藏  举报