Страницы: 1 2 След.
RSS
Извлечение данных в заданных столбцах из CSV макросом, Обработка внешнего файла и запись в новый файл
 
Добрий вечер!

Прошу помочь справиться с такой проблемкой.
С макросами почти не дружу. Но подключать умею :D . Есть цсв файлы со следующими характеристиками. Они лежат в одной папке.
Разделитель — запятая, кодировка — UTF8. Размеры — от ста мегабайтов до более гигабайта.
Что предстоит совершить с ними. В одной из ячеек файла с макросом будут указаны номера столбцов через запятую которые предполагается вытянуть из файлов.
В другой ячейке укажу путь к папке с цсв. В третьей ячейке будет лежать стоп слово по которому при вытягивании исключается строка с ненужной инфой.
Вытянутые столбцы нужно сохранить в новый файл, желательно тоже цсв, утф8, запятая как делитель. Желательно чтоб быстро работало на моем компьютере с 8гб памяти. Мой ексель 2007. Файлы для примера включены. files_data_import.csv — исходный файл. files_data_export.csv — результат. makros.xlsm — макрос и данные для вытягивания.
 
Тут задача комплексная прямо...  :D  
 
Господа, не жадничайте ,ну хоть маленький кусочек кода для чтения и записи потока из файла в файл покажите  ;)
Тот который наиболее подходит в моем случае.  
 
Цитата
natali.sobol написал: маленький кусочек кода
отработку по 1-му вашему файлу см. в окне Immediate VBEditor'e...
(нумерация Fields от 0 - т.е. отбирает 2-й и 3-й столбец в примере)
Код
Sub ADO_TXT_Parser() 
Dim cn As Object, rs As Object
 Dim sCon As String, sSql As String
 Dim dbfilePath As String, dbfile As String, x
 Dim i&
 Dim a As Variant
 
 col1 = 1   'НУЖНОЕ ПОЛЕ (столбец 2)
 col2 = 2   'НУЖНОЕ ПОЛЕ (столбец 3)
 
 dbfilePath = ThisWorkbook.Path & "\;"
 dbfile = "files_data_import.csv"
 
 'http://www.connectionstrings.com/
sCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbfilePath & "Extended Properties=""text;HDR=No;FMT=Delimited"";"
sSql = "SELECT * FROM " & dbfile & " AS t WHERE t.F2<>'Name'"
  
 On Error GoTo CnErrorHandler
 Set cn = CreateObject("ADODB.Connection")
 Set rs = CreateObject("ADODB.Recordset")
 
 cn.Open sCon
 rs.Open sSql, cn
'=========================================
'Debug.Print rs.Fields(col1).Name
'Debug.Print rs.Fields(col2).Name

Do Until rs.EOF
    Debug.Print rs.Fields(col1).Value
    Debug.Print rs.Fields(col2).Value
    rs.MoveNext
Loop
'=========================================
 rs.Close: cn.Close
 Set rs = Nothing
 Set cn = Nothing
Exit Sub

CnErrorHandler:
For Each ADOErr In cn.Errors        'Отладчик ошибок подключения
    MsgBox "№ ошибки " & ADOErr.Number & Chr(10) & _
    "Описание: " & ADOErr.Description & Chr(10) & _
    "Источник: " & ADOErr.Source, vbCritical
    Debug.Print "№ ошибки " & ADOErr.Number & Chr(10) & _
    "Описание: " & ADOErr.Description & Chr(10) & _
    "Источник: " & ADOErr.Source
    cn.Close
Set cn = Nothing
Next
End Sub
дальше создавайте массив, складывайте в него...
И зациклите на обработку Нескольких файлов...
И выгружайте куда хотите
Изменено: JeyCi - 17.07.2017 18:24:38
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, бесконечная вам благодарность!
Сейчас попробую.
 
Цитата
natali.sobol написал: В третьей ячейке будет лежать стоп слово по которому при вытягивании исключается строка с ненужной инфой.
в цикл формирования массива, который будете создавать между Do...Loop - вставите проверку на ваше слово (как на него натыкаетесь Exit Do) ...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Я бы посоветовал CSV импортировать все же не через ADODB, а через чтение и парсинг чистого текстового стрима (примеры). В этом случае проще "заставить" Excel не преобразовывать некоторые данные странным и понятным только ему образом  :)

Насчет экспорта в CSV - тоже есть примеры, дополнительную конвертацию кодировки можно добавить, опять же, см. предыдущую ссылку на макросы работы с текстовыми стримами.
 
AndreTM спасибо вам за участие. Изучу предложенные вами примеры.
 
Цитата
AndreTM написал: не через ADODB
спорно... через ADODB даже можно конкретные столбцы задать (но я не возилась с этим, возможно файл-схема понадобится, на скорую руку взяла всё, потом пробег по нужным полям) ... также можно отбор SQL запросом определить, чтобы не вытягивать лишнее (через WHERE)... на любителя...
а это
Цитата
AndreTM написал: некоторые данные странным и понятным только ему образом
если данные надлежащего вида, то работа с SQL через ADODB может ещё много преимуществ дать в компановке выборки нужного выходного вида... всё по ситуации
p.s.
каждый инструмент имеет свои Pro et Contra... ADODB даёт возможность работы с RecordSet'ом на лету, включая фильтрацию и сортировку... но это уже ТС сама, полагаю, решит, что и в каком объёме она хочет задействовать...
p.p.s
AndreTM спасибо за ваш view... и я согласна с вашим #2  ;) ... (по всему)
Изменено: JeyCi - 17.07.2017 14:52:37
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, благодарю что пояснили про стоп слово, сейчас разбираюсь с ADO.
Скачался MDAC_TYP.exe. После запуске ,куда то ставится и исчезает, ищу его :)
Немного туман в голове по поводу указания пути к файлам.
Их как будто 2.
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=С:\parser;
dbfilePath = ThisWorkbook.Path & "\;"
Уточните прошу вас что там нужно написать.
 
Вот именно, "если исходные данные надлежащего вида" - то никаких претензий к использованию ADO/DAO. А иначе - разбираться с сообщениями движка Jet - то ещё удовольствие. А учитывая, что ТС в первый раз видит ADODB...  :)

Кроме того, 2017 год на дворе. Есть Power Query, тогда уж его надо задействовать и пользовать.
 
Цитата
JeyCi написал:
dbfilePath = ThisWorkbook.Path & "\;"
dbfile = "files_data_import.csv"
всё же по коду есть
Path - это путь (путь текущей книги указала, т.к. файл с макросом и файл-csv у меня в одной папке лежали)... или пишите путь "C:\папка\подпапка\" (или как там у вас)
dbfile - это имя файла
Цитата
natali.sobol написал:
Скачался MDAC_TYP.exe
это вообще не знаю что - не надо (может потому что путь задали неверно)
Изменено: JeyCi - 17.07.2017 15:34:24
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
natali.sobol написал:
Source=С:\parser;
- это ваш путь? вы забыли "\" в конце
НО лучше пишите как в примере, задав его переменной!!  dbfilePath="C:\parser\" (если файл-csv лежит в этой папке)... и в строке подключения используйте эту переменную (как в примере) - & dbfilePath &
Изменено: JeyCi - 17.07.2017 15:33:46
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi благодарю за подсказки ,в окошечке иммедиате вижу проскакивают столбцы из моего файлика :)
Теперь их нужно сложить в файл экспорта, буду пытаться.
 
если данных так немного, как в файле примере, то можно выложить на лист
Код
Sub ADO_TXT_Parser() 
Dim cn As Object, rs As Object
 Dim sCon As String, sSql As String
 Dim dbfilePath As String, dbfile As String, x
 Dim i&
 Dim a As Variant
With Application: .ScreenUpdating = False: .EnableEvents = False: .DisplayAlerts = False: .Calculation = xlManual: End With 

On Error Resume Next
 ThisWorkbook.Sheets("EX").Delete
 On Error GoTo 0
 
 col1 = 1   'НУЖНОЕ ПОЛЕ (столбец 2)
 col2 = 3   'НУЖНОЕ ПОЛЕ (столбец 4)
 
 dbfilePath = ThisWorkbook.Path & "\;"
 dbfile = "files_data_import.csv"
 
 'http://www.connectionstrings.com/
sCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbfilePath & "Extended Properties=""text;HDR=Yes;FMT=Delimited"";"
sSql = "SELECT * FROM " & dbfile & " AS t"
  
 On Error GoTo CnErrorHandler
 Set cn = CreateObject("ADODB.Connection")
 Set rs = CreateObject("ADODB.Recordset")
 
 cn.Open sCon
 rs.Open sSql, cn
'=========================================
With ThisWorkbook.Worksheets.Add
    .Name = "EX"
    .Cells(1, 1) = rs.Fields(col1).Name
    .Cells(1, 2) = rs.Fields(col2).Name
     r = 1
    Do Until rs.EOF
    'ваша проверка !!
      If rs.Fields(0).Value <> "#" Then
        r = r + 1
        .Cells(r, 1) = rs.Fields(col1).Value
        .Cells(r, 2) = rs.Fields(col2).Value
        rs.MoveNext
      Else: Exit Do
      End If
    Loop
.Columns.AutoFit
End With
'=========================================
 rs.Close: cn.Close
 Set rs = Nothing
 Set cn = Nothing
'..................
With Application: .ScreenUpdating = True: .EnableEvents = True: .DisplayAlerts = True: .Calculation = xlAutomatic: End With
Exit Sub

CnErrorHandler:
'..................
With Application: .ScreenUpdating = True: .EnableEvents = True: .DisplayAlerts = True: .Calculation = xlAutomatic: End With
For Each ADOErr In cn.Errors        'Отладчик ошибок подключения
    MsgBox "№ ошибки " & ADOErr.Number & Chr(10) & _
    "Описание: " & ADOErr.Description & Chr(10) & _
    "Источник: " & ADOErr.Source, vbCritical
    Debug.Print "№ ошибки " & ADOErr.Number & Chr(10) & _
    "Описание: " & ADOErr.Description & Chr(10) & _
    "Источник: " & ADOErr.Source
    cn.Close
Set cn = Nothing
Next
End Sub
P.S.
копировать и сохранить как CSV
(перевложила файл с учётом последующих замечаний)... максимально полный и обновлённый код внутри...
Изменено: JeyCi - 18.07.2017 08:42:17
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, благодарю за содействие , но строчек будет очень много, на листе не поместятся.
Цитата
Размеры — от ста мегабайтов до более гигабайта.
 
Кстати, Exit Do не надо же делать (хотя проверять условие надо) - вроде как в вопросе было про "исключить строки со стоп-словом", а не "прервать импорт по стоп-слову".
 
Цитата
AndreTM написал: Кстати, Exit Do не надо
а зачем остальные строки ниже проверять? - если всё-что ниже не надо... я и выхожу из цикла
Цитата
natali.sobol написал: но строчек будет очень много, на листе не поместятся.
держать в памяти и думать, как обработать... я выхожу из темы - т.к., данные извлекли  ;) (Нзвание темы ветки)... а всё вместе - действительно, Комплексное ТЗ ...
это был (как пример)
Цитата
natali.sobol написал: маленький кусочек кода
p.s.
о формировании массива (можно и сразу в строку) и записи в новый файл - упоминала выше... но это, действительно, очень комплексно  
Изменено: JeyCi - 17.07.2017 17:11:22
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал:
а зачем остальные строки ниже проверять? - если всё-что ниже не надо... я и выхожу из цикла
Остальные строки нужны, заголовки пропускаем.
Цитата
я выхожу из темы - т.к., данные извлекли
Спасибо за помощь, хотя тема еще не исчерпала себя ;)
Цитата
...и запись в новый файл
 
Цитата
natali.sobol написал: Остальные строки нужны
вы говорили, что это
Цитата
natali.sobol написал: стоп слово
поняла буквально... иначе проверку в SQL на WHERE... потом всё вытянутое, переложить в новый контейнер (массив, как вариант - просто GetRows или ещё что и т.д.)... вобщем дальше и раньше - дело вкуса... успехов
(ваш вопрос похож на задание для Платного Раздела, а по объёму данных, возможно, и не совсем для xl. раз "на лист не влазит", хотя по размеру вашей оперативки - влезет, наверно, в память, чтобы потом записать в текст- csv, но надо ли так много [долго] записывать?! - лишь вопрос времени-оптимальности)
p.s. более оптимальным, наверно, будет файл csv из места выгрузки получить в нормальном виде (интересующем вас)...
Изменено: JeyCi - 17.07.2017 17:26:34
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
natali.sobol написал: о более гигабайта.
вы бы лучше в Access это делали - отобрали нужное (SQL'ем элементарно) и сохранили в csv... там тоже макросы работают (но написание другое - потому что объектная модель своя)
Изменено: JeyCi - 17.07.2017 17:31:06
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
С акцессом нет опыта работы. А в ексель есть некоторое погружение :)
Полдела уже сделано ,столбцы из файлов читаются, осталось их тока выгрузить в цсв.
 
Скрытый текст
F1 творит чудеса
 
Максим Зеленский
Скрытый текст
 
Цитата
JeyCi написал: в SQL на WHERE
чуть переписала #4 (раз уж в #15 рано выскочила из цикла),
В #15 вложила файл, в котором прописана и выгрузка в CSV с листа на этом всё...
выгрузка
p.s.
согласна с #23 - пора вам переходить на xl2010... требования для PowerQuery Microsoft Office 2010 Professional Plus (если он может в мозгах проворачивать ваши объёмы без выгрузки на лист для сохранения в CSV?)  
Изменено: JeyCi - 18.07.2017 08:57:40
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
natali.sobol, Excel не актуальный :)
F1 творит чудеса
 
Максим Зеленский, ексель уже модернизирован до 2016 :)  
 
Цитата
JeyCi написал:
чуть переписала #4 (раз уж в #15 рано выскочила из цикла)... на этом всё...
Благодарю от всей души!
 
ADO че то не срабатывает по человечески. Буквы из второго столбца отбрасываются , остаются только цифры. :(  
 
Цитата
natali.sobol написал: Буквы из второго столбца отбрасываются , остаются только цифры.  
не верю... у меня так по вашему файлу... (если вы прикладываете файл, не соответствующий реальной структуре  п2.3 Правил Форума) - вы не сможете получить ответ на ваш вопрос... пробуйте вариант, предложенный AndreTM (вопрос времени и оптимальности на ваши размеры это не снимает)

Изменено: JeyCi - 18.07.2017 13:26:37
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Страницы: 1 2 След.
Наверх