Хотите, чтобы VBA in excel читал очень большой CSV и создавал выходной файл небольшого подмножества CSV

У меня есть файл csv из 1,2 миллиона записей текста. Буквенно-цифровые поля заключаются в кавычки, поля даты / времени или числовые поля - нет.

Например «Фред», «Смит», 01.07.1967,2, «7, Хай-стрит», «Anytown», «Anycounty», «LS1 7AA»

Я хочу написать немного VBA в Excel (более или менее единственный доступный мне инструмент, в использовании которого я достаточно разбираюсь), который читает запись CSV по записи, выполняет проверку (как это происходит в последнем поле, почтовый индекс), а затем выводит небольшое подмножество записей размером 1,2 млн в новый выходной файл.

Я понимаю, как открыть два файла, прочитать запись, сделать с данными то, что мне нужно, и записать их (я просто выведу входную запись с префиксом, обозначающим тип исключения)

Я не знаю, как правильно разбирать CSV в VBA. Я не могу выполнять простое сканирование текста и искать запятые, поскольку в тексте иногда есть запятые (поэтому текстовые поля разделены текстом)

Есть ли фантастическая команда, которая позволила бы мне быстро получить данные из n-го поля в моей записи?

Я хочу s_work = field (s_input_record, 5), где 5 - номер поля в моем CSV ....

Большое спасибо, C

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
11
0
40 513
7

Ответы 7

Как насчет VBScript, хотя это тоже будет работать в Excel:

Set cn = CreateObject("ADODB.Connection")

'Note HDR=Yes, that is, first row contains field names '
'and FMT delimted, ie CSV '

strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\Docs\;" _
& "Extended Properties = ""text;HDR=Yes;FMT=Delimited"";"

cn.open strcon

'You would not need delimiters ('') if last field is numeric: '    
strSQL = "SELECT FieldName1, FieldName2 INTO New.csv FROM Old.csv " _
& " WHERE LastFieldName='SomeTextValue'"

'Creates new csv file
cn.Execute strSQL

Я использовал похожую технику, чтобы сделать то же самое в прошлом.

Mitch Wheat 09.01.2009 12:47

+1 это лучшее решение для такого большого набора данных, я делал это с агрегированными данными в прошлом

Our Man in Bananas 11.06.2013 14:57

@Fionnuala, я использую ваш ответ для чтения файла CSV в память. Тем не менее, у меня ограничение в 280 символов, как я указал в вопросе: stackoverflow.com/questions/34230062/… Было ли у вас такое поведение и какие-либо идеи, как преодолеть это ограничение?

izce 14.12.2015 15:00

Это не дает прямого ответа на ваш вопрос, но grep (или один из эквивалентов Windows) действительно подходит для этого, например,

grep -e <regex_filter> foo.csv > bar.csv

Варианты grep для Windows: WinGrep (wingrep.com), PowerGrep (powergrep.com) и GNU Grep для Windows (gnuwin32.sourceforge.net/packages/grep.htm).

Hank Gay 09.01.2009 13:25

Учитывая, что grep доступен в той или иной форме, и вся его цель - печатать строки, соответствующие регулярному выражению, что казалось достаточным для фильтрации, упомянутой в вопросе, это казалось естественным соответствием.

Hank Gay 09.01.2009 13:31

Следующий код должен помочь. Передо мной нет Excel, поэтому я не тестировал его, но концепция правильная.

Если это окажется слишком медленным, мы можем рассмотреть способы повышения эффективности.

Sub SelectSomeRecords()
    Dim testLine As String

    Open inputFileName For Input As #1
    Open outputFileName For Output As #2

    While Not EOF(1)
        Line Input #1, testLine
        If RecordIsInteresting(testLine) Then
            Print #2, testLine
        End If
    Wend

    Close #1
    Close #2
End Sub

Function RecordIsInteresting(recordLine As String) As Boolean
    Dim lineItems(1 to 8) As String

    GetRecordItems(lineItems(), recordLine)

    ''// do your custom checking here:
    RecordIsInteresting = lineItems(8) = "LS1 7AA"
End Function

Sub GetRecordItems(items() As String, recordLine as String)
    Dim finishString as Boolean
    Dim itemString as String
    Dim itemIndex as Integer
    Dim charIndex as Long
    Dim inQuote as Boolean
    Dim testChar as String

    inQuote = False
    charIndex = 1
    itemIndex = 1
    itemString = ""
    finishString = False

    While charIndex <= Len(recordLine)
        testChar = Mid$(recordLine, charIndex, 1)

        finishString = False

        If inQuote Then
            If testChar = Chr$(34) Then
                inQuote = False
                finishString = True
                charIndex = charIndex + 1 ''// ignore the next comma
            Else
                itemString = itemString + testChar
            End If
        Else
            If testChar = Chr$(34) Then
                inQuote = True
            ElseIf testChar = "," Then
                finishString = True
            Else
                itemString = itemString + testChar
            End If
        End If

        If finishString Then
            items(itemIndex) = itemString
            itemString = ""
            itemIndex = itemIndex + 1
        End If

        charIndex = charIndex + 1
    Wend
End Sub

Я бы посоветовал взглянуть на библиотеку регулярных выражений (вы должны увидеть ее в «Инструменты ... Ссылки» как «Microsoft VBScript Regular Expressions 5.5» или что-то очень похожее.

Здесь есть образцы как Reg Exp, так и довольно исчерпывающий посимвольный пример: http://www.xbeat.net/vbspeed/c_ParseCSV.php. Обратите внимание, что версия Regexp намного короче!

Повеселись...

Посмотрите на инструкцию Input # в справке Excel.

Пример использования:

Input #fnInput, s_Forename, s_Surname, dt_DOB, i_Something, s_Street, s_Town, s_County, s_Postcode

а затем используйте оператор Write #, чтобы снова записать совпадающие записи

Единственная проблема может заключаться в том, что формат даты на выходе будет # 1967-07-01 #, но этот формат однозначен, в отличие от 01.07.1967, который будет представлять 1 июля в Великобритании и 7 января в США. Если вам нужно сохранить форматирование даты, запишите ее в виде строки:

s_DOB = Format(dt_DOB, "dd/mm/yyyy")

Все, что вы можете делать по очереди с помощью vba в excel, вы можете делать в доступе с помощью vba; плюс намного больше, потому что это база данных, а не электронная таблица. Вам недоступен доступ?

Работать с логическими таблицами, записями и полями намного проще, чем с логическими листами, строками и столбцами.

Почему для ввода не работает "/ Data / Import External Data / Text / csv"? Вход не действительно переносимый csv?

1,2 миллиона строк не будут работать в Excel, однако данными можно управлять с помощью ADO с помощью механизма Jet, то есть механизма, на котором основан Access. Отсюда мой ответ.

Fionnuala 10.01.2009 21:23

ок - итак, чтобы подтвердить - доступ недоступен? В любом случае, если вы можете получить доступ к Jet с помощью ADO, вы также можете открыть базу данных Access mdb из Excel с помощью Excel VBA и хранить там данные - вам даже не потребуется установленный Access для этого.

dkretz 10.01.2009 21:53

Я использовал следующую производную от приведенного выше кода, чтобы успешно открыть произвольный файл csv из VBA в Excel.

Option Explicit
Public cn As Connection
Public Sub DoIt()
Dim strcon As String
Dim strsql As String
Dim rs As Recordset

Set cn = CreateObject("ADODB.Connection")

strcon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\bin\HomePlanet\;" _
& "Extended Properties = ""text;HDR=Yes;FMT=Delimited"";"

cn.Open strcon

strsql = "SELECT * FROM astuname.csv "
Set rs = New ADODB.Recordset
rs.Open strsql, cn
DoEvents ' pause here to inspect objects and properties rs.Close
End Sub

Rs (набор записей) имеет набор полей со свойством Count. Каждое поле как свойство типа.

Вы можете ссылаться на поля по порядковому номеру ...

Debug.Print rs.Fields(rs.Fields.Count - 1).Type

Этого достаточно?

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

Другие вопросы по теме