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

Предположим, имеется куча книг Excel, все листы из которых надо объединить в один файл. Копировать руками долго и мучительно, поэтому имеет смысл использовать несложный макрос.

Открываем книгу, куда хотим собрать листы из других файлов, входим в редактор Visual Basic сочетанием клавиш Alt+F11 одноименной кнопкой на вкладке Разработчик (Developer - Visual Basic), добавляем новый пустой модуль (в меню Insert - Module) и копируем туда текст вот такого макроса:

 
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().Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
        importWB.Close savechanges:=False
        x = x + 1
    Wend

    Application.ScreenUpdating = True
End Sub

После этого можно вернуться в Excel и запустить созданный макрос на вкладке Разработчик кнопкой Макросы (Developer - Macros) или нажав Alt+F8. Отобразится диалоговое окно открытия файла, где необходимо указать один или несколько (удерживая Ctrl или Shift) файлов, листы из которых надо добавить к текущей книге - и задача решена!

Ссылки по теме

 


Страницы: 1  2  
Akakiy
07.10.2012 13:27:51
Очень удобная вещь.
Пока правда других способов не знаю.
Спасибо.
Silver
07.10.2012 13:29:50
Спасибо!!! Макрос - ОГОНЬ! Полезная штука!.
Евгений
07.10.2012 13:32:01
Да, согласен, макрос очень даже неплох, но из Personal работать отказывается. Прична, как мне кажется, в том что Personal некоторые команды не воспринимает, или воспринимает как то иначе... например ThisWorkbook... Я переделал макрос, теперь работает и из Personal без проблем... получилось следующее:
Sub CombineWorkbooks()
 Dim FilesToOpen
 Dim x As Integer
 Dim wbk As Workbook
 Dim wbk2 As Workbook
 On Error GoTo ErrHandler
 Set wbk = ActiveWorkbook
 Application.ScreenUpdating = False
 FilesToOpen = Application.GetOpenFilename _
 (FileFilter:="Microsoft Excel Files (*.xls), *.xls", _
 MultiSelect:=True, Title:="Files to Merge")
 If TypeName(FilesToOpen) = "Boolean" Then
 MsgBox "No files!"
 GoTo ExitHandler
 End If
 x = 1
 While x <= UBound(FilesToOpen)
 Set wbk2 = Workbooks.Open(Filename:=FilesToOpen(x))
 wbk2.Sheets().Move After:=wbk.Sheets(wbk.Sheets.Count)
 x = x + 1
 Wend
 ExitHandler:
 Application.ScreenUpdating = True
 Exit Sub
 ErrHandler:
 MsgBox err.Description
 Resume ExitHandler
 End Sub
01.06.2016 07:29:59
Разрешите обратиться!
У меня при копировании листов с книг разных версий екселя работает только Ваш макрос, однако когда я хочу скопировать только первый лист с разных книг, я указал следующий код:

wbk2.Sheets().Move After:=wbk.Sheets(wbk.Sheets.Count)
wbk2.Sheets(1).Move After:=wbk.Sheets(wbk.Sheets.Count) 
При этом макрос сработал, все первые листы были успешно скопированы, но появился побочный эффект:
открываются все книги, из которых эти листы копировались.
Вопрос: можно ли изменить код таким образом, чтобы всё работало по прежней схеме, но при этом куча книг не открывалась и я указывал номер листа какой хочу?:)
28.10.2020 20:06:14
У меня почему-то после запуска макроса появляется проводник, в котором можно выбрать только файлы xls
поменял девятую строку из макроса в оригинальном посте - файлы появились, работает
(FileFilter:="All files (*.*), *.*", _ 
Слава
07.10.2012 13:35:48
Вот рабочий макрос, собирает любое количество листов. этот макрос работает и из Personal. Пользуйтесь, люди !!!

Sub Сбор_листов_в_один_файл()
 Const strStartDir = "c:\test" 'папка, с которой начать обзор файлов
 Const strSaveDir = "c:\test\result" 'папка, в которую будет предложено сохранить результат
 Dim wbTarget As New Workbook, wbSrc As Workbook, shSrc As Worksheet, shTarget As Worksheet, arFiles, _
 i As Integer, stbar As Boolean
 On Error Resume Next 'если указанный путь не существует, обзор начнется с пути по умолчанию
 ChDir strStartDir
 On Error GoTo 0
 With Application 'меньше писанины
 arFiles = .GetOpenFilename("Excel Files (*.xls), *.xls", , "Объединить файлы", , True)
 If Not IsArray(arFiles) Then End 'если не выбрано ни одного файла
 Set wbTarget = Workbooks.Add(template:=xlWorksheet)
 .ScreenUpdating = False
 stbar = .DisplayStatusBar
 .DisplayStatusBar = True
 .DisplayAlerts = False
 For i = 1 To UBound(arFiles)
 .StatusBar = "Обработка файла " & i & " из " & UBound(arFiles)
 Set wbSrc = Workbooks.Open(arFiles(i), ReadOnly:=True)
 For Each shSrc In wbSrc.Worksheets
 If IsNull(shSrc.UsedRange.Text) Then 'лист не пустой
 Set shTarget = wbTarget.Sheets.Add(after:=wbTarget.Sheets(wbTarget.Sheets.Count))
 shTarget.Name = shSrc.Name & "-" & i
 shSrc.Cells.Copy shTarget.Range("A1")
 End If
 Next
 wbSrc.Close False 'закрыть без запроса на сохранение
 Next
 .ScreenUpdating = True
 .DisplayStatusBar = stbar
 .StatusBar = False
 If wbTarget.Sheets.Count = 1 Then 'не добавлено ни одного листа
 MsgBox "В указанных книгах нет непустых листов, сохранять нечего!"
 wbTarget.Close False
 End
 Else
 .DisplayAlerts = False
 wbTarget.Sheets(1).Delete
 .DisplayAlerts = True
 End If
 On Error Resume Next 'если указанный путь не существует и его не удается создать,
 'обзор начнется с последней использованной папки
 If Dir(strSaveDir, vbDirectory) = Empty Then MkDir strSaveDir
 ChDir strSaveDir
 On Error GoTo 0
 arFiles = .GetSaveAsFilename("Результат", "Excel Files (*.xls), *.xls", , "Сохранить объединенную книгу")
 If VarType(arFiles) = vbBoolean Then 'если не выбрано имя
 GoTo save_err
 Else
 On Error GoTo save_err
 wbTarget.SaveAs arFiles
 End If
 End
 save_err:
 MsgBox "Книга не сохранена!", vbCritical
 End With
 End Sub
09.12.2022 10:12:52
:)Спасибо! Работает!!! А разные вкладки можно объединить уже Квери!
09.12.2022 11:26:23
Работает на ура с форматом 97-2003, перевела остальные файлы в этот же формат при обработке выскочила ошибка желтым
Set shTarget = wbTarget.Sheets.Add(after:=wbTarget.Sheets(wbTarget.Sheets.Count))

Что делать?
18.01.2013 19:04:41
Отличная и полезная вещь! Спасибо! Один вопрос, что нужно добавить в код чтоб не собирал пустые листы? типа как реализовано в посте выше, не получается самому сообразить.
19.01.2013 21:01:31
Отвечу сам себе :). В принципе нужен был вообще один лист, первый, поэтому в сторочке
Sheets().Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)

заменил Sheets() на Sheets(1), теперь собирает только первый лист из файлов. Почему то при наличии скрытых и очень скрытых листов в собираемых книгах Эксель упорно вылетал с ошибкой... после замены всё ОК стало.
20.01.2017 11:46:39
Как приятно видеть в комментариях ответ на собственный вопрос, да еще так идеально работающий=)
02.03.2013 10:32:31
А можно ли собрать всё на одном листе, помещая информацию друг под другом?
03.03.2013 08:44:52
Можно, но это будет совсем другой макрос :)
06.06.2013 13:52:34
а какой другой? вот он как раз и нужен!!!
28.03.2018 19:08:43
ОГРОМНЕЙШЕЕ СПАСИБО!!!!!! неделю мне спасли в очередной раз!!!!!!!!!!!!!!!:{}
18.06.2013 10:45:50
Здравствуйте, уважаемый Николай!

Обращаюсь к вам со следующим вопросом. Мне необходимо скопировать из книги не все листы, а только некоторые. Порядковые номера этих листов прописанны в определенных ячейках основной книги. Т.е., копируются только те листы, номера которых указаны в ячейках. Количество копируемых листов строго ограничено - 5шт.

Каким образом видоизменится макрос?

Заранее благодарю за помощь.

С уважением, Владислав!
02.07.2013 10:40:16
Вместо 21 строчки нужно будет вставить примерно следующее:
Sheets(ThisWorkbook.Worksheets("Лист1").Range("A1")).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
Sheets(ThisWorkbook.Worksheets("Лист1").Range("A2")).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
Sheets(ThisWorkbook.Worksheets("Лист1").Range("A3")).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
 

Подразумевается, что номера листов, которые надо копировать, лежат в ячейках А1, А2 и А3 на листе Лист1 основной книги.
Здравствуйте уважаемый Николай.
в вашей надстройке PLEX также есть возможность собирать в одну книгу листы из разных книг. Всё работало хорошо до вчерашнего дня. сейчас же, при попытке собрать листы в одну книгу процесс идет до какого то момента и отваливается либо просто по ошибке Экселя либо по ошибке Run-Time Error -2147417848 (80010108) Automation error и Эксель закрывается. Если успеть перед ошибкой сохранить документ то при открытии выскакивает ошибка "слишком много различных форматов ячеек". причем даже не получается собрать те данные которые неделей раньше с успехом собирались. Подскажите, пожалуйста, что нужно в коде поменять чтобы собирались только данные с листов, без форматов или может быть подскажите что в экселе изменилось, что он не хочет корректно работать. Спасибо вам за помощь.
21.07.2013 12:00:32
Макрос поменять не получится, ибо он копирует листы целиком. Попробуйте для начала использовать формат xlsx вместо xls - он позволяет хранить не 4 тыс, а 64 тыс. разных форматов ячеек.
Николай, спасибо за ответ. картина все равно странная получается. собираю 4 листа, очищаю от форматов, добавляю еще один и бац, вылетает по ошибка. И почему тогда неделей раньше я смог собрать большую книгу без очистки от форматов, а сейчас даже то, что собрал сделать вновь не могу? я попробую сделать то что вы посоветовали но уже дома, в компании мне никто не будет ставить новый офис.
22.07.2013 20:35:29
Трудно определенно сказать не видя файла. Возможно, количество форматов в какой-то момент все же превышает 4 тыс. Например, при копировании листа из какой-либо книги, где их было уже много.
Я таки смог еще раз собрать книгу с большим количеством листов. могу прислать два чистых файла экселя (xls), в один можно собрать много мноого листов а в другой нельзя (отваливается по ошибке, и ограничение только 24 листа). разницу я так и не понял, даже в структуре не нашел ничего подозрительного. если интересно, Николай, то как вам их прислать? спасибо.
26.07.2013 09:21:24
У меня, в любом случае, Excel 2013 - я вашу ошибку переполнения стилей воспроизвести не смогу. Киньте на info@planetaexcel.ru - гляну что и как.
25.07.2013 04:33:51
Отличный макрос, да. Благодарим.:) А можно-ли реализовать возможность именовать новые листы не "TEDSHEET" с номером, а в соответствии с названиями САМИХ ФАЙЛОВ  - было бы очень замечательно)    
22.08.2013 14:09:29
и все же возможно ли как-то видоизменить этот (первоначальный) макрос чтобы именовал листы в соответствии с названием файла, не используя PLEX. было бы великолепно)
26.07.2013 13:04:13
Действительно лучше. А я и забыл что приобрел PLEX :)
22.08.2013 14:06:40
и все же возможно ли как-то видоизменить этот (первоначальный) макрос не используя PLEX. было бы великолепно)
29.08.2013 13:10:18
Это непросто, ибо имена листов в Excel имеют ограничение на используемые символы и длину. Поэтому надо писать проверку всех этих факторов в макросе, иначе он будет выдавать ошибку.
Советую посмотреть (взять) код прямо в PLEX.
11.10.2013 21:05:23
скажите пожалуйста, а как переделать макрос, чтобы он собирал на отдельном листе книги данные по всем листам этой же книги (данные представлены в таблицах, однотипные, включают различные типы данных), чтобы на итоговом листе в первом столбце проставлялся порядковый номер записи и осуществлялась сортировка по дате, т.к. дата есть в каждой строке, очень нужно, я еще пока плохо разбираюсь в vba. спасибо!
08.11.2013 18:48:19
Пробовала всеми перечисленными способами..
Правильно я понимаю, что файлы должны быть в старом формате «Книга Excel 97-2003» .. ?
Когда мне предлагается выбрать файлы для объединения, то файлы в формате «Excel» и в формате с поддержкой макросов даже не отображаются..
Если так, то очень жаль – потому что при переводе файлов в формат «Книга Excel 97-2003» сильно портится форматирование ..
Последним из предложенных методов у меня даже получилось объединить.. но.. со ссылками на исходные файлы.. Это никуда не годится.
Что можно сделать .. пож-та посоветуйте .. !
03.12.2013 15:24:17
Николай, помогите мне пожалуйста!
У меня есть книга (отчет).
В этот отчет нужно добавлять информацию из 36 разных книг, т.е. существует 36 файлов exсel.
я делал старым - бабаевским методом просто давал ссылку на каждый из 36 файлов ячейку,
но информация не обновляется, нужно как бы открыть 36 файлов, только после этого информация обновляется

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

что посоветуйте сделать?
29.01.2014 16:22:58
Всем привет, надо сложить разные книги excel в одну. Я формулу делал с начало из нее самой (ячейка = ссылка из книги, адрес ячейки+ссылка из следующей книги и ячейки и т.д.). Сложность в том что после создания формулы я пытался раздвинуть ячейку на соседнею. Но при копирование, не изменялся адрес ячейки на соседнею а просто полностью копировалась в новую ячейку со старой формулой. Как можно упростить заполнение книги без ручного ввода каждой ячейки ???
17.06.2014 23:31:48
Очень крутая вещь, а есть ли решение чтобы копировать данные из разных таблиц в одну единственную?
Формат таблиц на всех листах одинаковый.
27.07.2014 10:22:59
Александр, можно либо написать для этого отдельный макрос, либо использовать для сборки таблиц с листов PLEX
16.07.2014 10:24:03
Спасибо, очень нужная штука! но:
1. Почему то вставляет только пустые листы..(
2. Поддержу Александра с вопросом о копировании таблиц в одну и по возможности копирование разных столбцов из разных книг в одну таблицу, в данный момент очень нужно в работе, помогите пожалуйста!
23.07.2014 12:56:26
Подскажите, пожалуйста, а как сделать в обратном порядке? В книге есть один лист, в котором информация по 20-ти складам, и нужно данный лист разбить на 20 листов, то есть для каждого склада свой лист. По фильтру копировать и вставлять долго. Может есть какой - то более автоматизированный способ?
27.07.2014 10:23:58
Спасибо, Николай. Так и сделала уже :)
20.09.2014 14:21:15
Спасибо!
09.11.2014 01:01:59
Помогите пожалуйста проблема такого рода:  есть много файлов (порядка 500)  из которых нужно взять только 3 лист. проблема в том что они одинаково называются и он (макрос) не дает их переместить ссылаясь на ошибку "runtime error 1004 это имя уже используется выберите другое". что нужно поменять в макросе чтобы исправить эту ошибку?
заранее спасибо
09.11.2014 01:06:13
Не мучайтесь и скачайте демку надстройки PLEX - она это умеет.
09.11.2014 01:10:13
я бы и скачал но мне это макрос нужен на работу а там его не установишь к сожалению.
09.11.2014 02:03:23
Установка надстройки - это не установка программы, на это права и разрешения от админа не нужны, на самом деле.
09.11.2014 02:56:51
мне нуже на макрос так как данная процедура будет делаться на постоянной основе и боюсь что 500 запусков не хватит. поэтому попроси вас и подсказать
10.11.2014 12:55:54
Фига, извините за выражение)
Крутой макрос) Спасибо!
03.12.2014 13:12:15
Добрый день, Николай!

У меня макрос отказывается работать.
Я запускаю макрос из эксельки, и пытаюсь собрать туда листы из csv файлов.
Количество столбцов в csv намного превышает этот показатель в эксель файле (в котором я запускаю макрос). Получается ошибка:

03.12.2014 13:30:22
Количество столбцов в csv намного превышает этот показатель в эксель файле
И почему в этом случае вас удивляет возникающая ошибка? Что макрос должен сделать в этом случае с неуместившимся столбцами по-вашему?

Рекомендую перейти уже на Excel 2007 хотя бы - там не 255 столбцов, а 16 тысяч :)
03.12.2014 14:33:37
Спасибо за рекомендацию, но я работаю в MS Office Professonal Plus 2010.
Данная ошибка меня не удивляет, просто обращаю ваше внимание, что обработка подобного рода проблем не предусмотрена в вашем макросе.
А столбцов в экселе мало - потому что он сохранён в 97-2003 - там к макросам более лояльное отношение :) , не надо никаких xlsm
Спасибо.
03.12.2014 16:10:23
Сергей, спасибо за замечание, но данный макрос приведен в качестве простого примера реализации сборки на VBA. У меня не было цели выкладывать тут универсальный мегамакрос, включающий в себя абсолютную "защиту от дурака" и проверку на все возможные варианты поведения пользователя и форматы исходных данных. Здесь это ни к чему.

Новые форматы файлов (XLSX, XLSM и XLSB) сильно лучше почти по всем параметрам старого XLS. Хотя, это вопрос привычки, конечно.
03.12.2014 17:23:33
Я извиняюсь, если мое замечание показалось грубым или вы чувствуете в нем какое-то обвинение :)
Я с вами абсолютно согласен, всех защит от дураков не сделаешь, да и смысла мало. Просто запустил его - ошибка вылезает. Растерялся, поделился тут скрином)
За код большое спасибо - мне он оказался очень полезным.
03.12.2014 23:27:12
Все ОК, никаких обид, боже упаси :)
Николай, добрый день!

Пожалуйста, помогите оптимизировать следующую задачу.

Каждый день приходят в одну папку файлы с предложениями по ценам на товар (Количество исходных файлов до 50 штук). Старые файлы при этом удаляются.  
Возможно ли создать сводную таблицу, которая будет автоматически собирать данные и обновлять их  со всех файлов на один лист с  названием файла в каждой строке сводной таблицы.
С условием, что  путь к папке мы указываем один раз.
 
12.03.2015 17:29:32
Добрый день Николай!
Подскажите, можно ли при сборке вышеуказанным макросом листов с разных книг одновременно и разрывать связи, которые там присутствуют?
Буду очень признателен, если поделитесь необходимым для этого макросом
Спасибо!
05.04.2015 10:13:21
Здравствуйте, подскажите пожалуйста, можно ли сделать так, чтобы перед сборкой листов в один файл, в эти листы вставлялость название книги из которой они копируются (к примеру в ячейку B2 вставляется название Книги, а затем лист копируется)?
Страницы: 1  2  
Наверх