MyTetra Share
Делитесь знаниями!
Импорт очень большого текстового файла (>10 млн строк, и объем около 2 ГБ) 2
Время создания: 16.03.2019 23:43
Текстовые метки: text, txt
Раздел: !Закладки - VBA - Text
Запись: xintrea/mytetra_db_adgaver_new/master/base/1514555603lrr65m747l/text.html на raw.githubusercontent.com

Подскажите, пожалуйста как оптимально по скорости/памяти решить следующую задачу:  

Имеются ежемесячные выгрузки из внешней системы, на которую я никак повлиять не могу.
Выгрузки представляют из себя текстовые файлы с разделителямя (зачисления).
Размер файла 1,5 - 2 ГБ и количество строк более 10 млн. Каждая строка = 1 зачисление , около 30 полей, из которых мне нужно только 5. (ФИО, Сумма, Дата операции, Дата рождения, тип зачисления) . Для одного клиента может быть несколько  зачислений (строчек).

Есть справочник клиентов (текстовый файл ~4 млн.записей), в котором хранятся только ФИО + Дата рождения

Мне необходимо из первого файла выбрать клиентов которые отсутствуют в справочнике и удовлетворяют определенным условиям. Таких ежемесячно бывает примерно 30-40 тыс. ФИО + ДР отобранных добавляем в справочник.

Соответственно,  чтобы решить данную задачу мне сейчас необходимо понять следующее:
1. Как правильно с точки зрения скорости/памяти считать текстовый файл в массив если я не знаю количество строчек в нем.Мне нужно будет в какой-то момент менять размерность массива, как это сделать лучше?

2. Прежде чем сравнивать массивы, по-любому придется их сортировать по полю ФИО. Подскажите пожалуйста самый быстрый алгоритм, который не использует вспомогательные массивы. Не хочется делать дополнительные копии массива в памяти.





Реализовал свою идею через Словари. Скорость приемлемая, за исключением последнего шага. В котором я пытаюсь сохранить Словарь в файл. На меленьких файлах скорость приемлемая, но когда размер справочника 4 млн строк, а размер занимаемой памяти Excel около 1 Гб,

сохранение идет очень долго - в минуту не более 1000 строк  :

Код

Public Sub ClosePensSprav(FileName As String)

Dim txtFile As TextStream

Dim TmpString As String

Dim Ndx As Long

Dim lLowVal As Long

Dim lHighVal As Long

Dim lStep As Long

 

    If Not (FSO.FileExists(FileName)) Then FSO.CreateTextFile (FileName)

    Set txtFile = FSO.OpenTextFile(FileName, ForWriting)

     

    lHighVal = PensSprav.Count

    lStep = CLng(lHighVal / 100)

     

    For Ndx = 0 To PensSprav.Count - 1

 

        lLowVal = Ndx

        If lLowVal Mod lStep = 0 Then Application.StatusBar = "Сохранение справочника:" & FSO.GetFileName(FileName) & ": " & sObrStr(lLowVal, lHighVal) & sSuff(CInt(lLowVal / lHighVal * 100))

 

        TmpString = PensSprav.Keys(Ndx) & "|" & PensSprav.Items(Ndx)

        txtFile.WriteLine (TmpString)

        DoEvents

    Next Ndx

     

    txtFile.Close

    Application.StatusBar = False

    Set txtFile = Nothing

    Set PensSprav = Nothing

 

End Sub

Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования