Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.07.2010, 08:49   #1
kipish_lp
Форумчанин
 
Регистрация: 25.11.2009
Сообщений: 113
По умолчанию Помогите оптимизировать макрос

Здравствуйте! Подскажите, пожалуйста, как можно оптимизировать макрос, который находится в примере. Надо просуммировать данные по определенным параметрам, и вывести их в нужные ячейки. Что макрос и делает. Но когда строк около 10000, а таблица, которую надо заполнить очень большая, макрос выполняется очень долго.
Скажу сразу, про сводные таблицы знаю, работать научилась, данные получать тоже, но иногда она не подходит. Поэтому прошу помощи с данным макросом.
Вложения
Тип файла: rar Книга1.rar (8.0 Кб, 25 просмотров)
kipish_lp вне форума Ответить с цитированием
Старый 24.07.2010, 13:58   #2
аналитика
Форумчанин
 
Регистрация: 14.05.2009
Сообщений: 311
По умолчанию

небольшая коррекция
можно привлечь встроенные средства Excel (СУММЕСЛИ напр.)
Вложения
Тип файла: rar Книга1.rar (14.0 Кб, 16 просмотров)
аналитика вне форума Ответить с цитированием
Старый 24.07.2010, 14:44   #3
kipish_lp
Форумчанин
 
Регистрация: 25.11.2009
Сообщений: 113
По умолчанию

Суммесли - это хорошо, но когда данные берутся из другой книги, не очень удобно, постоянно обновлять надо. И если более 2000 строк очень долго пересчет происходит. Про накопитель значений - косяк, недосмотрела. А так макрос все равно медленно работает, он каждый раз все строки прогоняет заново.
kipish_lp вне форума Ответить с цитированием
Старый 24.07.2010, 17:49   #4
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Убедился уже много раз.что для обработки такого количества строк очень удобно использовать АДО.На примере данных в 50 000 строк отработал менее 2 секунд.Имя листа с данными должно быть Лист1,под себя внесете исправления.
Единственный минус-месяцы идут по алфавиту.Если бы был формат даты -тогда без проблем. Я думаю проще столбцы потом поменять.
Вложения
Тип файла: rar К1.rar (74.9 Кб, 24 просмотров)
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 24.07.2010, 17:54   #5
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Я в последнее время массивы использую почаще. Вроде и код прозрачный, и быстро работают.
Вот этот код на диапазоне A2:E65500 отработал за 6.5 секунд.
Легко поменять всё под другие диапазоны. Файл тот же исходный, только данные вниз размножил.
Код:
Sub Sobrat()
'Dim tm 'это я время считал
'tm = Timer 'это я время считал
Dim ash As Worksheet
Dim a(), b(), c(), d()
Dim i As Long, k As Long, r As Long, aa As Long, bb As Long

Set ash = ThisWorkbook.ActiveSheet
ash.Range("i2:t7").Value = "" 'обнуляем, если надо суммировать - можно закомментировать
a = ash.Range("A2:e65500").Value 'база данных всего, вместо 65500 можно переменную
b = ash.Range("g2:h7").Value 'база сводной - что ищем
c = ash.Range("i1:t1").Value 'месяцы
d = ash.Range("i2:t7").Value 'диапазон выгрузки
aa = UBound(a)
bb = UBound(b)

For k = 1 To 12
    For r = 1 To bb
        For i = 1 To aa
        If a(i, 1) = c(1, k) And a(i, 2) = b(r, 1) And a(i, 3) = b(r, 2) Then d(r, k) = d(r, k) + a(i, 5)
        Next
    Next
Next

ash.Range("i2:t7") = d

'Debug.Print Timer - tm 'это я время считал
End Sub
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 24.07.2010, 18:23   #6
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

To doober - на моей машине ADO обошёл массивы всего на 2 секунды (время открытия файла не учитывал, только время работы Shet path, "Лист1").
А как же Перчатки 1/2/3?
И расположение... И код сложнее.
Я за массивы!
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 24.07.2010 в 18:51.
Hugo121 вне форума Ответить с цитированием
Старый 24.07.2010, 19:22   #7
alexvav
Форумчанин
 
Регистрация: 23.11.2006
Сообщений: 152
По умолчанию

Цитата:
Сообщение от аналитика Посмотреть сообщение
небольшая коррекция
можно привлечь встроенные средства Excel (СУММЕСЛИ напр.)
подскажите, как вы внесли формулу с фигурными скобками? в смысле, что это за формула такая?
alexvav вне форума Ответить с цитированием
Старый 24.07.2010, 19:25   #8
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

А я в последнее время ближе к базам и SQL.Да действительно в перчатках не правильный результат.если число сохранить как текст-работает правильно
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 24.07.2010, 19:29   #9
аналитика
Форумчанин
 
Регистрация: 14.05.2009
Сообщений: 311
По умолчанию

Цитата:
Сообщение от alexvav Посмотреть сообщение
подскажите, как вы внесли формулу с фигурными скобками? в смысле, что это за формула такая?
это формула массива
вводится Ctrl+Shift+Enter
аналитика вне форума Ответить с цитированием
Старый 24.07.2010, 20:12   #10
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Я тут подумал, и убрал один массив, правда работать особо быстрее не стало, и код проще не стал. Но всёж... Хотя можно и ещё один массив убрать...
Вот, вместо 4 массивов оставил 2. Особо быстрее работать не стало, может на пару сотых секунды.
Код:
Sub Sobrat()
'Dim tm 'это я время считал
'tm = Timer 'это я время считал
Dim ash As Worksheet
Dim a(), b()
Dim i As Long, k As Long, r As Long, aa As Long, bb As Long

Set ash = ThisWorkbook.Sheets(1)
ash.Range("i2:t7").Value = "" 'обнуляем, если надо суммировать - можно закомментировать
a = ash.Range("A2:e65500").Value 'база данных всего, вместо 65500 можно переменную
b = ash.Range("g1:t7").Value 'база сводной - что ищем и куда грузим
aa = UBound(a)
bb = UBound(b)

For k = 1 To 12
    For r = 2 To bb
        For i = 1 To aa
        If a(i, 1) = b(1, k + 2) And a(i, 2) = b(r, 1) And a(i, 3) = b(r, 2) Then b(r, k + 2) = b(r, k + 2) + a(i, 5)
        Next
    Next
Next

ash.Range("g1:t7") = b

'Debug.Print Timer - tm 'это я время считал
End Sub
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 24.07.2010 в 20:55.
Hugo121 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите оптимизировать код. kievlyanin Microsoft Office Excel 3 22.05.2009 18:20
помогите оптимизировать! kievlyanin Microsoft Office Excel 11 28.04.2009 14:19
Помогите оптимизировать процедуру Cold Went Компоненты Delphi 4 29.04.2008 15:11
Помогите оптимизировать! Altera Общие вопросы Delphi 6 25.03.2008 20:09
помогите оптимизировать процедуру _XspeC_ Общие вопросы Delphi 12 08.04.2007 02:05