Как сохранить данные нескольких документов в один csv

Автор celler, 10 марта 2015, 21:14

0 Пользователи и 1 гость просматривают эту тему.

celler

Как можно решить такую проблему. Есть очень много файлов таблиц, имеющих каждый по семь листов. На каждом из листов первые две строки пустые, в третьей - заголовки столбцов, а ниже - данные. Структура всех листов всех таблиц совершенно одинаковая, только данные в каждой разные. Можно ли как-нибудь все данные с первых листов таблиц скопировать в один csv, со вторых листов - во второй и т.д. Если это не возможно, то как сохранить данные со всех листов таблицы в один csv за один раз. Почему-то сохраняются данные только с одного листа в один приём.

rami

Цитата: celler от 10 марта 2015, 19:14Почему-то сохраняются данные только с одного листа в один приём.
В формате csv сохраняются только данные с активного листа, поэтому перед созданием файла csv нужно все данные собрать (если это возможно) на одном листе.
Цитата: celler от 10 марта 2015, 19:14Структура всех листов всех таблиц совершенно одинаковая, только данные в каждой разные. Можно ли как-нибудь все данные с первых листов таблиц скопировать в один csv, со вторых листов - во второй и т.д.
Чем больше объём данных, тем больше шансов их "утрамбовать" , но тут уже надо смотреть на данные, что можно сделать.

celler

Цитата: rami от 10 марта 2015, 20:27В формате csv сохраняются только данные с активного листа, поэтому перед созданием файла csv нужно все данные собрать (если это возможно) на одном листе.
Это очень проблематично, поскольку файлов очень много и к тому же в названии листов содержится также информация, поэтому если объединять всё на один лист в каждом документе, то придётся добавлять ещё один столбец для этой информации.
Цитата: rami от 10 марта 2015, 20:27Чем больше объём данных, тем больше шансов их "утрамбовать" , но тут уже надо смотреть на данные, что можно сделать.
Нет, "утрамбовывать" не нужно, надо просто всё объединить в один файл csv с разделителем ";" для всех первых листов, для вторых и т.д.

JohnSUN

А давай ещё раз пробежимся по задаче, уточним несколько моментов...
Цитата: celler от 10 марта 2015, 21:14
Есть очень много файлов таблиц, имеющих каждый по семь листов.
Откуда брать эти книги? Они лежат в одной папке и лишних (посторонних) файлов там нет? Или у них у всех какое-то "типовое имя" и их можно выбрать по маске? Ну, что-то вроде "Отчет_*15.ods"... Или нужно предусмотреть выбор в диалоге "Это, вот это и вот отсюда и до конца..."?
Цитата: celler от 10 марта 2015, 21:14На каждом из листов первые две строки пустые, в третьей - заголовки столбцов, а ниже - данные.
Заголовки одинаковые везде? Нужно ли перепроверять состав заголовков, чтобы нечаянно не вбросить в результирующий CSV какие-то "левые" данные?

Вызывает вопросы и такое сочетание условий:
Цитата: celler от 10 марта 2015, 21:14
Можно ли как-нибудь все данные с первых листов таблиц скопировать в один csv, со вторых листов - во второй и т.д.
Цитата: celler от 10 марта 2015, 23:03
...и к тому же в названии листов содержится также информация...
Так на что нужно ориентироваться при раскидывании данных по семи csv-файлам? На номер листа или все-таки на его имя? К сожалению (или к счастью?), изменить порядок листов очень легко - обычным драг-энд-дропом перетащил ярлычок в сторону и первый лист становится четвёртым... И сделать это можно совершенно случайно.
Опять же, а как поступать с книгами, в которых окажется шесть или восемь листов?
Цитата: celler от 10 марта 2015, 23:03
надо просто всё объединить в один файл csv с разделителем ";"
Может, для надежности и "заквотить" данные? Ну, взять каждое поле в кавычки... О каких данных идет речь? Только числа? Или многострочные тексты тоже могут попадаться?

Разумеется, лучшим решением для этой задачи будет макрос - одними формулами и встроенными механизмами здесь не обойтись.
И, по-хорошему, этот макрос не должен формировать единую сводную книгу для всех исходных данных. Он обязан писать сразу в семь csv-файлов. Основная причина для этого - фраза насчет "очень много файлов таблиц". Чтобы не нарваться в какой-то момент на предел в миллион записей, лучше сразу обойти эту опасность...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

celler

JohnSUN
Не проблема скопировать все файлы в одну папку и переименовать их по шаблону, например 0001, 0002 и т.д.
Файлы формируются автоматически, поэтому в них всё одинаково, только данные и их количество отличаются. На некоторых листах может не быть данных совсем. На всех листах 22 столбца. Порядок листов и их количество тоже всегда одинаковые, поэтому ориентироваться можно просто на номер листа. Все данные это однострочные тексты. Писать сразу в семь csv-файлов было бы наилучшим решением.

JohnSUN

Имена и расположение этих семи csv-файлов будешь задавать вручную или можно нагло впихнуть в текст макроса?
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

celler

Цитата: JohnSUN от 11 марта 2015, 11:11Имена и расположение этих семи csv-файлов будешь задавать вручную или можно нагло впихнуть в текст макроса?
Можно включить в текст макроса.

JohnSUN

Ну, в общем, получается что-то такое... Конечно, сырое и глючное, но как заготовка решения, может, и сгодится
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

celler

Цитата: JohnSUN от 11 марта 2015, 16:02Ну, в общем, получается что-то такое... Конечно, сырое и глючное, но как заготовка решения, может, и сгодится
Я попробовал на двух файлах в папке и почему-то копируются в csv только дважды данные из первого файла.

JohnSUN

Без образцов данных и тщательной отладки - нет, не взлетит... Я-то гонял его на тестовых данных, похожих друг на друга как две капли воды. Поэтому мог и не заметить, что внутри какого-то цикла при чтении массива записана, например, константа 0, а не переменная цикла... Говорю же - сырое ещё, даже на бета-версию не тянет...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

celler

JohnSUN, всё работает как надо уже на 99 процентов. Единственно, что вместо следующего файла вновь берётся первый. Я вот заметил, что после завершения макроса, рядом с первым файлом остаётся файлик с # на конце, что свидетельствует, что он небыл корректно закрыт. Может быть в этом всё дело?

JohnSUN

Скорее всего именно здесь собака и порылась... Там в районе 91-ой строки посмотри... Идея какая была: сначала открыть первый попавшийся файл из списка и из третьих строк каждого листа выкусить строки заголовков для каждого из CSV-файла... А потом запустить цикл по всем книгам из списка и эти строки заголовков игнорировать. Ну, типа, они у нас уже есть...
Так вот, в этом "большом" цикле я файлы закрываю через oDoc.Close(), а первый файл остался с DisposeDocument(oDoc)... Попробуй заменить на oDoc.Close(True)
Но если честно, то
Цитата: celler от 11 марта 2015, 23:30
вместо следующего файла вновь берётся первый
до конца не понимаю...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

rami

Цитата: JohnSUN от 11 марта 2015, 21:49Скорее всего именно здесь собака и порылась... Там в районе 91-ой строки посмотри...
Собака порылась не здесь, а в папке. У меня в этой папке первым номером идёт скрытый файл .DS_Store , который "дразнит собаку" см. снимки. Хотя в других папках он может быть в любой позиции. Вообще нужно сделать проверку очередного файла на "документообразность". Я сделал по-быстрому обработку цикла не с 0 , а с 1 и всё заработало, но это не надёжно.

celler

Цитата: rami от 12 марта 2015, 00:08Я сделал по-быстрому обработку цикла не с 0 , а с 1 и всё заработало, но это не надёжно.
Rami, у меня в папке скрытых файлов нет. А у Вас действительно правильно заработало? Вы можете проверить на приложенных файлах? В результирующих файлах должны получиться продолжающиеся последовательности записей.

rami

Ваш зип открылся без скрытого файла, но потом он "нарисовался", может быть для вашей файловой системы это не актуально, но стоит об этом знать.
Дублирование первого документа происходит от того, что в строке 101 отсутствует код: oSheets=oDoc.Sheets()