Этот макрос предназначен для сбора (загрузки) информации из файлов Excel, расположенных в одной папке.
Для работы этого макроса, помимо него самого, вам понадобится добавить в свой файл:
- функцию FilenamesCollection для получения списка файлов в папке
- функцию GetFolder для вывода диалогового окна выбора папки с запоминанием выбранной папки
- прогресс-бар для отображения процесса обработки файлов (модуль класса и форму)
Если при тестировании макроса у вас возникает ошибка, что не найдена та или иная функция,
— проверьте, все ли необходимые компоненты (которые перечислены выше) вы добавили в свой файл.
Этот макрос я публикую прежде всего для себя (поскольку использую этот код чуть ли ни в каждой третьей своей программе),
поэтому я не буду помогать вам в настройке этого макроса, если у вас он вдруг не заработает.
Макрос при запуске выдает диалоговое окно для выбора папки, в которой расположены обрабатываемые файлы,
после чего открывает каждый из файлов, считывает из него данные, помещает их в текущую книгу (из которой запущен макрос),
и закрывает обработанный файл без сохранения изменений.
После того, как очередной файл обработан, он перемещается во вторую папку («архив»).
Код макроса:
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
Список файлов в папке
Иногда бывает необходимо заполучить на лист Excel список файлов в заданной папке и ее подпапках. В моей практике такое встречалось неоднократно, например:
- перечислить в приложении к договору на проведение тренинга список файлов из раздаточных материалов для особо щепетильных юристов в некоторых компаниях
- создать список файлов для ТЗ проекта
- сравнить содержимое папок (оригинал и бэкап, например)
Для реализации подобной задачи можно использовать несколько способов.
Способ 1. Скелет из шкафа — функция ФАЙЛЫ
Этот способ использует древнюю функцию ФАЙЛЫ (FILES), оставшуюся в Microsoft Excel с далеких девяностых. Вы не найдете эту функцию в общем списке функций, но для совместимости, она всё ещё остаётся внутри движка Excel, и мы вполне можем её использовать.
Механизм таков:
1. В любую ячейку листа (например, в А1) введём путь к папке, список файлов из которой мы хотим получить.
Обратите внимание, что путь должен оканчиваться шаблоном со звездочками:
- *.* — любые файлы
- *.xlsx — книги Excel (только с расширением xlsx)
- *.xl* — любые файлы Excel
- *отчет* — файлы, содержащие слово отчет в названии
и т.д.
2. Создадим именованный диапазон с помощью вкладки Формулы — далее кнопка Диспетчер имен — Создать (Formulas — Names Manger — Create). В открывшемся окне введем любое имя без пробелов (например Мои_файлы) и в поле диапазона выражение:
=ФАЙЛЫ(Лист1!$A$1)
После нажатия на ОК будет создан именованный диапазон с именем Мои_файлы, где хранится список всех файлов из указанной в А1 папки. Останется их оттуда только извлечь.
3. Чтобы извлечь имена отдельных файлов из созданной переменной, используем функцию ИНДЕКС (INDEX), которая в Excel вытаскивает данные из массива по их номеру:
Если лениво делать отдельный столбец с нумерацией, то можно воспользоваться костылем в виде функции СТРОКИ (ROWS), которая будет подсчитывать количество заполненных строк с начала списка автоматически:
=ИНДЕКС(Мои_файлы; ЧСТРОК($B$3:B3))
Ну, и скрыть ошибки #ССЫЛКА! в конце списка (если вы протягиваете формулу с запасом) можно стандартной функцией ЕСЛИОШИБКА (IFERROR):
=ЕСЛИОШИБКА(ИНДЕКС(Мои_файлы; ЧСТРОК($B$3:B3)); «»)
Важное примечание: формально функция ФАЙЛЫ относится к макро-функциям, поэтому необходимо будет сохранить ваш файл в формате с поддержкой макросов (xlsm или xlsb).
Способ 2. Готовый макрос для ленивых
Если вы знакомы с макросами (не в смысле их программирования, а в смысле копипастинга готовых кодов на VBA), то вам, возможно, отлично зайдёт небольшой макрос, добавляющий в текущую книгу новый пустой лист и выводящий на него список всех файлов с их параметрами из заданной пользователем папки.
Для добавления макроса в вашу книгу нажмите сочетание клавиш Alt+F11, или кнопку Visual Basic на вкладке Разработчик (Developer), в открывшемся окне редактора Visual Basic вставьте новый модуль через меню Insert — Module и скопируйте туда текст этого макроса:
Sub FileList() Dim V As String Dim BrowseFolder As String 'открываем диалоговое окно выбора папки With Application.FileDialog(msoFileDialogFolderPicker) .Title = "Выберите папку или диск" .Show On Error Resume Next Err.Clear V = .SelectedItems(1) If Err.Number <> 0 Then MsgBox "Вы ничего не выбрали!" Exit Sub End If End With BrowseFolder = CStr(V) 'добавляем лист и выводим на него шапку таблицы ActiveWorkbook.Sheets.Add With Range("A1:E1") .Font.Bold = True .Font.Size = 12 End With Range("A1").Value = "Имя файла" Range("B1").Value = "Путь" Range("C1").Value = "Размер" Range("D1").Value = "Дата создания" Range("E1").Value = "Дата изменения" 'вызываем процедуру вывода списка файлов 'измените True на False, если не нужно выводить файлы из вложенных папок ListFilesInFolder BrowseFolder, True End Sub Private Sub ListFilesInFolder(ByVal SourceFolderName As String, ByVal IncludeSubfolders As Boolean) Dim FSO As Object Dim SourceFolder As Object Dim SubFolder As Object Dim FileItem As Object Dim r As Long Set FSO = CreateObject("Scripting.FileSystemObject") Set SourceFolder = FSO.getfolder(SourceFolderName) r = Range("A65536").End(xlUp).Row + 1 'находим первую пустую строку 'выводим данные по файлу For Each FileItem In SourceFolder.Files Cells(r, 1).Formula = FileItem.Name Cells(r, 2).Formula = FileItem.Path Cells(r, 3).Formula = FileItem.Size Cells(r, 4).Formula = FileItem.DateCreated Cells(r, 5).Formula = FileItem.DateLastModified r = r + 1 X = SourceFolder.Path Next FileItem 'вызываем процедуру повторно для каждой вложенной папки If IncludeSubfolders Then For Each SubFolder In SourceFolder.SubFolders ListFilesInFolder SubFolder.Path, True Next SubFolder End If Columns("A:E").AutoFit Set FileItem = Nothing Set SourceFolder = Nothing Set FSO = Nothing End Sub
Для запуска макроса нажмите сочетание клавиш Alt+F8,или кнопку Макросы (Macros) на вкладке Разработчик (Developer), выберите наш макрос FileList и нажмите кнопку Выполнить (Run). В диалоговом окне выберите любую папку или диск и — вуаля!
Если захотите, чтобы вместо пути к файлу в столбце B выводилась живая гиперссылка, то замените 52-ю строку
Cells(r, 2).Formula = FileItem.Path
на
Cells(r, 2).Formula = «=HYPERLINK(«»» & FileItem.Path & «»»)»
Способ 3. Мощь и красота — надстройка Power Query
Power Query — это очень мощная и при этом бесплатная надстройка для Excel от Microsoft, упрощающая множество задач по загрузке и трансформации данных. В нашей ситуации она тоже может здорово помочь.
Если у вас Excel 2016 или новее, то Power Query уже встроена в Excel по умолчанию, поэтому просто на вкладке Данные выберите команду Создать запрос / Получить данные — Из файла — Из папки (Create Query / Get Data — From file — From folder). Если у вас Excel 2010-2013, то Power Query нужно будет скачать с сайта Microsoft и установить как отдельную надстройку и она появится у вас в Excel в виде отдельной вкладки Power Query. На ней будет аналогичная кнопка Из файла — Из папки (From file — From folder).
В открывшемся окне нужно будет указать папку, содержимое которой мы хотим получить. После нажатия на ОК Power Query обшарит указанную папку и все вложенные подпапки и выдаст на экран окно с предварительным просмотром результатов:
Если внешний вид списка вас устраивает, то можно смело жать внизу кнопку Загрузить (Load), чтобы залить эти данные на новый лист. Если же хочется дополнительно обработать список (удалить лишние столбцы, отобрать только нужные файлы и т.п.), то нужно выбрать команду Изменить / Преобразовать данные (Edit / Transform Data).
Поверх окна Excel откроется окно редактора Power Query, где мы увидим список всех наших файлов в виде таблицы:
Дальше возможны несколько вариантов:
- Если нужны только файлы определенного типа, то их можно легко отобрать с помощью фильтра по столбцу Extension:
- Аналогичным образом фильтрами по столбцам Date accessed, Date modified или Date created можно отобрать файлы за нужный период (например, созданные только за последний месяц и т.п.):
- Если нужно получить данные не из всех папок, то фильтруем по столбцу Folder Path, чтобы оставить только те строки, где путь содержит/не содержит нужные имена папок:
- Там же можно выполнить сортировку файлов по любому столбцу, если требуется.
После того, как необходимые файлы отобраны, можно смело удалить ненужные столбцы, щелкнув по заголовку столбца правой кнопкой мыши и выбрав команду Удалить (Remove column). Это, кстати, уже никак не повлияет на фильтрацию или сортировку нашего списка:
Если в будущем планируется подсчитывать количество файлов в каждой папке (например, для контроля поступивших заявок или подсчета статистики по заявкам), то имеет смысл дополнительно сделать ещё пару действий:
- Щелкните правой кнопкой мыши по столбцу Folder Path и выберите команду Дублировать столбец (Duplicate Column).
- Выделите скопированный столбец и на вкладке Преобразование (Transform) выберите Разделить столбец — По разделителю (Split Column — By delimiter)
Мы получим рядом с нашими данными еще несколько столбцов, где будут продублированы имена вложенных папок — это пригодится нам чуть позже для подсчета статистики с помощью сводной таблицы:
Получившиеся столбцы можно переименовать (Диск, Папка1, Папка2 и т.д.), просто щёлкнув дважды по заголовку каждого.
И, наконец, когда список готов, то его можно выгрузить на лист с помощью команды Главная — Закрыть и загрузить — Закрыть и загрузить в… (Home — Close & Load — Close & Load to…):
И, само-собой, теперь можно построить по нашей таблице сводную (вкладка Вставка — Сводная таблица), чтобы легко подсчитать количество файлов в каждой папке:
Дополнительным бонусом можно сделать еще один столбец с функцией ГИПЕРССЫЛКА (HYPERLINK), которая создаст красивые стрелочки-ссылки для моментального перехода к каждому файлу:
Мелочь, а приятно
И вдвойне приятно, что в будущем, при изменении содержимого исходной папки, достаточно будет просто щелкнуть мышью по нашей таблице и выбрать команду Обновить (Refresh) — и Power Query выполнит всю цепочку запрограммированных нами единожды действий уже автоматически, отобразив все изменения в составе папки.
Ссылки по теме
- Что такое макрос, куда вставлять код макроса на Visual Basic
- Создание резервных копий ценных файлов
- Что такое Power Query и что можно делать с её помощью
0 / 0 / 0 Регистрация: 18.01.2013 Сообщений: 11 |
|
1 |
|
23.01.2013, 17:49. Показов 10968. Ответов 4
В папке находится куча xls файлов. У всех у них одинаковая структура. Но она может меняться периодически. Необходимо все файлы собрать в один.
0 |
KoGG 5590 / 1580 / 406 Регистрация: 23.12.2010 Сообщений: 2,366 Записей в блоге: 1 |
||||
24.01.2013, 13:49 |
2 |
|||
Кликните здесь для просмотра всего текста
1 |
Botъ 0 / 0 / 0 Регистрация: 18.01.2013 Сообщений: 11 |
||||
24.01.2013, 18:38 [ТС] |
3 |
|||
KoGG, спасибо! Добавлено через 12 минут Кликните здесь для просмотра всего текста
0 |
0 / 0 / 0 Регистрация: 27.01.2017 Сообщений: 1 |
|
12.05.2017, 14:02 |
4 |
Добрый день! Почти идеально подошел вышеуказанный макрос, только для моей задачи необходимо чтобы в каждой строчке еще был указан исходный файл, т.е. чтобы было видно что эти 5 наименований пришли из файла А , а другие 7 из файла И и т.д. Не подскажете что тут дописать/изменить?
0 |
KoGG 5590 / 1580 / 406 Регистрация: 23.12.2010 Сообщений: 2,366 Записей в блоге: 1 |
||||
13.05.2017, 17:11 |
5 |
|||
1 |
Предположим, имеется куча книг Excel, все листы из которых надо объединить в один файл. Копировать руками долго и мучительно, поэтому имеет смысл использовать несложный макрос.
Открываем книгу, куда хотим собрать листы из других файлов, входим в редактор Visual Basic (ALT+F11), добавляем новый пустой модуль (в меню Insert — Module) и копируем туда текст вот такого макроса:
Sub CombineWorkbooks()
Dim FilesToOpen
Dim x As IntegerApplication.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
WendApplication.ScreenUpdating = True
End Sub
После этого можно вернуться в Excel и запустить созданный макрос через меню Сервис — Макрос — Макросы (Tools — Macro — Macros) или нажав ALT+F8. Отобразится диалоговое окно открытия файла, где необходимо указать один или несколько (удерживая CTRL или SHIFT) файлов, листы из которых надо добавить к текущей книге.
PE
В случаях, когда требуется выполнить однотипные операции с большим количеством файлов Excel (будь то сбор данных или внесение изменений) проще всего использовать скрипт Excel-VBA. В статье приведены примеры таких скриптов и пошагово объяснёна их работа.
Для того, чтобы перебрать все файлы .xls и .xlsx в папке C:/Folder/ можно использовать следующий код:
sFolder = "C:/Folder/"
sFolder = sFolder & IIf(Right(sFolder, 1) = Application.PathSeparator, "", Application.PathSeparator)
sFiles = Dir(sFolder & "*.xls*")
Do While sFiles <> ""
Workbooks.Open sFolder & sFiles
'what to do in each file
ActiveWorkbook.Close False
'write data
sFiles = Dir
Loop
В первом блоке мы задаём целевую папку и добавляем разделительный символ / к адресу в случае, если мы забыли его указать. Это делается по причине того, что чаще всего мы копируем путь из проводника и там этот символ в конце отсутствует.
sFolder = "C:/Folder/"
sFolder = sFolder & IIf(Right(sFolder, 1) = Application.PathSeparator, "", Application.PathSeparator)
Следующая команда открывает первый файл, находящийся в целевой папке. Для того, чтобы был открыт именно файл Excel мы прописываем в качестве аргумента соединение двух строк: sFolder & «.xls*». Звёздочки в данном случае интерпретируются как любое количество любых символов. Таким образом мы открываем все файлы, оканчивающиеся на .»xls»+ любые другие символы. Если нам было бы нужно перебрать только файлы с определёнными символами в имени, то аргумент мог бы выглядеть так: sFolder &»*Шаблон_имени_файла*»& «.xls*»
sFiles = Dir(sFolder & "*.xls*")
В заключительной части мы перебираем все остальные файлы, попадающие под заданный шаблон:
Do While sFiles <> ""
Workbooks.Open sFolder & sFiles
'what to do in each file
ActiveWorkbook.Close False
'write data
sFiles = Dir
Loop
Очевидно, что перебор осуществляется с помощью цикла While. Цикл работает пока переменная sFiles не будет равна пустой строке «». Предпоследняя строка — повторное использование функции Dir без аргумента присваивает переменной sFiles название пути и имени следующего файла, имя которого соответствует шаблону. В случае, если под заданный шаблон не больше не попадает файлов, переменная функция Dir присваивает переменной sFiles значение «», что приводит к остановке цикла.
Хитрости »
1 Май 2011 765601 просмотров
Как собрать данные с нескольких листов или книг?
Очень часто бывает необходимо собрать данные с нескольких листов одной книги или даже с листов нескольких книг. Например, каждую неделю мы получаем некие отчеты от отделов, которые необходимо собрать в одну общую таблицу для построения сводной таблицы. Или это могут быть некие книги прайсов по товарам от разных поставщиком, который опять же надо сначала объединить, а потом уже анализировать. Вручную делать это довольно муторно. И то, муторно это только для первых 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 091 скачиваний)
Также см.:
Сбор данных с нескольких листов/книг
Как объединить несколько текстовых файлов в один?
Просмотреть все файлы в папке
План-фактный анализ в Excel при помощи Power Query
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Skip to content
Мы рассмотрим три способа объединения файлов Excel в один: путем копирования листов, запуска макроса VBA и использования инструмента «Копировать рабочие листы» из надстройки Ultimate Suite.
Намного проще обрабатывать данные в одном файле, чем переключаться между многочисленными книгами. Однако объединение нескольких книг Excel в один файл может быть сложным и долгим процессом, особенно если книги, которые вам нужно объединить, содержат много листов. Итак, как подойти к этой проблеме? Вы будете копировать их вручную или с помощью кода VBA? Или вы используете один из специализированных инструментов для объединения файлов Excel?
Ниже вы найдете несколько хороших способов, позволяющих реализовать объединение.
- Самое простое — копировать вручную.
- Объединение файлов Excel при помощи VBA.
- Как объединить несколько файлов с помощью Ultimate Suite.
Примечание. В этой статье мы рассмотрим, как копировать листы из нескольких книг Excel в одну книгу. Если вы ищете быстрый способ скопировать данные с нескольких листов на один общий лист, вы найдете подробную инструкцию в другой статье: Как объединить несколько листов в один.
Простой метод — копировать листы руками.
Если вам нужно объединить всего пару файлов Excel, вы можете вручную скопировать или переместить листы из одного файла в другой. Вот как это можно сделать:
- Откройте книги, которые мы планируем объединить.
- Выберите листы в исходной книге, которые вы хотите скопировать в основную книгу.
Чтобы выбрать несколько листов, используйте один из следующих приемов:
- Чтобы выбрать соседние листы, щелкните вкладку первого, который вы хотите скопировать, нажмите и удерживайте клавишу Shift, а затем щелкните вкладку последнего. Это действие выберет все листы между ними.
- Чтобы выбрать несмежные, удерживайте клавишу Ctrl и щелкайте вкладку каждого из них по отдельности.
- Выделив все нужные листы, щелкните правой кнопкой мыши любую из выделенных вкладок и выберите «Переместить» или «Копировать…» .
- В диалоговом окне «Перемещение или копирование» выполните следующие действия:
- В раскрывающемся списке «Переместить выбранные листы в книгу» выберите целевую книгу, в которую вы хотите объединить другие файлы.
- Укажите, где именно должны быть вставлены вкладки. В нашем случае мы выбираем вариант вставки в конец списка.
- Установите флажок «Создать копию», если хотите, чтобы исходные данные оставались оригинальном файле.
- Нажмите
ОК
, чтобы завершить операцию.
Чтобы объединить вкладки из нескольких файлов 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
Как добавить этот макрос в книгу
Если вы хотите вставить макрос в свою книгу, выполните следующие обычные действия:
- нажимать
Alt + F11
, чтобы открыть редактор Visual Basic. - Щелкните правой кнопкой мыши ThisWorkbook на левой панели и выберите « Вставить» > « Модуль» в контекстном меню.
- В появившемся окне (Окно кода) вставьте указанный выше код.
Более подробная инструкция описана в разделе Как вставить и запустить код VBA в Excel .
Кроме того, вы можете загрузить макрос в файле Excel, открыть его в этой книге (включить выполнение макросов, если будет предложено), а затем переключиться на свою собственную книгу и нажать Alt + F8
для его запуска. Если вы новичок в использовании макросов в Excel, следуйте подробным инструкциям ниже.
Как использовать макрос MergeExcelFiles
Откройте файл Excel, в котором вы хотите объединить листы из других книг, и выполните следующие действия:
- Нажмите комбинацию
Alt + F8
, чтобы открыть окно диалога. - В разделе « Имя макроса» выберите MergeExcelFiles и нажмите «Выполнить».
- Откроется стандартное окно проводника, вы выберите одну или несколько книг, которые хотите объединить, и нажмите «Открыть» . Чтобы выбрать несколько файлов , удерживайте нажатой клавишу Ctrl, указывая на их имена.
В зависимости от того, сколько файлов вы выбрали, дайте макросу несколько секунд или минут для их обработки. После завершения всех операций он сообщит вам, сколько файлов было обработано и сколько листов было объединено:
Как объединить несколько файлов с помощью Ultimate Suite.
Если вам не очень комфортно с VBA и вы ищете более простой и быстрый способ объединить файлы Excel, обратите внимание на инструмент «Копирование листов (Copy Sheets)» — одну из более чем 60 функций, включенных в невероятно функциональную программу Ultimate Suite for Excel. Она работает в версиях Excel 2010-2019.
С Ultimate Suite объединение нескольких файлов Эксель в один так же просто, как раз-два-три (буквально, всего 3 быстрых шага). Вам даже не нужно открывать те из них, которые вы хотите объединить. И это могут быть два файла или несколько — не важно.
- Открыв главную книгу, перейдите на вкладку «Ablebits Data» и нажмите «Копировать листы (Copy Sheets)» > «Выбранные в одну книгу (Selected Sheets to one workbook)».
- В диалоговом окне выберите файлы (а в них — листы), которые вы хотите объединить, и нажмите «Далее (Next)» .
Советы:
- Чтобы выбрать все листы в определенной книге, просто поставьте галочку в поле рядом с именем книги, и все они в этом файле будут выбраны автоматически.
- Чтобы объединить листы из закрытых книг, нажмите кнопку «Добавить файлы…» и выберите столько книг, сколько нужно. Это добавит выбранные файлы только в окно копирования, не открывая их в Excel.
- По умолчанию копируются все данные. Однако, в разных листах можно выбрать разные диапазоны для объединения. Чтобы скопировать только определенную область, наведите указатель мыши на имя вкладки, затем щелкните значок и выберите нужный диапазон.
- При необходимости укажите один или несколько дополнительных параметров и нажмите «Копировать» . На снимке скриншоте а ниже показаны настройки по умолчанию: Вставить все (формулы и значения) и Сохранить форматирование.
Дайте мастеру копирования листов несколько секунд для обработки и наслаждайтесь результатом!
На этой странице есть подробное описание всех возможностей работы мастера копирования.
Чтобы поближе познакомиться с этим и другими инструментами для Excel, вы можете загрузить ознакомительную версию Ultimate Suite.
Итак, я надеюсь, вы получили ответ на вопрос — как быстро объединить несколько файлов Excel в один.
Есть функция, которая открывает по очереди все файлы в заданной папке и запускает в каждом из них макрос UpdateFile.
Макрос делает обновление данных, сохранение и закрытие файла.
Макрос UpdateFile может быть в каждом из обрабатываемых файлов или может быть в исходном файле, откуда запускается весь процесс обновления файлов.
Sub Obnovlenie_Sokhranenie_failov_v_papke()
Dim s As String, fldr As String, j As Integer, f As Integer
Dim rc As Range
fldr = "d:"
s = Dir(fldr & "*.xls*")
j = 0
f = 0
Application.ScreenUpdating = False
'podschyot kolichestva failov v papke
Do While s <> ""
s = Dir
f = f + 1
Loop
'obrabotka failov v papke
s = Dir(fldr & "*.xls*")
Do While s <> ""
With Workbooks.Open(fldr & s)
'deistviia s knigoi
'Application.Run (UpdateFile) 'вот тут проблема
Application.Wait Time:=Now + TimeValue("0:00:10") 'задержка
.Close (True)
End With
s = Dir
j = j + 1
Application.StatusBar = "Obrabotano: " & j & " iz " & f & " failov" & " -> " & s: DoEvents
Loop
Application.ScreenUpdating = True
ActiveWorkbook.RefreshAll
Application.StatusBar = "Obrabotano: " & j & " èç " & f & " failov"
End Sub
Макрос UpdateFile:
Sub UpdateFile()
'deistviia s knigoi
Application.DisplayAlerts = False
Application.ScreenUpdating = False
ActiveWorkbook.RefreshAll
Application.Wait Time:=Now + TimeValue("0:00:05") 'задержка
ActiveWorkbook.Save
ActiveWorkbook.Close True
Application.ScreenUpdating = True
End Sub
задан 17 окт 2018 в 11:10
Виталий МурачВиталий Мурач
371 золотой знак1 серебряный знак6 бронзовых знаков
Запуск макроса из другой книги:
With Workbooks.Open(Filename:=fldr & s)
Application.Run "'" & s & "'!Module1.UpdateFile"
Module1 — имя модуля, в котором записан макрос.
При этом отключать/включать обновление экрана и сообщения следует только один раз, в общей процедуре.
With Application
.DisplayAlerts = False
.ScreenUpdating = False
End With
Сохранение и закрытие книги тоже передать наружу и в макросе останется только запуск обновлений (и правильнее не активной книги, а книги, в которой находится макрос):
Sub UpdateFile()
ThisWorkbook.RefreshAll
End Sub
ответ дан 17 окт 2018 в 11:25
Сбор данных из файлов Excel в заданной папке
- Макросы VBA Excel
- Обработка файлов
- Работа с диапазонами ячеек и листами
- Обработка таблиц
- Список файлов
- Объединение файлов
- Книги Excel
- Сводные таблицы
Этот макрос предназначен для сбора (загрузки) информации из файлов Excel, расположенных в одной папке.
Для работы этого макроса, помимо него самого, вам понадобится добавить в свой файл:
- функцию FilenamesCollection для получения списка файлов в папке
- функцию GetFolder для вывода диалогового окна выбора папки с запоминанием выбранной папки
- прогресс-бар для отображения процесса обработки файлов (модуль класса и форму)
Если при тестировании макроса у вас возникает ошибка, что не найдена та или иная функция,
— проверьте, все ли необходимые компоненты (которые перечислены выше) вы добавили в свой файл.
Этот макрос я публикую прежде всего для себя (поскольку использую этот код чуть ли ни в каждой третьей своей программе),
поэтому я не буду помогать вам в настройке этого макроса, если у вас он вдруг не заработает.
Макрос при запуске выдает диалоговое окно для выбора папки, в которой расположены обрабатываемые файлы,
после чего открывает каждый из файлов, считывает из него данные, помещает их в текущую книгу (из которой запущен макрос),
и закрывает обработанный файл без сохранения изменений.
После того, как очередной файл обработан, он перемещается во вторую папку («архив»).
Код макроса:
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