Страницы: 1
RSS
Макрос, собирающий данные из разных файлов .xlsx в папке по условию
 
Здравствуйте!  
 
Крайне необходимо написать макрос, собирающий данные из разных файлов в папке по условию.  
Нашел в интернете нечто похожее и попытался переделать под свой файл, но поскольку я в программировании разбираюсь крайне мало, видимо написал что-то не так и макрос работать не хочет.  
 
Сам макрос должен делать следующее:  
Есть папка с множеством файлов, названных кое-как. В этой же папке находится файл с итоговой таблицей. Макрос по очереди открывает все файлы .xlsx, ищет ячейку с кодом сотрудника, и по коду подтягивает в итоговую таблицу две цифры.  
 
Огромная просьба помочь разобраться почему макрос не работает.  
 
Пример итогового файла и двух файлов, с которых тянутся данные, прилагаю.    
 
Заранее огромное спасибо!
 
Так и не понял, что нужно копировать с файлов? (ФИО и КОД - табельный №?)  
файлы всегда одинакового формата?  
столбцы меняются местами?  
нужно копировать данные с каких-то определенных ячеек? со всех одних и тех же?
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Прошу прощения - видимо плохо объяснил.  
 
Код - это табельный номер сотрудника.    
Копировать надо две цифры - затраты сотрудника и компании - они стоят возле ячеек "Из них компания:" и "Сотрудник:" (я их пытался выудить с помощью offset, поскольку они всегда находятся в одном и том же столбце, но при этом могут находится в разных строках).  
Файлы всегда формата *.xlsx.    
Все необходимые данные (код и копируемые значения) всегда в одних и тех же столбцах (но могут быть в разных строках).  
Вставлять нужно в итоговую таблицу в строки напротив соответствующего кода (сотрудника), но этот отчет обновляется 4 раза в месяц, поэтому каждый раз данные нужно вставлять в незаполненные ячейки (т.е. вставлять в пустые ячейки, слева от заполненных).  
 
Еще раз прошу прощения.  
Спасибо!
 
* выше в последнем пункте имеется ввиду "вставлять в пустые ячейки СПРАВА от заполненных".
 
Option Explicit  
Option Private Module  
Dim o_Files As Object  
Dim i As Integer  
Dim wb As Object  
Dim wb_Close As Workbook  
Dim j As Long  
Dim iLastrow As Long  
Dim o_Files_Count As Long  
 
 
Sub iOpen()  
   Application.ScreenUpdating = False  
 
   On Error GoTo err  
 
   Set o_Files = Application.FileDialog(msoFileDialogFilePicker)  
 
   o_Files.Show  
   o_Files_Count = o_Files.SelectedItems.Count  
 
   For i = 1 To o_Files_Count  
       Range("A" & i).Value = o_Files.SelectedItems(i)  
   Next  
 
   iLastrow = ThisWorkbook.Sheets(2).Cells(Rows.Count, 1).End(xlUp).Row  
 
   With ThisWorkbook.Sheets(1)  
       For j = 1 To iLastrow  
           Set wb = ThisWorkbook.Sheets(2).Range("A" & j).Cells  
           Workbooks.Open Filename:=wb  
           Windows(ThisWorkbook.Name).ActivateNext  
           ActiveWorkbook.Sheets(1).[a2].Copy .Range("B" & .Cells(.Rows.Count, 2).End(xlUp).Row).Offset(1, 0)
           ActiveWorkbook.Sheets(1).[d2].Copy .Range("C" & .Cells(.Rows.Count, 3).End(xlUp).Row).Offset(1, 0)
           ActiveWorkbook.Sheets(1).Range("B" & Cells(Rows.Count, 2).End(xlUp).Row) _  
               .Copy .Range("E" & .Cells(.Rows.Count, 5).End(xlUp).Row).Offset(1, 0)  
           ActiveWorkbook.Sheets(1).Range("B" & Cells(Rows.Count, 2).End(xlUp).Row - 1) _  
               .Copy .Range("F" & .Cells(.Rows.Count, 6).End(xlUp).Row).Offset(1, 0)  
       Next  
   End With  
 
   For Each wb_Close In Workbooks  
       If Not wb_Close Is ThisWorkbook And Windows(wb_Close.Name).Visible Then wb_Close.Close (False)  
   Next  
 
   Exit Sub  
err:  
   MsgBox "Файлы не выбраны", vbCritical, ""  
   Application.ScreenUpdating = True  
End Sub
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Спасибо за макрос!  
 
Попробовал запустить макрос - он не работает.  
Насколько я понял, надо нажать кнопку "Open" и выбрать файлы с которых необходимо собирать данные...Помести файл в папку с двумя тестовыми фалами (которые я высылал), нажал-выбрал, появляется сообщение "Файлы не выбраны".  
 
Может, я что-то не так делаю?  
Может, можно реализовать сбор данных со всех файлов в папке, кроме отчетного (ненужных файлов там нет).    
 
 
Подскажите, пожалуйста.
 
Разархивируйте
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Я разархивировал. Пользовался файлом из архива - там один файлик, который называется "Отчет". Поместил его в папку с двумя тестовыми файлами, и попробовал воспользоваться - появилась проблема, описанная выше.
 
файлы формата .txt или .xls?  
с файлами экселя - у меня работает нормально, никаких ошибок
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Файлы формата .xlsx. Возможно, макрос не работает, поскольку файлы сохранены в формате Excel 2010?
 
В случае необходимости могу еще раз выложить файлы,с которыми данный отчет работать не хочет. В принципе, это те же файлы, которые я выкладывал ранее...
 
Подправил
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Теперь отлично, все работает.  
 
Еще один нюанс: макрос вставляет в поле "Фамилия" фамилию сотрудника, В поле "код", собственно код из файлов сотрудников.    
 
На деле в этих ячейках уже проставлены фамилия и код, а макрос должен по коду искать сотрудника, и проставлять данные напротив нужного сотрудника. Причем первые две ячейки справа от кода уже могут быть заняты (данные вносятся в один и тот же файл 4 раза в месяц), и если они уже заполнены данными - макрос вставляет данные в следующие две ячейки, которые стоят правее от заполненных - и так, пока не дойдет до конца файла (до ячеек Итого, которые уже заполнены итоговыми значениями). В конце я думал выводить какое-то сообщение (наподобии "не осталось пустых ячеек"), но поскольку столкнулся с проблемой в работе макроса уже на начальном этапе, то до этого не дошел.  
 
Я об этом писал выше, но наверное опять-таки написал криво и непонятно.  
Помогите, пожалуйста еще с реализацией этого момента!  
 
ЗАранее большое спасибО!
 
Предлагаю такой вариант
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Спасибо ОГРОМНОЕ за помощь!  
Предложенный вариант к сожалению не подходит - итоговая таблица должна быть установленного образца...в любом случае большое спасибо за помощь...  
 
Возможно кто-нибудь знает каким образом можно реализовать данную задачу?  
Заранее спасибо.
 
{quote}{login=Wayfarer}{date=22.03.2012 03:25}{thema=}{post}... Возможно кто-нибудь знает каким образом можно реализовать данную задачу?.. {/post}{/quote}  
Рискну предположить, что на данном этапе - после предшествующих и немалых заморочек - только одним образом - платным, т.е. под заказ (если кто возьмется)... ;) -70774-
 
Если готовы заплатить за работу - напишите мне на почту overseerpower@gmail.com доведу до ума по Вашему желанию
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Мне собственно полностью реализация не нужна - частично работоспособный макрос есть. Часть макроса не работает. Если кто-то подскажет почему не работает и/или как ее можно заставить работать - буду очень благодарен.  
 
Сам макрос:  
 
 
Option Explicit  
 
Sub CombineTables()  
Dim BazaWb As Workbook 'текущая книга (общий файл)  
Dim BazaSht As Worksheet 'лист База покупателей в общем файле  
Dim iTempFileName As String 'имя по-очерёдно открываемого файла  
Dim iPath As String 'путь к папке, где лежат все файлы  
Dim iLastRowBaza As Long 'последняя заполненная строка в общем файле в столбце D  
Dim iLastRowTempWb As Long 'последняя заполненная строка в по-очерёдно открываемом файле в столбце A  
Dim iLastColTempWb 'последний столбец с инфо в по-очерёдно открываемом файле  
Dim iNumFiles As Long 'количество открываемых файлов  
Dim IsHeader As Boolean 'скопирована ли шапка таблицы  
Dim CodeRng As Range 'ячейка с кодом сотрудника (надписью "Код")  
Dim CompRng As Range 'ячейка с надписью "Из них - Компания:"  
Dim StaffRng As Range 'ячейка снадписью "Сотрудник:"  
Dim firstAddress As String  
Dim n As Long 'счётчик  
Dim k As Long 'счётчик  
Dim m As Long 'счётчик  
Dim iLastRowTbl As Long 'номер последний строки в текущей таблице  
Dim iTablesCnt As Long 'количество скопированных таблиц  
 
     
   With Application  
       .ScreenUpdating = False  
       .DisplayAlerts = False  
       .Calculation = xlManual  
       Set BazaWb = ThisWorkbook  
       Set BazaSht = BazaWb.Worksheets("Расчет")  
       iPath = BazaWb.Path & "\"  
       iTempFileName = Dir(iPath & "*.xlsx")  
       Do While iTempFileName <> ""  
           If iTempFileName = BazaWb.Name Then GoTo iNext:  
           With .Workbooks.Open _  
               (Filename:=iPath & iTempFileName, UpdateLinks:=False, ReadOnly:=True)  
               If Not IsShtPresent("Заказы") Then  
                   Application.ScreenUpdating = True  
                   MsgBox "Листа с названием ""Заказы"" в активной книге нет! ", 48, "Ошибка"  
                   Exit Sub  
               End If  
               iNumFiles = iNumFiles + 1  
                   'Поиск меток в меню  
                   With .Worksheets("Заказы")  
                   .UsedRange.EntireRow.Hidden = False  
                   'ищем ячейку с "Company"  
                   Set CompRng = .Columns(1).Find(What:="Из них - Компания:", LookIn:=xlFormulas, LookAt:=xlWhole)  
                   'ищем ячейку с "Staff"  
                   Set StaffRng = .Columns(1).Find(What:="Сотрудник:", LookIn:=xlFormulas, LookAt:=xlWhole)  
                   'ищем ячейку с "Code"  
                   Set CodeRng = .Columns(4).Find(What:="Код", LookIn:=xlFormulas, LookAt:=xlWhole)  
 
 
До данного момента макрос работоспособен.  
Неработающая часть:  
         
 
       For k = 1 To BazaWb.BazaSht.Cells(Rows.Count, 4).End(xlUp).Row  
           If BazaWb.BazaSht.Cells(k, 4).Value = CodeRng.Offset(1, 0).Value Then  
               For m = 1 To Cells(1, Columns.Count).End(xlToLeft).Column  
                   If BazaWb.BazaSht.Cells(k, m) = "" Then  
                       BazaWb.BazaSht.Cells(k, m).Value = StaffRng.Offset(0, 1).Value  
                       BazaWb.BazaSht.Cells(k, m + 1).Value = CompRng.Offset(0, 1).Value  
               End If  
               Next m  
                 
            End If  
       Next k  
 
 
Начиная с этого момента макрос также полностью работоспособен  
 
             
               End With  
               .Close saveChanges:=False  
          End With  
iNext:  
          iTempFileName = Dir  
       Loop  
       Range("B2:B3").Merge  
       Columns("B:D").AutoFit  
       .Calculation = xlAutomatic  
       .DisplayAlerts = True  
       .ScreenUpdating = True  
   End With  
   MsgBox "Информация собрана из " & iNumFiles & " файлов"  
End Sub  
 
Function IsShtPresent(iShtName As String) As Boolean  
'проверяем существование листа в книге  
Dim iShtTest As Worksheet  
   On Error Resume Next  
   Set iShtTest = ActiveWorkbook.Sheets(iShtName)  
   If iShtTest Is Nothing Then  
       IsShtPresent = False  
   Else  
       IsShtPresent = True  
   End If  
End Function  
 
Просто никак не могу реализовать копирование данных :(  
Я его тестировал по кускам - он находит данные, файлы и т.д. правильно, а вот как их скопировать - неизвестно :(
 
"На деле в этих ячейках уже проставлены фамилия и код" - и где это "дело"?  
И пример в готовом виде тоже не помешал бы.
 
{quote}{login=Hugo}{date=22.03.2012 03:41}{thema=}{post}... И пример в готовом виде тоже не помешал бы.{/post}{/quote}  
??? - "Мне собственно полностью реализация не нужна" - 22,03,2012 - 15:40
 
Пример я выложил в своем самом первом посте.  
 
В примере три файла:  
Отчет с таблицей нужного вида (за исключением того, что в таблицу поместил только две фамилии для тестирования)  
Два файла - якобы файлы сотрудников с именами в названиях файлов.  
 
Макрос поочередно открывает все файлы в папке. Находит три параметра - код сотрудника, и суммы денег сотрудника и компании. По коду сотрудника находит нужную строку в итоговой таблицы и копирует эти две цифры в первые две незаполненные ячейки справа от кода сотрудника.  
 
Проблема с реализацией копирования.
 
{quote}{login=Hugo}{date=22.03.2012 03:41}{thema=}{post}... И пример в готовом виде тоже не помешал бы.{/post}{/quote}Вопрос непонятен...
 
Извиняюсь - нашёл оригинальный пример - вопросы снимаются (коды/фамилии есть, что куда копировать тоже вроде понятно).
 
Слегка модифицировал Ваш код.
 
{quote}{login=Hugo}{date=22.03.2012 04:05}{thema=}{post}Извиняюсь - нашёл оригинальный пример - вопросы снимаются (коды/фамилии есть, что куда копировать тоже вроде понятно).{/post}{/quote}  
Я выше на всякий случай еще раз все описал. Вроде нашел наиболее лаконичную и корректную версию. Но при ответе забыл нажать кнопку цитировать...
 
Чтоб цикл заработал - уберите BazaWb. :  
 
       For k = 1 To BazaSht.Cells(Rows.Count, 4).End(xlUp).Row  
           If BazaSht.Cells(k, 4).Value = CodeRng.Offset(1, 0).Value Then  
               For m = 1 To Cells(1, Columns.Count).End(xlToLeft).Column  
                   If BazaSht.Cells(k, m) = "" Then  
                       BazaSht.Cells(k, m).Value = StaffRng.Offset(0, 1).Value  
                       BazaSht.Cells(k, m + 1).Value = CompRng.Offset(0, 1).Value  
               End If  
               Next m  
                 
            End If  
       Next k  
 
 
Но что он делает - пока не вникал, но что-то не то...
 
{quote}{login=sva}{date=22.03.2012 04:07}{thema=}{post}Слегка модифицировал Ваш код.{/post}{/quote}  
 
Супер! Все работает идеально!Спасибо ОГРОМНОЕ!!!  
Тема закрыта.  
Буду разбирать код...  
 
З.Ы. mr.Freeman тире Сумасшедший Фрэнки на авке - супер!)
 
{quote}{login=Hugo}{date=22.03.2012 04:13}{thema=}{post}Чтоб цикл заработал - уберите BazaWb....{/post}{/quote}  
Спасибо большое! Впринципе, это то, что я хотел узнать. Не претендую на то, что там все корректно, поскольку планировал его еще дорабатывать - для меня самое главное чтобы он хоть что-то делал. Что дальше подправить или изменить я бы уже разобрался.  
Саму ошибку пробовал гуглить, но адекватных ответов не нашел(
Страницы: 1
Читают тему
Наверх