使用ADO读取所有数据均在一行上的文本文件问:
您好,脚本专家!我有一个固定宽度的文本文件,该文件包含名字(6个字符)、姓氏(13个字符)和部门(9个字符),并且它们均在同一行上。我该如何使用ADO来读取呢?
--DW
答:
您好,DW。坦白地讲,我们认为您不能使用ADO(ActiveX数据对象)读取这样的文件。ADO是一种和文本文件进行交互的非常好的方法(有关详细信息,请参阅文章有关文本文件的ADO更多知识(英文)),但是,确实,ADO有些挑剔:它的每项设置都必须完全正确,否则就会拒绝工作。(不像脚本专家,即使所有事情都已准备就绪,他们还是会拒绝工作。)作为一种数据库技术,ADO需要一个“结构良好”(借用XML领域的一个术语)的数据库;它无法直接利用您那样的文件格式并从中产生数据库。(在这种情况下,可以将您的巨行分成若干单个记录。)
但是没关系;毕竟,我们可以使用虽古老但优秀而可靠的VBScript来创建结构良好的数据库。我们今天要做的就是向您展示如何快速而便捷地将您的巨大数据字符串分割成单个记录。只需通过将这些单个记录(即,文本文件中的单个记录)回显到屏幕上我们就可以达到目的。不过,您可以将这些记录段写到另一个文本文件然后使用ADO从其中读取数据。我们只是帮您开个头,剩下的就要靠您自己了。
首先,我们假定您已拥有一个类似于下面的文本文件,该文件的字段名称和两条记录包含于同一行之上:
FirstLastDeptKenMeyerFinancePilarAckermanHR
我们希望最后的结果同下面的显示更为相似:
FirstLastDept
KenMeyerFinance
PilarAckermanHR
这可能吗?当然可能:
复制代码 代码如下:
ConstForReading=1
SetobjFSO=CreateObject("Scripting.FileSystemObject")
SetobjFile=objFSO.OpenTextFile("C:ScriptsTest.txt",ForReading)
strContents=objFile.ReadAll
objFile.Close
i=False
DoUntili=True
intLength=Len(strContents)
IfintLength<28Then
ExitDo
EndIf
strLines=strLines&Left(strContents,28)&vbCrLf
strContents=Right(strContents,intLength-28)
Loop
Wscript.EchostrLines
首先定义名为ForReading的常量并将其值设置为1;我们将使用它打开要读入的文本文件。
注意:您知道您的母亲为何一直告诉您要带上帽兜或者在穿过街道的时候朝两边看吗?是的,我们脚本专家也一直告诉您在没有指定要打开的文本文件的方式的情况下是无法将其打开的:是读取、写入还是添加。一次只能执行一项操作:无法同时以读取和写入方式打开文本文件。因此需要常量ForReading。
噢,也戴上您的帽兜。外面很冷。
接下来我们创建FileSystemObject的实例并使用OpenTextFile方法打开文件C:ScriptsTest.txt。我们调用ReadAll方法以将此文件的全部内容读取到变量strContents中,然后使用Close方法关闭文件。
之后的这行代码很短并且有些古怪:
i=False
我们立即要做的就是建立Do循环,该循环用28个字符的增量来读取文件的内容(即变量strContents的值)。为什么是28个字符?因为,在每条记录中,我们使用6个字符保存名字、13个字符保存姓氏和9个字符保存部门。因此:
6+13+9=28
为了保证循环始终进行直到整个文件读取结束,我们将变量i设为False,然后执行循环直到i等于True:
DoUntili=True
我们发现,i永远不会等于True,但是别着急:我们仍可以跳出此循环,稍后就会向您显示这种神奇的功能。
在循环内部,我们首先使用Len函数来确定字符串strContents中字符的数量(对于我们的示例文件,再加上作为一条记录的标题行,共3条记录,每条28个字符,即总共84个字符)。然后是以下这一小段代码:
IfintLength<28Then
ExitDo
EndIf
这里我们要做的就是检查字符串长度是否少于28个字符。如果是,则我们一定已经到达了文件的末尾。因此,我们使用ExitDo命令退出循环。(这就是非常了不起的脚本专家设法逃离永无休止的Do循环魔掌的方式!)
若长度为28个字符或更多,则执行下面这行代码:
strLines=strLines&Left(strContents,28)&vbCrLf
此处我们创建一个新字符串strLines,它将文本文件的内容分成几条单个记录,每条记录由28个字符及一个回车换行符(vbCrLf)组成。为此,我们只需将strLine的当前内容同字符串中的前28个字符(Left函数执行的正是此操作)及VBScript的常量vbCrLf连接起来即可。第一次循环之后strLines结果如下:
FirstLastDept
明白其工作原理了吗?
在第一行(也就是我们的第一条记录)被安全地放到变量strLines中之后,接着我们就要将该信息从strContents中删除。这就是下面的代码所要执行的操作:
strContents=Right(strContents,intLength-28)
这次我们要使用Right函数从字符串末端取出x个字符,也就是逆向执行。那么我们所说的x个字符到底是什么意思?要得到x的值,我们需取到strContents的长度(84)然后减去28(单个记录的长度)。得到的结果为56(84-28=56),因此我们从字符串的末端开始向回数56个字符。这表示第一次循环之后我们会得到下面这样的结果:
KenMeyerFinancePilarAckermanHR
注意:是的,有其他的方法可以达到同样的目的,其中一些可能会节省一两行代码。不过,我们认为这种方法是最简单的。
正如您所见,我们所做的全部工作就是删除了第一条记录。现在准备返回循环,重复此过程。当然,这次strContents的长度为56;因为我们刚刚去掉了28个字符。自然,这意味着我们要停止提取此数据并停止将其添加到变量strLines中:
KenMeyerFinance
我们继续此过程直到删除变量strContents中的所有字符。此时,我们只是回显strLines的值:
FirstLastDept
KenMeyerFinance
PilarAckermanHR
如果不是一个结构良好的数据库,那我们也不知道结果会是什么样子。
如果您希望能够将数据保存到一个文本文件并可以使用ADO读取此数据,就按我们讲过的去做;或者也可以只使用VBScript的字符串处理功能来将每行分成若干单个记录。我们将决定权留给了您。