Excel макрос для сбора в одну книгу

Обработка данных из файлов Excel - отображение информации на индикаторе состояния

Этот макрос предназначен для сбора (загрузки) информации из файлов Excel, расположенных в одной папке.

Для работы этого макроса, помимо него самого, вам понадобится добавить в свой файл:

  1. функцию FilenamesCollection для получения списка файлов в папке
  2. функцию GetFolder для вывода диалогового окна выбора папки с запоминанием выбранной папки
  3. прогресс-бар для отображения процесса обработки файлов (модуль класса и форму)

Если при тестировании макроса у вас возникает ошибка, что не найдена та или иная функция,
— проверьте, все ли необходимые компоненты (которые перечислены выше) вы добавили в свой файл.

Этот макрос я публикую прежде всего для себя (поскольку использую этот код чуть ли ни в каждой третьей своей программе),
поэтому я не буду помогать вам в настройке этого макроса, если у вас он вдруг не заработает.

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

После того, как очередной файл обработан, он перемещается во вторую папку («архив»).

Код макроса:

Sub ИмпортДанныхИзЗаявок()
    On Error Resume Next: Err.Clear
    ' запрашиваем пути к папкам с файлами
    InvoiceFolder$ = GetFolder(1, , "Выберите папку с файлами заявок (из Outlook)")
    If InvoiceFolder$ = "" Then MsgBox "Не задана папка с заявками", vbCritical, "Обработка заявок невозможна": Exit Sub
 
    ArchieveFolder$ = GetFolder(2, , "Выберите папку, куда будут помещаться обработанные файлы заявок")
    If ArchieveFolder$ = "" Then MsgBox "Не задана папка для архива заявок", vbCritical, "Обработка заявок невозможна": Exit Sub
 
    Dim coll As Collection
    ' загружаем список файлов по маске имени файла
    Set coll = FilenamesCollection(InvoiceFolder$, "Заявка №*от*.xls*", 1)
 
    If coll.Count = 0 Then
        MsgBox "Не найдено ни одной заявки для обработки в папке" & vbNewLine & InvoiceFolder$, _
               vbExclamation, "Нет необработанных заявок"
        Exit Sub
    End If
 
    Dim pi As New ProgressIndicator: pi.Show "Обработка заявок", , 2
    pi.StartNewAction , , , , , coll.Count    ' отображаем прогресс-бар

    Dim WB As Workbook, sh As Worksheet, ra As Range
    Application.ScreenUpdating = False  ' отключаем обновление экрана (чтобы процесс открытия файлов не был виден)

    ' перебираем все найденные в папке файлы
    For Each Filename In coll
 
        ' обновляем информацию на прогресс-баре
        pi.SubAction "Обрабатывается заявка $index из $count", "Файл заявки: " & Dir(Filename), "$time"
        pi.Log "Файл: " & Dir(Filename)
 
        ' открываем очередной файл в режиме «только чтение»
        Set WB = Nothing: Set WB = Workbooks.Open(Filename, False, True)
 
        If WB Is Nothing Then    ' не удалось открыть файл
            pi.Log vbTab & "ОШИБКА при загрузке файла. Файл не обработан."
 
        Else    ' файл успешно открыт
            Set sh = WB.Worksheets(1)    ' будем брать данные с первого листа
            ' берем диапазон ячеек с ячейки B1 до последней заполненной в столбце B
            Set ra = sh.Range(sh.Range("b1"), sh.Range("b" & sh.Rows.Count).End(xlUp))
 
            ' ==== переносим данные в наш файл (shb - кодовое имя листа, куда помещаем данные)
            shb.Range("a" & shb.Rows.Count).End(xlUp).Offset(1).Resize(, ra.Rows.Count).Value = _
            Application.WorksheetFunction.Transpose(ra.Value)
            ' ==== конец обработки данных из очередного файла

            WB.Close False: DoEvents    ' закрываем обработанный файл без сохранения изменений
            pi.Log vbTab & "Файл успешно обработан."
 
            ' перемещаем обработанный файл из папки InvoiceFolder$ в папку ArchieveFolder$
            Name Filename As ArchieveFolder$ & Dir(Filename, vbNormal)
 
        End If
    Next
 
    ' закрываем прогресс-бар, включаем обновление экрана
    pi.Hide: DoEvents: Application.ScreenUpdating = True
    MsgBox "Обработка заявок завершена", vbInformation
End Sub

Во вложении — файл со всеми необходимыми макросами для сбора данных из других файлов Excel

0 / 0 / 0

Регистрация: 17.12.2015

Сообщений: 3

1

Собрать данные из разных книг в одну

17.12.2015, 11:33. Показов 22890. Ответов 18


Студворк — интернет-сервис помощи студентам

Добрый день.
Прошу помощи в написании макроса, который собирал бы данные из нескольких книг в одну.
таблицы во всех книгах одинаковые: шапка таблицы на 6 строке, ниже построчно идут данные, в каждой таблице может быть разное количество строк. в таблицах одинаковое количество столбцов. По сути макрос должен создать итоговою таблицу, где все строки одна под одной склеятся в одну таблицу (базу данных). строка считается заполненной, если по ней хотя бы в одном столбце содержатся данные. соответственно пустые строки не собираются.

Результирующая таблица имеет такой же вид , как и рабоче книги.

Для примера прикрепляю 2 книги, в которых находятся таблицы.



0



0 / 0 / 0

Регистрация: 17.12.2015

Сообщений: 3

17.12.2015, 12:33

 [ТС]

2

В том-то и дело, что хотелось бы просить , чтобы мне показали наиболее подходящий вариант. я уже штук 5 перепробовал, ничего не получается.



0



5590 / 1580 / 406

Регистрация: 23.12.2010

Сообщений: 2,366

Записей в блоге: 1

17.12.2015, 16:46

3

Подходящий вариант.



1



5590 / 1580 / 406

Регистрация: 23.12.2010

Сообщений: 2,366

Записей в блоге: 1

17.12.2015, 16:55

4

Лучше проверку данных не копировать.



0



0 / 0 / 0

Регистрация: 17.12.2015

Сообщений: 3

17.12.2015, 18:14

 [ТС]

5

Благодарю, будем пробовать).

Добавлено через 48 минут
Работает замечательно! Огромное спасибо. Единственный вопрос, в какой строке предусматривается возможность прописать имя листа отличное от «Форма». Или задам вопрос по другому: как добавить еще один вариант с именем листа, откуда собираются данные?



0



KoGG

5590 / 1580 / 406

Регистрация: 23.12.2010

Сообщений: 2,366

Записей в блоге: 1

18.12.2015, 09:30

6

Здесь можно добавлять имена листов сбора сразу в массив ImenaListovSbora через «,»

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Option Compare Text
 
Sub Собрать_данные()
    ' Макрос собирает данные на активном листе активной книги из всех листов "Форма" xls файлов заданной директории,
    Dim ImenaListovSbora: ImenaListovSbora = Array("Форма", "Реестр")
    Const FirstRow_Cel& = 7          ' Номер строки начала построения
    Const FirstRow& = 7              ' Номер строки начала сбора данных (ниже шапки)
    Dim i&, LastRow&, LastRow_Cel&
    Dim ShCel As Worksheet, Sh As Worksheet, wb_Tek As Workbook
    Dim MyPath$, MyFileName$, MyFullName$
    Set ShCel = ActiveSheet
    LastRow_Cel = FirstRow_Cel
    With ShCel
        i = .UsedRange.Rows.Count + .UsedRange.Row - 1
        If i < FirstRow_Cel Then i = FirstRow_Cel
        .Rows(FirstRow_Cel & ":" & i).ClearContents
    End With
    MyPath = Trim$(ShCel.[C1])
    If Right$(MyPath, 1) <> "" Then MyPath = MyPath & ""
    MyFileName = Dir(MyPath & "*.xls*")
    Do Until MyFileName = ""
        MyFullName = MyPath & MyFileName
        Set wb_Tek = Workbooks.Open(Filename:=MyFullName, UpdateLinks:=0, ReadOnly:=True)
        For Each Sh In wb_Tek.Worksheets
            For i = 0 To UBound(ImenaListovSbora)
                If Sh.Name = ImenaListovSbora(i) Then
                    With Sh
                        LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
                        .Range(.Cells(FirstRow, 1), .Cells(LastRow, 8)).Copy
                        ShCel.Cells(LastRow_Cel, 1).PasteSpecial Paste:=xlPasteFormulas, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
                        LastRow_Cel = LastRow_Cel + LastRow - FirstRow + 1
                    End With
                End If
            Next
        Next Sh
        wb_Tek.Close SaveChanges:=False
        MyFileName = Dir
    Loop
    With ShCel
        .Range(.Cells(LastRow_Cel - 1, 1), .Cells(LastRow_Cel - 1, 8)).Copy
        .Cells(LastRow_Cel, 1).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
                SkipBlanks:=False, Transpose:=False
        .Cells(LastRow_Cel, 2).Select
    End With
End Sub



0



0 / 0 / 1

Регистрация: 16.03.2019

Сообщений: 50

23.03.2019, 21:52

7

Здравствуйте! Наткнулась на Ваш код — очень поможет в работе, спасибо!
Несколько вопросов:
1. как можно подправить код, чтобы вместо того чтобы в файле в строке писать путь, выдавало окно поиска папки?
2. как отключить мерцание экрана при поиске/проверке файлов? (когда файлов много — немного напрягает глаза)
3. как избежать появления окна примерно такого содержания «в буфере обмена много данных. сохранить их…?» если файлов много — замучаешься отвечать

Добавлено через 6 минут
KoGG, прошу прощения, сразу не поняла, как вставить ссылку на ник.



0



Schumacher57

12 / 11 / 3

Регистрация: 07.09.2015

Сообщений: 256

24.03.2019, 13:03

8

Лучший ответ Сообщение было отмечено Остап Бонд как решение

Решение

rinolga,
Ответ на 2ой вопрос:
Перед началом выполненения кода добавьте:

Visual Basic
1
Application.Screenupdating = false

Ответ на 3ий вопрос:
Так же, перед началом выполнения кода, поставте:

Visual Basic
1
Application.DisplayAlerts = false

Рекомендую в конце кода вернуть значения в положения true. Могут возникнуть неприятности, наподобие: закроете книгу отредактированную, она не сохранится и не задаст вопрос о сохранении по причине решения третьего вопроса.



1



rinolga

0 / 0 / 1

Регистрация: 16.03.2019

Сообщений: 50

24.03.2019, 15:06

9

Лучший ответ Сообщение было отмечено Остап Бонд как решение

Решение

Schumacher57, спасибо, помогло!
а 1й вопрос помогли решить так:

Visual Basic
1
2
3
4
5
6
With Application.FileDialog(msoFileDialogFolderPicker)
        .ButtonName = "Выбрать папку с отчётами"
        .Title = "Папка"
        If .Show <> -1 Then Exit Sub
        MyPath = .SelectedItems.Item(1) & ""
    End With



0



12 / 11 / 3

Регистрация: 07.09.2015

Сообщений: 256

24.03.2019, 16:06

10

Лучший ответ Сообщение было отмечено Остап Бонд как решение

Решение

rinolga, Не за что
Да, это действующий вариант. Есть так же возможность, делать отображение только интересующих файлов, т.е. во время просмотра директории будут отображаться только текстовые файлы или файлы Word.
Не знаю, противоречит ли моё предложение правилам форума. В общем, могу оказать помощь пишите в ЛС или на почту (указана в профиле), подскажу, если смогу или будет время. Абсолютно бесплатно, сам изучаю VBA, будет интересно порешать похожие вопросы.
Не стесняйтесь.



0



0 / 0 / 1

Регистрация: 16.03.2019

Сообщений: 50

24.03.2019, 22:08

11

Цитата
Сообщение от Schumacher57
Посмотреть сообщение

время просмотра директории будут отображаться только текстовые файлы или файлы Word.

текстовые мне в данном случае не нужны нужны только экселевские. Насколько я смогла понять из кода, макрос обрабатывает файлы с маской *.xls*, как раз то что надо



0



0 / 0 / 0

Регистрация: 02.02.2020

Сообщений: 1

05.02.2020, 21:45

12

Добрый день, воспользовалась данным макросом, правда у меня столбцов и строк в таблицах намного больше, данные переносит. И вроде бы все ничего, но он переносит заливку ячеек темно серую и между данными книг оставляет по тысячи пустых строк, почему это может быть?



0



12 / 11 / 3

Регистрация: 07.09.2015

Сообщений: 256

20.08.2020, 11:52

13

Лена122,
Это, честно говоря, очень и очень общий вопрос. Правда, со стороны (кто чуть-чуть понимает в VBA), звучит примерно так:
«Я села за машину той же марки, а она не едет, в чём может быть проблема?»
Вот особенно по этой строчке:

Цитата
Сообщение от Лена122
Посмотреть сообщение

правда у меня столбцов и строк в таблицах намного больше

Тут надо всё индивидуально смотреть (изменения в один символ в програмном коде, влечёт (хоть и работающий код) за собой с сотню всяких изменений.
По заливке, Cells.ClearFormat — может помочь…



0



passedbyz

Заблокирован

20.08.2020, 16:09

14

Мдя За полгода Лена решила уже свою проблему наверно?



0



12 / 11 / 3

Регистрация: 07.09.2015

Сообщений: 256

20.08.2020, 16:25

15

passedbyz сам не знаю, что на меня нашло)



1



0 / 0 / 0

Регистрация: 21.10.2020

Сообщений: 3

21.10.2020, 11:41

16

Доброго времени суток! Помогите, пожалуйста, с такой задачей. Необходимо собрать данные из разных книг (база с данными олимпиад), с одними и теми же столбцами, но разным количеством строк. Есть еще затруднение в том, что в книге несколько листов (много предметов). Возможен ли такой сбор информации? Буду рада, если сможете помочь! Для наглядности прикрепляю исходную таблицу



0



2628 / 1634 / 744

Регистрация: 23.03.2015

Сообщений: 5,135

21.10.2020, 12:45

17

AnastasiyaAR,
Прикрепите пару книг …



0



0 / 0 / 0

Регистрация: 21.10.2020

Сообщений: 3

21.10.2020, 15:22

18

Здравствуйте! Вот для примера 2 школы, три предмета. Объединить надо по предметам в один лист. Например, Химия и там обе школы. Благодарю!



0



0 / 0 / 0

Регистрация: 21.10.2020

Сообщений: 3

21.10.2020, 15:27

19

Здравствуйте! Вот для примера прикрепляю архив — 2 школы, три предмета. Объединить надо по предметам в один лист. Например, Химия и там обе школы. Благодарю!



0



Макрос для сбора данных из нескольких книг в одну

EL85

Дата: Четверг, 26.12.2019, 10:21 |
Сообщение № 1

Группа: Пользователи

Ранг: Новичок

Сообщений: 13


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

Добрый день! Появилась необходимость работать с данными посредствам VBA. Если Иксель в какой-то мере стал понятным и местами даже родным, то написание кода – пока нет.
Есть задача, которая требует ежемесячного обновления одного файла данными из пяти других.
Спешу заверить, что форумы я читал, статьи читал, код посложнее чем Hello world осилил, НО сложность и оперативность вышеозначенной задачки вынуждает меня просить о помощи…
Поэтому, я обращаюсь, чтобы получить готовый макрос и уже на его основе изучить как это и что это…
Итак, есть 2 типа иксель файлов:
База данных (БД), это файл, в который должны попадать данные из следующего типа файлов. Макрос должен запускаться из БД.
5 иксель файлов, это источники данных для БД, назовем их Источник 1, Источник 2, … или совокупно – Источники.
МЕХАНИКА СБОРА ДАННЫХ:
Каждый месяц я открываю БД и запускаю макрос. Перед этим, я помещаю 5 файлов Источников в определенную папку.
ВАЖНЫЕ ОБСТОЯТЕЛЬСТВА ПРОЦЕССА:
1) БД и Источники находятся в определенных папках, перемещение не планируется.
2) Источники – это всегда 5 иксель файлов.
3) Источники каждый месяц помещаются в папку, отдают данные для БД, удаляются и в следующем месяце их место занимаются новые 5 файлов.
4) Каждый из 5 файлов Источников имеет одинаковую структуру, т.е. в каждом Источнике есть 5 листов, содержат обычные таблицы с заголовками и разными форматами значений: текст, число, процент. Листы в каждом Источнике названы одинаково. Столбцы названы одинаково. Объем данных в целом идентичен, кроме как на листе SKU data flat кол-во строк может варьироваться от примерно 150 до 400+.
5) БД тоже содержит 5 листов, название которых нарочно совпадает с таковыми в любом из Источников.
6) На каждый лист БД данные из Источников должны попадать в каждую последующую свободную строку, чтобы не затирать данные, которые там уже будут на тот момент.

ПРИМЕР:
В январе 2020 г., в Data Base на лист SKU data flat, должны попасть данные с листа SKU data flat из источника PREE_Operations report_PRU, PREE_Operations report_PRK и других 3х источников.
На лист Log data flat должны попасть данные с листа Log data flat из источника PREE_Operations report_PRU, PREE_Operations report_PRK и других 3х источников.
И так далее по всем 5 листам. Заполнение линейное, то есть сперва 1й лист Data Base

Набор корректных имен для кода:
Файл БД = Data Base,
Имена Источников:
PREE_Operations report_PRU
PREE_Operations report_PRK
PREE_Operations report_PRR
PREE_Operations report_PRA
PREE_Operations report_PRM
Имена 5 листов в БД и Источниках: SKU data flat, Log data flat, Invent data flat, Stock evo flat, Cost flat
Я заранее благодарю того, кто возьмется за задачу! Попытки написать код я сознательно не выкладываю, потому что там бред. Прилагаю лишь файл Data Base и пример одного из 5 источников (рыжие листы).
Если правила предполагают вознаграждение – прошу скоординировать по дальнейшим действиям.
Спасибо.

 

Ответить

китин

Дата: Четверг, 26.12.2019, 10:38 |
Сообщение № 2

Группа: Модераторы

Ранг: Экселист

Сообщений: 6973


Репутация:

1063

±

Замечаний:
0% ±


Excel 2007;2010;2016

Если правила предполагают вознаграждение

перенести тему в раздел Работа/Фриланс?


Не судите очень строго:я пытаюсь научиться
ЯД 41001877306852

 

Ответить

EL85

Дата: Четверг, 26.12.2019, 10:45 |
Сообщение № 3

Группа: Пользователи

Ранг: Новичок

Сообщений: 13


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

китин, доброе утро, не понятен вопрос, не могли бы пожалуйста перефразировать и без пропуска букв? Спасибо.

Сообщение отредактировал EL85Четверг, 26.12.2019, 10:46

 

Ответить

RAN

Дата: Четверг, 26.12.2019, 12:14 |
Сообщение № 4

Группа: Друзья

Ранг: Экселист

Сообщений: 5645

я обращаюсь, чтобы получить готовый макрос и уже на его основе изучить как это и что это…

Получите


Быть или не быть, вот в чем загвоздка!

Сообщение отредактировал RANЧетверг, 26.12.2019, 12:15

 

Ответить

Michael_S

Дата: Четверг, 26.12.2019, 12:17 |
Сообщение № 5

Группа: Друзья

Ранг: Старожил

Сообщений: 2012


Репутация:

373

±

Замечаний:
0% ±


Excel2016

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

Если правила предполагают вознаграждение – прошу скоординировать по дальнейшим действиям.

Вознаграждение предполагают не правила, а объём поставленной задачи. В этом случае тему нужно располагать в разделе Работа / Фриланс
[p.s.]Если ни с кем еще не договаривались — пишите мне в личку.[/p.s.]

 

Ответить

EL85

Дата: Четверг, 26.12.2019, 13:44 |
Сообщение № 6

Группа: Пользователи

Ранг: Новичок

Сообщений: 13


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

RAN, Добрый день и спасибо заранее! К сожалению рабочий комп наглухо блокирует ссылку, попробую посмотреть ее дома.

 

Ответить

EL85

Дата: Четверг, 26.12.2019, 13:46 |
Сообщение № 7

Группа: Пользователи

Ранг: Новичок

Сообщений: 13


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

Michael_S, теперь понял, спасибо. RAN прислал сообщение чуть ранее вашего и вероятно с решением, посмотрю что там и тогда уже соориентируюсь.

 

Ответить

EL85

Дата: Четверг, 26.12.2019, 17:14 |
Сообщение № 8

Группа: Пользователи

Ранг: Новичок

Сообщений: 13


Репутация:

0

±

Замечаний:
0% ±


Excel 2016

RAN, спасибо за ссылку, видел ее, когда искал решение в инете, но для меня это космос пока….

 

Ответить

cdj100

Дата: Четверг, 26.12.2019, 22:43 |
Сообщение № 9

Группа: Пользователи

Ранг: Прохожий

Сообщений: 3


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Добрый день, нужна помощь в доработке макроса ниже:
В исходном варианте он копирует лист 1 из указанного набора книг в текущую книгу.
Хотелось бы, чтобы он копировал указанный диапазон (А1:A13) со всех листов 1 (также из всех выбранных книг) но начиная с выделенной мной ячейки текущей книги, в столбец слева направо. (например столбец А,B)
А при появлении новых книг, новые данные добавлял бы данные, начиная со столба С. И т.д.

Подскажите как корректно изменить код?

Sub CombineWorkbooks()
Dim FilesToOpen
Dim x As Integer

Application.ScreenUpdating = False ‘отключаем обновление экрана для скорости

‘вызываем диалог выбора файлов для импорта
FilesToOpen = Application.GetOpenFilename _
(FileFilter:=»All files (*.*), *.*», _
MultiSelect:=True, Title:=»Files to Merge»)

If TypeName(FilesToOpen) = «Boolean» Then
MsgBox «Не выбрано ни одного файла!»
Exit Sub
End If

‘проходим по всем выбранным файлам
x = 1
While x <= UBound(FilesToOpen)
Set importWB = Workbooks.Open(Filename:=FilesToOpen(x))
Sheets(1).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
importWB.Close savechanges:=False
x = x + 1
Wend

Application.ScreenUpdating = True
End Sub

Сообщение отредактировал cdj100Четверг, 26.12.2019, 22:45

 

Ответить

Pelena

Дата: Четверг, 26.12.2019, 22:49 |
Сообщение № 10

Группа: Админы

Ранг: Местный житель

Сообщений: 18797


Репутация:

4284

±

Замечаний:
±


Excel 2016 & Mac Excel

cdj100, Прочитайте Правила форума, создайте свою тему, оформите код тегами с помощью кнопки #
Правилами запрещено задавать новые вопросы в чужих темах


«Черт возьми, Холмс! Но как??!!»
Ю-money 41001765434816

 

Ответить

Хитрости »

1 Май 2011              765432 просмотров


Как собрать данные с нескольких листов или книг?

Очень часто бывает необходимо собрать данные с нескольких листов одной книги или даже с листов нескольких книг. Например, каждую неделю мы получаем некие отчеты от отделов, которые необходимо собрать в одну общую таблицу для построения сводной таблицы. Или это могут быть некие книги прайсов по товарам от разных поставщиком, который опять же надо сначала объединить, а потом уже анализировать. Вручную делать это довольно муторно. И то, муторно это только для первых 20-ти листов/файлов, потом становится просто тошно. Поэтому решил поделиться решением, которое поможет собрать данные со всех листов книги, со всех листов всех указанных книг или только с указанных листов:

'---------------------------------------------------------------------------------------
' Author : Щербаков Дмитрий(The_Prist)
'          Профессиональная разработка приложений для MS Office любой сложности
'          Проведение тренингов по MS Excel
'          https://www.excel-vba.ru
'          info@excel-vba.ru
'          WebMoney - R298726502453; Яндекс.Деньги - 41001332272872
' Purpose: http://www.excel-vba.ru/chto-umeet-excel/kak-sobrat-dannye-s-neskolkix-listov-ili-knig/
'             Процедура сбора данных с нескольки листов/книг
'---------------------------------------------------------------------------------------
Option Explicit
 
Sub Consolidated_Range_of_Books_and_Sheets()
    Dim iBeginRange As Range, rCopy As Range, lCalc As Long, lCol As Long
    Dim oAwb As String, sCopyAddress As String, sSheetName As String
    Dim lLastrow As Long, lLastRowMyBook As Long, li As Long, iLastColumn As Integer
    Dim wsSh As Worksheet, wsDataSheet As Worksheet, bPolyBooks As Boolean, avFiles
    Dim wbAct As Workbook
    Dim bPasteValues As Boolean, IsPasteSheetName As Boolean
 
    On Error Resume Next
    'Выбираем диапазон выборки с книг
    Set iBeginRange = Application.InputBox("Выберите диапазон сбора данных." & vbCrLf & _
                                           "1. При выборе только одной ячейки данные будут собраны со всех листов начиная с этой ячейки. " & _
                                           vbCrLf & "2. При выделении нескольких ячеек данные будут собраны только с указанного диапазона всех листов.", Type:=8)
    'для указания диапазона без диалогового окна:
    'Set iBeginRange = Range("A1:A10") 'диапазон указывается нужный
    'Если диапазон не выбран - завершаем процедуру
    If iBeginRange Is Nothing Then
        Exit Sub
    End If
    'Указываем имя листа
    'Допустимо указывать в имени листа символы подставки ? и *.
    'Если указать только * то данные будут собираться со всех листов
    sSheetName = InputBox("Введите имя листа, с которого собирать данные(если не указан, то данные собираются со всех листов)", "Параметр")
    'Если имя листа не указано - данные будут собраны со вех листов
    If sSheetName = "" Then
        sSheetName = "*"
    End If
    'добавлять ли имя листа в начало таблицы
    IsPasteSheetName = (MsgBox("Вставлять имя листа первым столбцом?", vbQuestion + vbYesNo, "www.wxcel-vba.ru") = vbYes)
    On Error GoTo 0
    'Запрос - вставлять на результирующий лист все данные
    'или только значения ячеек (без формул и форматов)
    bPasteValues = (MsgBox("Вставлять только значения?", vbQuestion + vbYesNo, "www.wxcel-vba.ru") = vbYes)
    'Запрос сбора данных с книг(если Нет - то сбор идет с активной книги)
    If MsgBox("Собрать данные с нескольких книг?", vbInformation + vbYesNo, "www.wxcel-vba.ru") = vbYes Then
        avFiles = Application.GetOpenFilename("Excel files(*.xls*),*.xls*", , "Выбор файлов", , True)
        If VarType(avFiles) = vbBoolean Then Exit Sub
        bPolyBooks = True
        lCol = 1
    Else
        avFiles = Array(ThisWorkbook.FullName)
    End If
    If IsPasteSheetName Then
        lCol = lCol + 1
    End If
    'отключаем обновление экрана, автопересчет формул и отслеживание событий
    'для скорости выполнения кода и для избежания ошибок, если в книгах есть иные коды
    With Application
        lCalc = .Calculation
        .ScreenUpdating = False
        .EnableEvents = False
        .Calculation = xlManual
    End With
    'создаем новый лист в книге для сбора
    Set wsDataSheet = ActiveWorkbook.Sheets.Add(After:=Sheets(Sheets.Count))
    'если нужно сделать сбор данных на новый лист книги с кодом
    'Set wsDataSheet = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
    'цикл по книгам
    For li = LBound(avFiles) To UBound(avFiles)
        If bPolyBooks Then
            Set wbAct = Workbooks.Open(Filename:=avFiles(li))
        Else
            Set wbAct = ThisWorkbook
        End If
        oAwb = wbAct.Name
        'цикл по листам
        For Each wsSh In wbAct.Sheets
            If wsSh.Name Like sSheetName Then
                'Если имя листа совпадает с именем листа, в который собираем данные
                'и сбор идет только с активной книги - то переходим к следующему листу
                If wsSh.Name = wsDataSheet.Name And bPolyBooks = False Then GoTo NEXT_
                With wsSh
                    Select Case iBeginRange.Count
                    Case 1 'собираем данные начиная с указанной ячейки и до конца данных
                        lLastrow = .Cells(1, 1).SpecialCells(xlLastCell).Row
                        iLastColumn = .Cells.SpecialCells(xlLastCell).Column
                        sCopyAddress = .Range(.Cells(iBeginRange.Row, iBeginRange.Column), .Cells(lLastrow, iLastColumn)).Address
                    Case Else 'собираем данные с фиксированного диапазона
                        sCopyAddress = iBeginRange.Address
                    End Select
                    lLastRowMyBook = wsDataSheet.Cells.SpecialCells(xlLastCell).Row + 1
                    'определяем для копирования диапазон только заполненных данных на листе
                    Set rCopy = Intersect(.Range(sCopyAddress).Parent.UsedRange, .Range(sCopyAddress))
                    'вставляем имя книги, с которой собраны данные
                    If lCol > 0 Then
                        If bPolyBooks Then
                            wsDataSheet.Cells(lLastRowMyBook, 1).Resize(rCopy.Rows.Count).Value = oAwb
                        End If
                        If IsPasteSheetName Then
                            wsDataSheet.Cells(lLastRowMyBook, lCol).Resize(rCopy.Rows.Count).Value = .Name
                        End If
                    End If
                    'если вставляем только значения
                    If bPasteValues Then
                        rCopy.Copy
                        wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol).PasteSpecial xlPasteValues
                        wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol).PasteSpecial xlPasteFormats
                    Else 'если вставляем все данные ячеек(формулы, форматы и т.д.)
                        rCopy.Copy wsDataSheet.Cells(lLastRowMyBook, 1).Offset(, lCol)
                    End If
                End With
            End If
NEXT_:
        Next wsSh
        If bPolyBooks Then
            wbAct.Close False
        End If
    Next li
    With Application
        .ScreenUpdating = True
        .EnableEvents = True
        .Calculation = lCalc
    End With
End Sub

Приведенный выше код необходимо вставить в стандартный модуль(Что такое модуль? Какие бывают модули?). Выполнить его можно будет из этой книги нажатием клавиш Alt+F8. В появившемся окне выбрать Consolidated_Range_of_Books_and_Sheets и нажать Выполнить. Так же можно создать на листе кнопку и назначить ей данный макрос. Так же, если впервые работаете с макросами настоятельно рекомендую прочитать статью: Что такое макрос и где его искать?, а так же Почему не работает макрос?

После вызова макроса поочередно будут появляется запросы, в которых надо будет указать исходные параметры:

  • Диапазон сбора данных — Если в окне выбора диапазона выбрать только одну ячейку, то данные будут собраны со всех листов книги/книг, начиная с этой ячейки и до последней ячейки листа.
    Если выбрать несколько ячеек, данные будут собраны только с указанного диапазона всех листов книги/книг. Допускается указать несвязанный(рваный) диапазон(например, только три столбца: A:A,D:D,F:F). Сделать это можно, выделив нужный диапазон с зажатой клавишей Ctrl. Здесь необходимо учитывать, что Excel позволяет одним махом скопировать не любые рваные диапазоны, а только диапазоны одного размера и только если они начинаются с одной строки. Например, если выделить диапазоны A1:B20, F1:H20 — они будут скопированы без проблем. Но если попробовать указать диапазоны со сдвигом: A1:B20, F2:H21 — Excel выдаст ошибку.
  • Имя листа — Необязателен для указания. Если не указан — данные будут собраны со всех листов. Указать можно как точное соответствие имени листа, так и с частичным соответствием. Например, если в книгах для сбора данных необходимо собрать данные только с листа «Январь», то следует так и указать — «Январь». Если требуется собрать данные только с листов, начинающихся с «Продажи»(«Продажи ЮГ», «Продажи НН», «Продажи Запад» и т.д.), то следует применить символ подстановки звездочку — «Продажи*». Если надо собрать с листов, содержащих в имени «продажи»(«Итоговые продажи ЮГ», «Продажи НН», «Сезонные продажи» и т.д.), то указываем «*продажи*». Если надо собрать только с листа «Сезонные продажи», но известно, что вместо пробела может быть нижнее подчеркивание или тире(«Сезонные продажи», «Сезонные_продажи», «Сезонные-продажи») или иной символ, то можно также применить звездочку — «Сезонные*продажи». Но если среди листов могут встречаться и такие как «Сезонные разовые продажи», «Сезонные корпоративные продажи» и т.п., но информацию с них собирать не надо, то можно применить вопросительный знак — «Сезонные?продажи». Вопросительный знак заменяет любой один символ, звездочка — любое количество любых символов.
  • Вставлять имя листа первым столбцом? — если выбрать Да, перед данными в итоговой таблице будут записаны имена листов, с которых были собраны данные. Если будет указано собирать данные с нескольких книг — то имя листа будет во втором столбце, если с листов одной книги — то имя листа будет первым столбцом.
  • Вставлять только значения? — если выбрать Да, то в результирующий лист с листов будут вставлены исключительно значения ячеек (без формул), но при этом сохранятся их форматы(формат чисел, цвет заливки, цвет шрифта, границы и т.п.). Может пригодится, если на листах для сбора записаны формулы, ссылающиеся на другие листы, книги, диапазоны. При обычном копировании может случиться так, что формула выдаст ошибку, т.к. в книге для вставки нет таких листов и диапазонов или данные расположены иначе. Если выбрать Нет, то все ячейки с листов на результирующий будут копироваться в точности как в исходных листах.
  • И последний запрос: Собрать данные с нескольких книг? — если выбрать Да, то появится диалоговое окно выбора файлов. Надо указать все файлы, данные с которых необходимо собрать. Если выбрать Нет, то данные будут собираться с листов только активной книги. При этом, если выбран вариант сбора с нескольких книг, то первым столбцом в итоговой таблице будут записаны имена файлов, с которых были собраны данные

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

Если после сбора данных обнаружили, что после каждого файла/листа много пустых строк, то следует найти в коде строку:

lLastrow = .Cells(1, 1).SpecialCells(xlLastCell).Row

и заменить её на строку примерно следующего содержания:

lLastrow = .Cells(.Rows.Count, 1).End(xlUp).Row

где 1 — это номер столбца на листах данных, в котором искать последнюю заполненную ячейку.
Актуально это для файлов с одинаковой структурой. Например, если сбор идет с листов по продажам, то вполне может быть такое, что в столбце 1 может не быть данных. Поэтому следует определить номер столбца, в котором наполнение данных максимально. Например, это может быть столбец с наименованиями товара или с суммами. Если это столбец D, то следует строку записать так:

lLastrow = .Cells(.Rows.Count, 4).End(xlUp).Row 'ищем последнюю строку в 4-м столбце

Подробнее про определение последней строки можно прочитать в статье: Как определить последнюю ячейку на листе через VBA?

Важное замечание: Если вы используете Excel 2007 и выше и файлы для сбора данных тоже в этом формате, то следует скачанный файл сначала сохранить в формат «Книга Excel с поддержкой макросов(.xlsm)», закрыть и открыть заново. Иначе есть шанс получить ошибку при сборе данных, т.к. Excel будет в режиме совместимости и не сможет поместить на результирующий лист более 65536 строк.

Скачать пример:

  Сбор данных с листов и книг.xls (73,0 KiB, 37 087 скачиваний)

Также см.:
Сбор данных с нескольких листов/книг
Как объединить несколько текстовых файлов в один?
Просмотреть все файлы в папке
План-фактный анализ в Excel при помощи Power Query


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

Skip to content

Как быстро объединить несколько файлов Excel

Мы рассмотрим три способа объединения файлов Excel в один: путем копирования листов, запуска макроса VBA и использования инструмента «Копировать рабочие листы» из надстройки Ultimate Suite.

Намного проще обрабатывать данные в одном файле, чем переключаться между многочисленными книгами. Однако объединение нескольких книг Excel в один файл может быть сложным и долгим процессом, особенно если книги, которые вам нужно объединить, содержат много листов. Итак, как подойти к этой проблеме? Вы будете копировать их вручную или с помощью кода VBA? Или вы используете один из специализированных инструментов для объединения файлов Excel? 

Ниже вы найдете несколько хороших способов, позволяющих реализовать объединение.

  • Самое простое — копировать вручную.
  • Объединение файлов Excel при помощи VBA.
  • Как объединить несколько файлов с помощью Ultimate Suite.

Примечание. В этой статье мы рассмотрим, как копировать листы из нескольких книг Excel в одну книгу. Если вы ищете быстрый способ скопировать данные с нескольких листов на один общий лист, вы найдете подробную инструкцию в другой статье: Как объединить несколько листов в один.

Простой метод — копировать листы руками.

Если вам нужно объединить всего пару файлов Excel, вы можете вручную скопировать или переместить листы из одного файла в другой. Вот как это можно сделать:

  1. Откройте книги, которые мы планируем объединить.
  2. Выберите листы в исходной книге, которые вы хотите скопировать в основную книгу.

Чтобы выбрать несколько листов, используйте один из следующих приемов:

  • Чтобы выбрать соседние листы, щелкните вкладку первого, который вы хотите скопировать, нажмите и удерживайте клавишу Shift, а затем щелкните вкладку последнего. Это действие выберет все листы между ними.
  • Чтобы выбрать несмежные, удерживайте клавишу Ctrl и щелкайте вкладку каждого из них по отдельности.
  • Выделив все нужные листы, щелкните правой кнопкой мыши любую из выделенных вкладок и выберите «Переместить» или «Копировать…» .

  1. В диалоговом окне «Перемещение или копирование» выполните следующие действия:
    • В раскрывающемся списке «Переместить выбранные листы в книгу» выберите целевую книгу, в которую вы хотите объединить другие файлы.
    • Укажите, где именно должны быть вставлены вкладки. В нашем случае мы выбираем вариант вставки в конец списка.
    • Установите флажок «Создать копию», если хотите, чтобы исходные данные оставались оригинальном файле.
    • Нажмите ОК, чтобы завершить операцию.

Чтобы объединить вкладки из нескольких файлов Excel, повторите описанные выше шаги для каждой книги отдельно.

Замечание. При копировании листов вручную помните о следующем ограничении, налагаемом Excel: невозможно переместить или скопировать группу листов, если какой-либо из них содержит «умную» таблицу. В этом случае вам придется либо преобразовать таблицу в диапазон, либо использовать один из других методов, не имеющих этого ограничения.

Как объединить файлы Excel с VBA

Если у вас есть несколько файлов Excel, которые необходимо объединить в один файл, более быстрым способом будет автоматизировать процесс с помощью макроса VBA.

Ниже вы найдете код VBA, который копирует все листы из всех файлов Excel, которые вы выбираете, в одну книгу. Этот макрос MergeExcelFiles написан Алексом.

Важное замечание! Макрос работает со следующим ограничением — объединяемые файлы не должны быть открыты физически или находиться в памяти, в буфере обмена. В таком случае вы получите ошибку во время выполнения.

Sub MergeExcelFiles()
    Dim fnameList, fnameCurFile As Variant
    Dim countFiles, countSheets As Integer
    Dim wksCurSheet As Worksheet
    Dim wbkCurBook, wbkSrcBook As Workbook
 
    fnameList = Application.GetOpenFilename(FileFilter:="Microsoft Excel Workbooks (*.xls;*.xlsx;*.xlsm),*.xls;*.xlsx;*.xlsm", Title:="Choose Excel files to merge", MultiSelect:=True)
 
    If (vbBoolean <> VarType(fnameList)) Then
 
        If (UBound(fnameList) > 0) Then
            countFiles = 0
            countSheets = 0
 
            Application.ScreenUpdating = False
            Application.Calculation = xlCalculationManual
 
            Set wbkCurBook = ActiveWorkbook
 
            For Each fnameCurFile In fnameList
                countFiles = countFiles + 1
 
                Set wbkSrcBook = Workbooks.Open(Filename:=fnameCurFile)
 
                For Each wksCurSheet In wbkSrcBook.Sheets
                    countSheets = countSheets + 1
                    wksCurSheet.Copy after:=wbkCurBook.Sheets(wbkCurBook.Sheets.Count)
                Next
 
                wbkSrcBook.Close SaveChanges:=False
 
            Next
 
            Application.ScreenUpdating = True
            Application.Calculation = xlCalculationAutomatic
 
            MsgBox "Processed " & countFiles & " files" & vbCrLf & "Merged " & countSheets & " worksheets", Title:="Merge Excel files"
        End If
 
    Else
        MsgBox "No files selected", Title:="Merge Excel files"
    End If
End Sub

Как добавить этот макрос в книгу

Если вы хотите вставить макрос в свою книгу, выполните следующие обычные действия:

  1. нажимать Alt + F11 , чтобы открыть редактор Visual Basic.
  2. Щелкните правой кнопкой мыши ThisWorkbook на левой панели и выберите « Вставить» > « Модуль» в контекстном меню.
  3. В появившемся окне (Окно кода) вставьте указанный выше код.

Более подробная инструкция описана в разделе Как вставить и запустить код VBA в Excel .

Кроме того, вы можете загрузить макрос в файле Excel, открыть его в этой книге (включить выполнение макросов, если будет предложено), а затем переключиться на свою собственную книгу и нажать Alt + F8 для его запуска. Если вы новичок в использовании макросов в Excel, следуйте подробным инструкциям ниже.

Как использовать макрос MergeExcelFiles

Откройте файл Excel, в котором вы хотите объединить листы из других книг, и выполните следующие действия:

  1. Нажмите комбинацию Alt + F8, чтобы открыть окно диалога.
  2. В разделе « Имя макроса» выберите MergeExcelFiles и нажмите «Выполнить».

  1. Откроется стандартное окно проводника, вы выберите одну или несколько книг, которые хотите объединить, и нажмите «Открыть» . Чтобы выбрать несколько файлов , удерживайте нажатой клавишу Ctrl, указывая на их имена.

В зависимости от того, сколько файлов вы выбрали, дайте макросу несколько секунд или минут для их обработки. После завершения всех операций он сообщит вам, сколько файлов было обработано и сколько листов было объединено:

Как объединить несколько файлов с помощью Ultimate Suite.

Если вам не очень комфортно с VBA и вы ищете более простой и быстрый способ объединить файлы Excel, обратите внимание на инструмент «Копирование листов (Copy Sheets)» — одну из более чем 60 функций, включенных в невероятно функциональную программу Ultimate Suite for Excel. Она работает в версиях Excel 2010-2019.

С Ultimate Suite объединение нескольких файлов Эксель в один так же просто, как раз-два-три (буквально, всего 3 быстрых шага). Вам даже не нужно открывать те из них, которые вы хотите объединить. И это могут быть два файла или несколько — не важно.

  1. Открыв главную книгу, перейдите на вкладку «Ablebits Data» и нажмите «Копировать листы (Copy Sheets)» > «Выбранные в одну книгу (Selected Sheets to one workbook)».

  1. В диалоговом окне выберите файлы (а в них — листы), которые вы хотите объединить, и нажмите «Далее (Next)» .

Советы:

  • Чтобы выбрать все листы в определенной книге, просто поставьте галочку в поле рядом с именем книги, и все они в этом файле будут выбраны автоматически.
  • Чтобы объединить листы из закрытых книг, нажмите кнопку «Добавить файлы…» и выберите столько книг, сколько нужно. Это добавит выбранные файлы только в окно копирования, не открывая их в Excel.
  • По умолчанию копируются все данные. Однако, в разных листах можно выбрать разные диапазоны для объединения. Чтобы скопировать только определенную область, наведите указатель мыши на имя вкладки, затем щелкните значок    и выберите нужный диапазон. 
  • При необходимости укажите один или несколько дополнительных параметров и нажмите «Копировать» . На снимке скриншоте а ниже показаны настройки по умолчанию: Вставить все (формулы и значения) и Сохранить форматирование.

Дайте мастеру копирования листов несколько секунд для обработки и наслаждайтесь результатом!

На этой странице есть подробное описание всех возможностей работы мастера копирования.

Чтобы поближе познакомиться с этим и другими инструментами для Excel, вы можете загрузить ознакомительную версию Ultimate Suite.

Итак, я надеюсь, вы получили ответ на вопрос — как быстро объединить несколько файлов Excel в один.

Понравилась статья? Поделить с друзьями:
  • Excel макрос для рисунка
  • Excel макрос для разных файлов
  • Excel макрос для примечания
  • Excel макрос для построения диаграммы
  • Excel макрос для построения графиков