Добрый день! Подскажите, как расширить возможности макроса из темы http://www.excelworld.ru/forum/10-16320-1 ,чтобы была возможность суммировать все файлы (на каждом листе свое суммирование) из папки, выбираемой пользователем. Для результирующего файла формат листа, ширина столбцов берется из любого файла.
Добрый день! Подскажите, как расширить возможности макроса из темы http://www.excelworld.ru/forum/10-16320-1 ,чтобы была возможность суммировать все файлы (на каждом листе свое суммирование) из папки, выбираемой пользователем. Для результирующего файла формат листа, ширина столбцов берется из любого файла.Мурад
Сообщение отредактировал Мурад - Четверг, 29.11.2018, 16:51
Коллегой написан макрос, суммирующий данные со всех листов, но время его выполнения удручает. 130 файлов обрабатываются более 30 минут.. Прилагаю файл
Коллегой написан макрос, суммирующий данные со всех листов, но время его выполнения удручает. 130 файлов обрабатываются более 30 минут.. Прилагаю файлМурад
Мурад, в вашей "простыне" долго разбираться не стал, скажу только, что отключение лишь обновления экрана мало, надо еще отключать события листа, автопересчет и т.п. как это сделал Kuzmich в макросе по ссылке. правда, в вашей простыне я его макроса не нашел... во вторых, рекомендую использовать объектные переменные. Например, Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") - это объект и если вы его в макросе используете 101 раз, то замените на переменную. так же можно использовать конструкцию With ... End With Один макрос я вам поправил, добавил две функции для включения и отключения обновление экрана и т.п., а остальное сами сделайте по аналогии...
[vba]
Код
Sub квр_111_сред() Dim sh As Worksheet Set sh = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") ' .Activate 'а вот активировать каждый раз не надо Dim AutoCalculat As Boolean: AutoCalculat = Prepare With sh If Val(.Cells(22, 5).Value) <> 0 Then For j = 6 To 10 For i = 21 To 28 .Cells(i - 10, j).Value = .Cells(i, j).Value / .Cells(22, 5).Value .Cells(i, j).ClearContents Next i Next j .Cells(22, 5).ClearContents ' Else 'Это абсолютно не требуется ' Exit Sub End If End With Call Ended(AutoCalculat) End Sub
Function Prepare() As Boolean ' Description: отключаем пересчет, обновление экрана и т.п. With Application .ScreenUpdating = False 'Обновление экрана, чтобы ничего не мигало. .EnableEvents = False 'Не обрабатывать события. .DisplayStatusBar = False 'В статусной строке выводятся различные данные, что замедляет работу, отключаем. .DisplayAlerts = False 'Выключает сообщения Экселя. If .Calculation = xlAutomatic Then Prepare = True: .Calculation = xlManual 'Включает ручной пересчет. End With End Function
Function Ended(AutoCalculat As Boolean) ' Description: включаем пересчет, обновление экрана и т.п. With Application .ScreenUpdating = True .EnableEvents = True .DisplayStatusBar = True .DisplayAlerts = True .Calculation = IIf(AutoCalculat, xlAutomatic, xlManual) End With End Function
[/vba]
вы удивитесь, на сколько изменится скорость выполнения.
Мурад, в вашей "простыне" долго разбираться не стал, скажу только, что отключение лишь обновления экрана мало, надо еще отключать события листа, автопересчет и т.п. как это сделал Kuzmich в макросе по ссылке. правда, в вашей простыне я его макроса не нашел... во вторых, рекомендую использовать объектные переменные. Например, Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") - это объект и если вы его в макросе используете 101 раз, то замените на переменную. так же можно использовать конструкцию With ... End With Один макрос я вам поправил, добавил две функции для включения и отключения обновление экрана и т.п., а остальное сами сделайте по аналогии...
[vba]
Код
Sub квр_111_сред() Dim sh As Worksheet Set sh = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") ' .Activate 'а вот активировать каждый раз не надо Dim AutoCalculat As Boolean: AutoCalculat = Prepare With sh If Val(.Cells(22, 5).Value) <> 0 Then For j = 6 To 10 For i = 21 To 28 .Cells(i - 10, j).Value = .Cells(i, j).Value / .Cells(22, 5).Value .Cells(i, j).ClearContents Next i Next j .Cells(22, 5).ClearContents ' Else 'Это абсолютно не требуется ' Exit Sub End If End With Call Ended(AutoCalculat) End Sub
Function Prepare() As Boolean ' Description: отключаем пересчет, обновление экрана и т.п. With Application .ScreenUpdating = False 'Обновление экрана, чтобы ничего не мигало. .EnableEvents = False 'Не обрабатывать события. .DisplayStatusBar = False 'В статусной строке выводятся различные данные, что замедляет работу, отключаем. .DisplayAlerts = False 'Выключает сообщения Экселя. If .Calculation = xlAutomatic Then Prepare = True: .Calculation = xlManual 'Включает ручной пересчет. End With End Function
Function Ended(AutoCalculat As Boolean) ' Description: включаем пересчет, обновление экрана и т.п. With Application .ScreenUpdating = True .EnableEvents = True .DisplayStatusBar = True .DisplayAlerts = True .Calculation = IIf(AutoCalculat, xlAutomatic, xlManual) End With End Function
[/vba]
вы удивитесь, на сколько изменится скорость выполнения.boa
Сообщение отредактировал boa - Пятница, 30.11.2018, 10:44
boa, огромное Вам спасибо! Сделал по аналогии в других модулях. Но что делать, если после определения переменной sh, идет активация 2 книг (основная и переменная функции inputbook)? Задавать 2 переменную? [vba]
Код
Sub КВР_111(inputbook As String) Dim sh As Worksheet Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Activate Application.Workbooks(inputbook).Worksheets("КВР_111").Activate Dim AutoCalculat As Boolean: AutoCalculat = Prepare For i = 11 To 12 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 4).Value Next i For i = 14 To 18 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 4).Value Next i
For i = 11 To 12 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 11).Value Next i For i = 14 To 18 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 11).Value Next i
For j = 6 To 10 For i = 21 To 28 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i - 10, j).Value
Next i Next j Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(22, 5).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(22, 5).Value + 1
If UserForm1.CheckBox1.Value = True Then For j = 12 To 17 For i = 11 To 12 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, j).Value Next i For i = 14 To 18 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, j).Value Next i Next j End If Call Ended(AutoCalculat) End Sub
[/vba]
boa, огромное Вам спасибо! Сделал по аналогии в других модулях. Но что делать, если после определения переменной sh, идет активация 2 книг (основная и переменная функции inputbook)? Задавать 2 переменную? [vba]
Код
Sub КВР_111(inputbook As String) Dim sh As Worksheet Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Activate Application.Workbooks(inputbook).Worksheets("КВР_111").Activate Dim AutoCalculat As Boolean: AutoCalculat = Prepare For i = 11 To 12 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 4).Value Next i For i = 14 To 18 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 4).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 4).Value Next i
For i = 11 To 12 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 11).Value Next i For i = 14 To 18 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, 11).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, 11).Value Next i
For j = 6 To 10 For i = 21 To 28 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i - 10, j).Value
Next i Next j Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(22, 5).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(22, 5).Value + 1
If UserForm1.CheckBox1.Value = True Then For j = 12 To 17 For i = 11 To 12 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, j).Value Next i For i = 14 To 18 Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111").Cells(i, j).Value + Application.Workbooks(inputbook).Worksheets("КВР_111").Cells(i, j).Value Next i Next j End If Call Ended(AutoCalculat) End Sub
я имею в виду, как использовать конструкцию With ... End With, если открываем одновременно 2 книги? я начал было писать: [vba]
Код
Sub КВР_111(inputbook As String) Dim sh As Worksheet, ph As Worksheet Set sh = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") Set ph = Application.Workbooks(inputbook).Worksheets("КВР_111") Dim AutoCalculat As Boolean: AutoCalculat = Prepare With sh With ph
[/vba] но потом задумался, как vba поймет, к ячейкам каких из 2 книг обращаться...
я имею в виду, как использовать конструкцию With ... End With, если открываем одновременно 2 книги? я начал было писать: [vba]
Код
Sub КВР_111(inputbook As String) Dim sh As Worksheet, ph As Worksheet Set sh = Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") Set ph = Application.Workbooks(inputbook).Worksheets("КВР_111") Dim AutoCalculat As Boolean: AutoCalculat = Prepare With sh With ph
[/vba] но потом задумался, как vba поймет, к ячейкам каких из 2 книг обращаться...Мурад
sh=Application.Workbooks(inputbook).Worksheets("КВР_111") with Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") For i = 11 To 12 .Cells(i, 4).value=.Cells(i, 4).value + sh.Cells(i, 4).value next i end with
[/vba]
* А With на текущий момент кода может быть только один. Конструкция with aaa: with bbb будет обрабатывать последний with (bbb который). Но как только напишете end with, то bbb закончится и станет обрабатываться aaa [vba]
Код
With aaa 'работаем с aaa With bbb 'работаем с bbb end with 'работаем с aaa end with
[/vba]
Примерно так можно [vba]
Код
sh=Application.Workbooks(inputbook).Worksheets("КВР_111") with Application.Workbooks("Консолидация.xlsb").Worksheets("КВР_111") For i = 11 To 12 .Cells(i, 4).value=.Cells(i, 4).value + sh.Cells(i, 4).value next i end with
[/vba]
* А With на текущий момент кода может быть только один. Конструкция with aaa: with bbb будет обрабатывать последний with (bbb который). Но как только напишете end with, то bbb закончится и станет обрабатываться aaa [vba]
Код
With aaa 'работаем с aaa With bbb 'работаем с bbb end with 'работаем с aaa end with
Понял, сделаю, спасибо! А разве отключение событий не должно запрещать книге обращаться по связям? Все-таки мы используем макросы, которые могут всё..
Понял, сделаю, спасибо! А разве отключение событий не должно запрещать книге обращаться по связям? Все-таки мы используем макросы, которые могут всё..Мурад
Насчет того, чтобы заходить в каждую книгу и отключать связи, дабы не выскакивало сообщение, как в посте №8. Вот надстройка, которая открывает эти же самые книги, не ругаясь на связи. Узнаем, как она это делает и наш макрос будет работать также без ошибок https://psv4.userapi.com/c834603....oj&dl=1
Насчет того, чтобы заходить в каждую книгу и отключать связи, дабы не выскакивало сообщение, как в посте №8. Вот надстройка, которая открывает эти же самые книги, не ругаясь на связи. Узнаем, как она это делает и наш макрос будет работать также без ошибок https://psv4.userapi.com/c834603....oj&dl=1Мурад