Страницы: 1
RSS
Из нескольких csv сделать сводный файл, а затем сделать сводный файл по всем директориям
 
Здравствуйте! Реквестирую помощь, пожалуйста
Есть несколько директорий с массивами данных в формате csv (разделитель запятая). Файлы с данными имеют идентичные названия столбцов. Необходимо в каждой из директорий сделать сводный файл с разбивкой на столбцы а затем сделать сводный файл по всем директориям.
Нашел данный код для сводки из массива файлов, и немного исправил под себя::
Код
Sub ПримерИспользованияФункции_DATfolder2Array()
    Папка = "D:\0\AreaData_1\"    ' папка, в которой будет производиться поиск файлов DAT для обработки
    Dim ErrorsArray    ' пустой массив для ошибок

    ' считываем данные из все файлов .DAT в папке в двумерный массив
    DataArr = DATfolder2Array(Папка, 8, "1,2,4,5", ErrorsArray)
 
    ' результаты выводим на листы "errors" и "result" (они должны существовать)
    Array2worksheet Worksheets("errors"), ErrorsArray, _
                    Array("Имя файла", "Номер строки", "Данные из строки")
    Array2worksheet Worksheets("result"), DataArr, _
                    Array("0", "Label", "Area", "Feret", "FeretX", "FeretY", "FeretAngle", "MinFeret")
End Sub
Код
Function DATfolder2Array(ByVal FolderPath$, ByVal ColumnsCount As Long, _
                         ByVal TextColumns$, ByRef ErrorsArr) As Variant
    ' получает путь FolderPath$ к папке с DAT-файлами
    ' считывает из файлов все строки, в которых число записей в строке равно ColumnsCount
    ' остальные (неподходящие) строки отправляет в массив ErrorsArr
    ' (столбцы ErrorsArr: 1-имя файла, 2 - номер строки, 3 - данные)
    ' в переменной TextColumns$ через запятую перечислены номера ТЕКСТОВЫХ столбцов
    ' Возвращает двумерный массив размером N*ColumnsCount

    ReDim ErrorsArr(1 To 1000, 1 To ColumnsCount + 2)
    On Error Resume Next
 
    Dim coll As New Collection, filename
    filename = Dir(FolderPath$ & "*.csv")
    While filename <> ""
        coll.Add filename    ' считываем в колекцию coll нужные имена файлов
        filename = Dir
    Wend
 
    Dim newtxt As String, ro As String, errIndex As Long
    For Each filename In coll
        Application.StatusBar = "Обрабатывается файл: " & filename
        newtxt = ReadTXTfile(FolderPath$ & filename)
        tempArr = "": tempArr = Split(newtxt, vbNewLine)
        For i = LBound(tempArr) To UBound(tempArr)
            ro = tempArr(i): ro = Replace(ro, vbTab, ",")
            If UBound(Split(ro, ",")) <> ColumnsCount - 1 And Len(Trim(ro)) > 0 Then
                tempArr(i) = "": errIndex = errIndex + 1
                ErrorsArr(errIndex, 1) = filename
                ErrorsArr(errIndex, 2) = "Строка " & i + 1
                ErrorsArr(errIndex, 3) = ro
            End If
        Next i
        newtxt = Join(tempArr, vbNewLine)
        txt = txt & newtxt & vbNewLine: DoEvents
    Next
    While InStr(1, txt, vbNewLine & vbNewLine) > 0
        txt = Replace(txt, vbNewLine & vbNewLine, vbNewLine)
    Wend
 
    txt = Replace(txt, vbTab, ","): tempArr = Split(txt, vbNewLine)
    ReDim newArr(1 To UBound(tempArr), 1 To ColumnsCount)
 
    For i = LBound(tempArr) To UBound(tempArr)
        roArr = "": roArr = Split(tempArr(i), ",")
        For j = 1 To ColumnsCount
            newArr(i + 1, j) = roArr(j - 1)
            If "," & TextColumns$ & "," Like "*," & j & ",*" Then
                newArr(i + 1, j) = "'" & newArr(i + 1, j)
            End If
        Next j
    Next i
    DATfolder2Array = newArr
    Application.StatusBar = False
End Function
Но при включении макроса выбивает "Sub or function not defined"
Подскажите чего делать и как улучшить для моего варианта событий?
 
будет-ли это улучшением сомневаюсь, но скопируйте в модуль эту процедуру:
Код
Sub Array2worksheet(WS, ErAr, arr)
  ' это фиктивная процедура, чтобы заработал ПримерИспользованияФункции_DATfolder2Array
End Sub
Изменено: Ігор Гончаренко - 12.04.2019 01:04:59
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Ігор Гончаренко написал:
но скопируйте в модуль эту процедуру:
:D Ансверище на реквестище  :D
retgae, Игорь так намекает что потеряна процедура, которая или не перенесена из источника, где вы нашли используемый код, или там её не было.
По вопросам из тем форума, личку не читаю.
 
Цитата
retgae написал:
Файлы с данными имеют идентичные названия столбцов. Необходимо в каждой из директорий сделать сводный файл с разбивкой на столбцы а затем сделать сводный файл по всем директориям.
Т.е. Вам видимо не нужны эти навороты в коде типа ErrorsArray, номера столбцов. Тогда задачу можно решить с помощью скрипта VBS или даже BAT: в каждой подпапке папки со скриптом слить все CSV файлы в один CSV, оставив один заголовок. И в общий файл в корневой папке.
Приложите файл-пример (архив с папками и файлами).
Изменено: Казанский - 12.04.2019 12:53:56
 
Казанский,  спасибо за Ваш ответ
Да, именно так и нужно! Хотя бы сводный файл для каждой директории, потому что общий сводный все равно придется делать в одной книге и разбивать по разным листам или отдельно по столбцам для каждой директории, что наверное будет проще сделать вручную
Заранее спасибо
Изменено: retgae - 16.04.2019 15:29:42
 
Наиболее практичный путь.

1. Объедините файлы. Для этого поместите в директорию с csv-файлами следующий cmd-файл и выполните его:
Код
del common.csv
copy *.csv common.csv
2. Импортируйте common.csv в Excel. Поскольку Ваши файлы имеют "международный" формат (запятая - разделитель полей; дробная часть числа отделяется точкой), проще всего это сделать следующим макросом:
Код
Sub OpenCsvGlobal()
  Dim f
  f = Application.GetOpenFilename("Csv Files (*.csv), *.csv", _
      Title:="Открытие csv-файлов в ""международном"" формате")
  If f <> False Then
    Workbooks.Open f, Format:=xlCSV, local:=False
  End If
End Sub
В открывшейся книге переименуйте лист нужным Вам образом.
Удалите через Автофильтр повторы первой строки (заголовков)

3. Сохраните книгу как книгу Excel.

4. Повторите пункты 1,2 для других директорий и скопируйте листы новых книг в первую книгу.
Владимир
 
Доброе время суток.
Версия на Power Query.
Цитата
retgae написал:
все равно придется делать в одной книге и разбивать по разным листам
А какой в этом смысл, учитывая предполагаемый объём? Не проще ли сразу сводную делать?
Страницы: 1
Наверх