【问题标题】:How can I detect the end of a text file (EOF) in vbscript?如何在 vbscript 中检测文本文件 (EOF) 的结尾?
【发布时间】:2017-02-04 02:06:24
【问题描述】:

我正在使用 VBscript 将文本文件中的信息排序到 Excel 工作表中。我可以这样做,但是只读取了一行文本,并且循环控制似乎没有转到文本文件的下一行。我为此使用 AtEndOfStream,但正如我所说,我只得到一行输出。谁能帮我弄清楚如何执行程序直到文件结束?

代码如下:

Set objExcel = CreateObject("Excel.Application")            'Bind to the Excel object
objExcel.Workbooks.Add                                      'Create a new workbook.
Sheet = 1                                                   'Select the first sheet
Set objSheet = objExcel.ActiveWorkbook.Worksheets(Sheet)    'Bind to worksheet. 
objSheet.Name = "ErrorSpreadsheet"                          'Name the worksheet
strExcelPath = "c:\scripts\ErrorSpreadsheet.xlsx"           'Set the save location

objSheet.Range("A1:E1").Font.Bold = True
objExcel.Columns(5).AutoFit()
objSheet.Cells(1, 1).Value = "Date"                         'Row 1 Column 1 (A)
objSheet.Cells(1, 2).Value = "Time"                         'Row 1 Column 2 (B)
objSheet.Cells(1, 3).Value = "Category"                     'Row 1 Column 3 (C)
objSheet.Cells(1, 4).Value = "Error"                        'Row 1 Column 4 (D)
objSheet.Cells(1, 5).Value = "Index"                        'Row 1 Column 5 (E)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\scripts\ErrorMsg.txt",1)

i = 0
r = 2
c = 1
j = 0
Do While NOT objFile.AtEndOfStream 
    Redim Preserve arrFileLines(10)
    arrFileLines(i) = objFile.ReadLine
    text = arrFileLines(j)
    'Dim a() 
    a = Split(text,";")
    For Each line In a
        objSheet.Cells(r,c).Value = a(i)
        i = i + 1
        c = c + 1
    Next
    j = j + 1
    r = r + 1
Loop


objFile.Close
objExcel.ActiveWorkbook.SaveAs strExcelPath
objExcel.ActiveWorkbook.Close
objExcel.Application.Quit

我现在以没有任何错误的方式编写代码。在我的 excel 文件中,我既有标题行也有拆分文本文件的一行,但没有以下任何行。文本文件是这样写的:

       9/23;12:00;cat;error;236
       9/24;12:30;cat2;error;897
       9/24;4:06;cat5;error;23
       9/25;3:45;cat1;error;54
       9/26;1:09;cat6;error;18

所以我在 excel 中得到的输出是 Excel Output

谁能帮我弄清楚如何到达文本文件的末尾?

【问题讨论】:

  • 您确实注意到,由于您正在重用i,因此您将第一行添加到arrFileLines(0),但第二次您应该将该行添加到您的arrFileLines(i),您将将它添加到arrFileLines(4) because of the iteration in the For`循环,对吗?另外,您在arrFileLines(i) 中添加该行,但随后从arrFileLines(j) 读取,这可能会导致无法预料的问题。我会为arrFileLines 使用i(或另一个更好命名的变量),为a 使用j(或另一个更好命名的变量),并避免重复使用这样的变量
  • 另外,你在循环中的Redim Preserve arrFileLines(10) 是没用的。对于每次迭代,您都重新声明 arrFileLines,维度为 10,但保留现有数据。您可以在没有Preserve 的循环之前声明它,也可以动态地使用它,使用ReDim arrFileLines(-1) before the loop and then, inside the loop you do ReDim Preserve arrFileLines(UBound(arrFileLines)+1)` 来获得一个具有适当尺寸的数组
  • @VictorMoraes 感谢您的回复,但如果我尝试将 arrFileLines(i) = objFile.ReadLine 更改为 arrFileLines(j) = objFile.ReadLine,则会收到错误消息“下标超出范围:'i'" 在 objSheet.Cells(r,c).Value = a(i) 行中。我该如何解决这个问题?
  • 请看下面我的回答

标签: excel vbscript split eof


【解决方案1】:

为什么要单独读取每一行,而现在可以使用objFile.ReadAll 一次将整个文件读取到缓冲区中?通过这种方式 1)您立即知道 EOF(= 缓冲区长度),2)您可以轻松地“读取”缓冲区中的每一行,3)您“读取”行比读取磁盘快得多,4)您避免过度使用磁盘,尤其是。如果文件很长!

【讨论】:

    【解决方案2】:

    正如我在 cmets 中提到的,您的问题在于您的变量,因为您试图重用它们,但没有正确使用它们。 如果您手动进入您的代码,您会看到,在第一次迭代中,您将 objFile.ReadLine 添加到 arrFileLines(0),然后将 arrFileLines(0) 存储到 text
    但是随后您将进入您的内部For 循环并迭代i,这将在拆分后将For 循环保留为4

    第二次进入循环时,您会将objFile.ReadLine 添加到arrFileLines(4),然后将arrFileLines(1)(为空)存储到text。您不会收到任何错误,因为数组的维度是固定的,并且会在范围内,直到您完成对文件的遍历,但您也不会得到任何结果。
    这就是为什么我建议您使用不同的变量并避免重复使用的原因。
    实际上,如果唯一的目的是将 CSV 中的值添加到 Excel 工作表中,您甚至不需要将 objFile.ReadLine 存储到 arrFileLines 中,因为您没有使用数组。直接添加到Text即可。

    所以,通过一些修改,比如变量重命名等等,你最终会得到这样的结果:

    ' The rest of your code, Variables declarations and so forth
    
    iRow = 2    ' Starting Row
    iCol = 1    ' Starting Col
    
    Do While Not objFile.AtEndOfStream
        currLine = objFile.ReadLine
        arrLine = Split(currLine, ";")
        For Each item In arrLine
            objSheet.Cells(iRow, iCol).Value = item
            iCol = iCol + 1
        Next
        iCol = 1    ' Reset for every row
        iRow = iRow + 1
    Loop
    
    ' The rest of your code
    

    【讨论】:

    • 非常感谢,它现在可以工作了。我必须在 for 循环之后添加一个额外的行“iCol = 1”,以便格式正确,但除此之外它工作得很好。我真的很感激!
    猜你喜欢
    • 2016-08-13
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2011-05-20
    • 2020-02-22
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多