Как оптимизировать производительность извлечения данных из очень большого текстового файла в Excel через VBA - PullRequest
0 голосов
/ 08 июня 2019

Я хочу получить данные о значении в сравнении со значением ячейки ключа в строке.Проблема в том, что файл действительно большой, у меня есть файл .txt, который имеет около 54000 строк и 14 столбцов, поэтому сам текстовый файл имеет размер 20 МБ, и сверх этого мне нужно получить значение столбца D относительнозначение в столбце F.Значения в столбце F уникальны.

Я до сих пор пробовал прямой подход, чтобы извлечь данные из файла .txt и скопировать их на лист, а затем запустить цикл, чтобы получить прикрепленное значение.

Но код не может извлечь данные из файла .txt даже после ожидания в течение 15 минут.

  Do While bContinue = True
  outRow = 1

  sInputFile = Application.GetOpenFilename("Text Files (*.txt), *.txt")
  If sInputFile = "False" Then
     bContinue = False
     Reset 'close any opened text file
     Exit Sub

  Else
     outCol = outCol + 2

     'process text file
     fNum = FreeFile
     Open sInputFile For Input As #fNum

     Do While Not EOF(fNum)
        outRow = outRow + 1
        Line Input #fNum, sInputRecord
        Sheets("Sheet1").Cells(outRow, outCol).Value = sInputRecord
     Loop
     Close #fNum

  End If
  Loop

  errHandler:
  Reset 
  End Sub

Я ожидал, что это займет некоторое время, но запуск этого кода займет целую вечность, чтоубивает цель использования макроса.Я просто спрашиваю, есть ли у кого-нибудь лучший способ решить эту проблему.

Ответы [ 2 ]

2 голосов
/ 08 июня 2019

Первая часть кода отсутствует, но я полагаю, вы объявили переменные. Если нет, то это может немного повлиять на производительность.

Вы также можете попробовать отключить вычисления в начале процесса, а затем переключить их обратно в конце.

Application.Calculation = xlCalculationManual
'...
Application.Calculation = xlCalculationAutomatic

Вы говорите, что вам нужен только 4-й и 6-й столбцы текста, но вы помещаете всю строку в ячейку.

Если вы действительно хотите поместить в лист только две части линии, вы можете сделать что-то вроде этого:

 With Sheets("Sheet1")
     Do While Not EOF(fNum)
        outRow = outRow + 1
        Line Input #fNum, sInputRecord
        .Cells(outRow, outCol).Value = Split(sInputRecord,";")(3)
        .Cells(outRow, outCol+1).Value = Split(sInputRecord,";")(5)
     Loop
 End With

Измените точку с запятой на любой символ, который разделитель находится в текстовом файле.

1 голос
/ 15 июня 2019

Пожалуйста, попробуйте это и отправьте отзыв.

Sub TryMe()

Dim cN As ADODB.Connection '* Connection String
Dim RS As ADODB.Recordset '* Record Set
Dim sQuery As String '* Query String
On Error GoTo ADO_ERROR

cN = New ADODB.Connection
cN.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\temp\;Extended Properties=""text;HDR=Yes;FMT=Delimited(,)"";Persist Security Info=False"
cN.ConnectionTimeout = cN.Open()

RS = New ADODB.Recordset
sQuery = "Select * From VBA.csv ORDER BY ID"
RS.ActiveConnection = cN
RS.Source = sQueryRS.Open()
If RS.EOF <> True Then
    While RS.EOF = False
    Open "c:\temp\vba_sorted.csv" For Append As 1
    Print #1, RS.Fields(0) & "," & RS.Fields(1); RS.MoveNext()
    Close #1
End If
If Not RS Is Nothing Then RS = Nothing
If Not cN Is Nothing Then cN = Nothing

ADO_ERROR:
If Err <> 0 Then
Debug.Assert (Err = 0)

MsgBox (Err.Description)
Resume Next
End If
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...