Excel 来自 txt 的 300 万行端口数据

3 million lines of port data in Excel from txt

我需要从一个文本文件中获取 Excel 中 300 万行端口数据,每 100 万行端口开始一个新列表。代码有什么问题,告诉我?

    Sub ReadFile()
  Dim I, J
  I = 1
  J = 1
  File = "\bla.bla.bla\Desktop\vsr.txt"
  Open File For Input As #1
  Do While Not EOF(1)
    Line Input #1, MyString
    Sheets("LIST" & J).Cells(I, 1) = MyString
    If I = 1000000 Then
      I = 1
      J = J + 1
    Else
      I = I + 1
    End If
  Loop
  Close #1
End Sub

也许这样会更好。我无法测试它,因为你没有包含相同的数据,而且我不知道 port data 是什么,但它应该可以工作。

如果它有问题(或者任何时候你有代码问题)尝试使用 F8 单步执行代码 来找到确切地了解每一行发生了什么。 (更多来自 Chip Pearson here。)

Option Explicit

Sub ReadFile()
    Const fName = "\bla.bla.bla\Desktop\vsr.txt"
    Dim rowNum As Long, shtNum As Long, myString As String
    
    Open fName For Input As #1
    shtNum = 1
    Do While Not EOF(1)
        rowNum = rowNum + 1
        Line Input #1, myString
        Sheets("LIST" & shtNum).Cells(rowNum, 1) = myString
        If rowNum = 1000000 Then
            shtNum = shtNum + 1
            rowNum = 0
        End If
    Loop
    Close #1
End Sub

一些注意事项:

  • [始终]在[每个]模块的顶部使用'Option Explicit来帮助定位未正确声明或处理的变量。 (即,MyString 未申报)
  • 就个人而言,我尽量避免对变量使用像 File 这样的常用词,因为它可能是也可能不是“保留字”(即 [=56 中内置的常量或函数名) =])
  • 就个人而言,我通常将我的变量的第一个字母小写,以帮助一目了然地将我的变量与内置关键字区分开来。
  • 避免使用无意义的变量,如 IJ(尤其是在发布代码以寻求他人帮助时)。几个额外的字符使代码更容易理解,并且 modify/debug 以后。
  • 声明变量时,尽可能指定数据类型。
  • 您没有提及任何关于创建工作sheet的事情,并且您的代码也没有尝试这样做,因此此代码假定所有必需的输出工作sheet存在并且空白.
  • 使用 shtNum(或您的示例中的 J)的替代方法是使用 Int(rowNum/1000000)+1 获取 sheet 号码。这个公式returns1表示0到999999,2表示1000000到1999999等

@ashleedawg 已经写了大部分重要的东西,悬停我会再对代码进行更正。

您现在处理数据的方式意味着您在 vsr.txt 文件中查找行,然后将其复制为字符串,最后将其写入单元格。这会占用大量处理能力并且会非常慢(尤其是您访问单元格的部分。将所有文本复制到数组中然后一次粘贴它们会更有效率。

WorksheetFunction.Transpose() 是必需的,因为 excel 中的数组使用列作为第一个维度。
每 10'000 行插入代码可防止 Transpose 函数 运行 进入问题。我假设因为它是 WorksheetFunction 代码的一部分,它可能会依赖于一些旧代码,甚至可以通过这种方式专门制作成 运行 滞后代码(return 值的长度必须是长度整数数组或其他东西).
使用 myWb 可以使范围修饰符完全合格,这不是必需的,但可以为您省去很多麻烦。
使用 GROUPSIZE,您可以调整一次要导入的 Array-Block 的大小,更大的数字可能会给您更快的处理速度。

Option Explicit

Sub ReadFile()

    Const GROUPSIZE As Long = 10000 'ENTRIESPERPAGE must be divisible by this without rest to fit exactly 
    Const ENTRIESPERPAGE As Long = 1000000 
    Const fName As String = "\bla.bla.bla\Desktop\vsr.txt"

    Dim rowNum As Long
    Dim rowOffset As Long
    Dim shtNum As Long
    Dim myString(1 To GROUPSIZE) As String
    Dim myWB As Workbook
    Dim Range2Fill As String

    Set myWB = ThisWorkbook

    Open fName For Input As #1
    shtNum = 1
    rowNum = 0
    rowOffset = 0
    Do While Not EOF(1)
        rowNum = rowNum + 1
        Line Input #1, myString(rowNum)

        If rowNum = GROUPSIZE Then
            Range2Fill = "A" & rowOffset + 1 & ":A" & rowOffset + rowNum
            myWB.Worksheets(shtNum).Range(Range2Fill) = WorksheetFunction.Transpose(myString)
            Debug.Print "Sheet: " & shtNum, "Offset: " & rowOffset

            If rowOffset >= ENTRIESPERPAGE - rowNum Then
                rowOffset = 0
                shtNum = shtNum + 1
            Else
                rowOffset = rowOffset + GROUPSIZE
            End If

            rowNum = 0
        End If
    Loop

    'writes the last set of data in case there are not an exact multiple of 1M values
    Range2Fill = "A" & rowOffset + 1 & ":A" & rowOffset + rowNum
    myWB.Worksheets(shtNum).Range(Range2Fill) = WorksheetFunction.Transpose(myString)
    Close #1

End Sub

补充说明:

  • Excel 每个工作表最多支持 1,048,576 行,但预计性能会在如此多的数据点上急剧下降,尤其是当您开始计算它们或在图表中使用它们时。
  • 有更好的选择来处理像这样的大型数据集,Origin、MatLab 和 DIAdem 是我所知道并到目前为止使用过的几个,基于植物的免费替代品是 Spyder。

这是一个替代解决方案 - 将此代码保存为 bat 文件,它会将您的文件拆分为您 select 的 mb 数量,这将使您能够修改 Excel 中的数据并创建 3 * 1m 工作表:

@REM 使用 How to run a PowerShell script from a batch file @REM 和 How can I split a text file using PowerShell?

@PowerShell  ^

$upperBound =  100MB;  ^
$rootName = 'ENTER YOUR FILE PATH HERE. csv file';  ^
$from = $rootName;  ^
$fromFile = [io.file]::OpenRead($from);  ^
$buff = new-object byte[] $upperBound;  ^
$count = $idx = 0;  ^
try {  ^
    do {  ^
        'Reading ' + $upperBound;  ^
        $count = $fromFile.Read($buff, 0, $buff.Length);  ^
        if ($count -gt 0) {  ^
            $to = '{0}.{1}' -f ($rootName, $idx);  ^
            $toFile = [io.file]::OpenWrite($to);  ^
            try {  ^
                'Writing ' + $count + ' to ' + $to;  ^
                $tofile.Write($buff, 0, $count);  ^
            } finally {  ^
                $tofile.Close();  ^
            }  ^
        }  ^
        $idx ++;  ^
    } while ($count -gt 0);  ^
}  ^
finally {  ^
    $fromFile.Close();  ^
}  ^
%End PowerShell%

请注意,代码将拆分单元格内的数据,因此您需要修复生成的每个文件的第一行和最后一行。我知道这不是 VBA 解决方法,但它会起作用...修改上限以更改文件大小,即 50mb 等