Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Скорость работы цикла/Find - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: китин, _Boroda_  
Скорость работы цикла/Find
AVI Дата: Суббота, 06.10.2018, 05:17 | Сообщение № 1
Группа: Проверенные
Ранг: Ветеран
Сообщений: 523
Репутация: 17 ±
Замечаний: 0% ±

Excel 2016
Добрый день!
Меня преследует гигантомания
У меня есть две массива с данными.
В примере в первом массиве 30 строк во втором 152. И те данные, что в первом (столбец С) Сравниваются с теми, что во втором и выводятся соответсвующие значения
[vba]
Код
Sub cvbn()
    ar = Cells(Rows.Count, "C").End(xlUp).Row
    For i = 2 To ar
        Set FCell = Columns("I:I").Find(Cells(i, "C"))
        If Not FCell Is Nothing Then
            Cells(i, "D") = FCell.Offset(0, 1)
            Cells(i, "E") = FCell.Offset(0, 2)
            Cells(i, "F") = FCell.Offset(0, 3)
        End If
     Next i
End Sub
[/vba]
Все здорово, пока не запускается код на полном файле, где в первом массиве 700 000 строк, а во втором 15 000.
Раньше, когда я делал все руками: искал эти совпадения ВПР'ом, Формула работала минут 20.
Сначала я запустил все циклом и ощутил всю тягость на моем i7 и наглухо зависший эксель пришлось тупо отрубить. Решил попробовать через find: стало все получше, даже файл не завис, и половину обработал, но опять же процесс был существенно более долгим, чем формульная впр. Как можно ускорить обработку таких массивов?
К сообщению приложен файл: 7358440.xlsm (18.0 Kb)
 
Ответить
СообщениеДобрый день!
Меня преследует гигантомания
У меня есть две массива с данными.
В примере в первом массиве 30 строк во втором 152. И те данные, что в первом (столбец С) Сравниваются с теми, что во втором и выводятся соответсвующие значения
[vba]
Код
Sub cvbn()
    ar = Cells(Rows.Count, "C").End(xlUp).Row
    For i = 2 To ar
        Set FCell = Columns("I:I").Find(Cells(i, "C"))
        If Not FCell Is Nothing Then
            Cells(i, "D") = FCell.Offset(0, 1)
            Cells(i, "E") = FCell.Offset(0, 2)
            Cells(i, "F") = FCell.Offset(0, 3)
        End If
     Next i
End Sub
[/vba]
Все здорово, пока не запускается код на полном файле, где в первом массиве 700 000 строк, а во втором 15 000.
Раньше, когда я делал все руками: искал эти совпадения ВПР'ом, Формула работала минут 20.
Сначала я запустил все циклом и ощутил всю тягость на моем i7 и наглухо зависший эксель пришлось тупо отрубить. Решил попробовать через find: стало все получше, даже файл не завис, и половину обработал, но опять же процесс был существенно более долгим, чем формульная впр. Как можно ускорить обработку таких массивов?

Автор - AVI
Дата добавления - 06.10.2018 в 05:17
Pelena Дата: Суббота, 06.10.2018, 08:26 | Сообщение № 2
Группа: Админы
Ранг: Местный житель
Сообщений: 19405
Репутация: 4555 ±
Замечаний: ±

Excel 365 & Mac Excel
Здравствуйте.
Попробуйте на массивах сделать. Должно быть быстрее
[vba]
Код
Sub cvbn()
    Dim x1, x2
    Application.ScreenUpdating = False
    ar1 = Cells(Rows.Count, "C").End(xlUp).Row
    x1 = Range("C2:F" & ar1).Value
    ar2 = Cells(Rows.Count, "I").End(xlUp).Row
    x2 = Range("I2:L" & ar2).Value
    For i = 1 To UBound(x1)
        For j = 1 To UBound(x2)
            If x1(i, 1) = x2(j, 1) Then
                x1(i, 2) = x2(j, 2)
                x1(i, 3) = x2(j, 3)
                x1(i, 4) = x2(j, 4)
                Exit For
            End If
        Next j
    Next i
    Range("C2:F" & ar1) = x1
    Application.ScreenUpdating = True
End Sub
[/vba]
К сообщению приложен файл: 7185668.xlsm (19.0 Kb)


"Черт возьми, Холмс! Но как??!!"
Ю-money 41001765434816
 
Ответить
СообщениеЗдравствуйте.
Попробуйте на массивах сделать. Должно быть быстрее
[vba]
Код
Sub cvbn()
    Dim x1, x2
    Application.ScreenUpdating = False
    ar1 = Cells(Rows.Count, "C").End(xlUp).Row
    x1 = Range("C2:F" & ar1).Value
    ar2 = Cells(Rows.Count, "I").End(xlUp).Row
    x2 = Range("I2:L" & ar2).Value
    For i = 1 To UBound(x1)
        For j = 1 To UBound(x2)
            If x1(i, 1) = x2(j, 1) Then
                x1(i, 2) = x2(j, 2)
                x1(i, 3) = x2(j, 3)
                x1(i, 4) = x2(j, 4)
                Exit For
            End If
        Next j
    Next i
    Range("C2:F" & ar1) = x1
    Application.ScreenUpdating = True
End Sub
[/vba]

Автор - Pelena
Дата добавления - 06.10.2018 в 08:26
_Boroda_ Дата: Суббота, 06.10.2018, 16:49 | Сообщение № 3
Группа: Админы
Ранг: Местный житель
Сообщений: 16718
Репутация: 6505 ±
Замечаний: ±

2003; 2007; 2010; 2013 RUS
А я бы на словаре сделал
[vba]
Код
Sub tt()
    Application.ScreenUpdating = 0
    Application.Calculation = 3
    r0_ = 2 '
    n1_ = Cells(Rows.Count, 3).End(3).Row - r0_ + 1
    n2_ = Cells(Rows.Count, 9).End(3).Row - r0_ + 1
    Cells(r0_, 4).Resize(n1_, 3).Clear
    ar1 = Cells(r0_, 3).Resize(n1_, 4)
    ar2 = Cells(r0_, 9).Resize(n2_, 4)
    Set slov = CreateObject("Scripting.Dictionary")
    With slov
        For i = 1 To n2_
            .Item(ar2(i, 1)) = i
        Next i
        For j = 1 To n1_
            If .exists(ar1(j, 1)) Then
                s_ = .Item(ar1(j, 1))
                For k = 2 To 4
                    ar1(j, k) = ar2(s_, k)
                Next k
            End If
        Next j
    End With
    Cells(r0_, 3).Resize(n1_, 4) = ar1
    Application.Calculation = 1
    Application.ScreenUpdating = 1
End Sub
[/vba]
К сообщению приложен файл: 45646464.xlsm (19.1 Kb)


Скажи мне, кудесник, любимец ба’гов...
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995
 
Ответить
СообщениеА я бы на словаре сделал
[vba]
Код
Sub tt()
    Application.ScreenUpdating = 0
    Application.Calculation = 3
    r0_ = 2 '
    n1_ = Cells(Rows.Count, 3).End(3).Row - r0_ + 1
    n2_ = Cells(Rows.Count, 9).End(3).Row - r0_ + 1
    Cells(r0_, 4).Resize(n1_, 3).Clear
    ar1 = Cells(r0_, 3).Resize(n1_, 4)
    ar2 = Cells(r0_, 9).Resize(n2_, 4)
    Set slov = CreateObject("Scripting.Dictionary")
    With slov
        For i = 1 To n2_
            .Item(ar2(i, 1)) = i
        Next i
        For j = 1 To n1_
            If .exists(ar1(j, 1)) Then
                s_ = .Item(ar1(j, 1))
                For k = 2 To 4
                    ar1(j, k) = ar2(s_, k)
                Next k
            End If
        Next j
    End With
    Cells(r0_, 3).Resize(n1_, 4) = ar1
    Application.Calculation = 1
    Application.ScreenUpdating = 1
End Sub
[/vba]

Автор - _Boroda_
Дата добавления - 06.10.2018 в 16:49
AVI Дата: Суббота, 06.10.2018, 19:18 | Сообщение № 4
Группа: Проверенные
Ранг: Ветеран
Сообщений: 523
Репутация: 17 ±
Замечаний: 0% ±

Excel 2016
_Boroda_, Вы простите, это, я даже не могу сказать что. Код от Pelena работа 15 минут. Ваш 12 СЕКУНД, Карл Александр.


Сообщение отредактировал AVI - Суббота, 06.10.2018, 19:18
 
Ответить
Сообщение_Boroda_, Вы простите, это, я даже не могу сказать что. Код от Pelena работа 15 минут. Ваш 12 СЕКУНД, Карл Александр.

Автор - AVI
Дата добавления - 06.10.2018 в 19:18
_Boroda_ Дата: Суббота, 06.10.2018, 19:43 | Сообщение № 5
Группа: Админы
Ранг: Местный житель
Сообщений: 16718
Репутация: 6505 ±
Замечаний: ±

2003; 2007; 2010; 2013 RUS
Ваш 12 СЕКУНД

Что-то долго он у Вас. У меня отрабатывает в среднем за 1,5 секунды (машинке уже лет 6)
Можно немного ускорить, не меняя логику
[vba]
Код
Sub tt1()
    t_ = Timer
    Application.ScreenUpdating = 0
    Application.Calculation = 3
    r0_ = 2 '
    n1_ = Cells(Rows.Count, 3).End(3).Row - r0_ + 1
    n2_ = Cells(Rows.Count, 9).End(3).Row - r0_ + 1
    ar1 = Cells(r0_, 3).Resize(n1_)
    ar11 = Cells(r0_, 9999).Resize(n1_, 3)
    ar2 = Cells(r0_, 9).Resize(n2_, 4)
    Set slov = CreateObject("Scripting.Dictionary")
    With slov
        For i = 1 To n2_
            .Item(ar2(i, 1)) = i
        Next i
        For j = 1 To n1_
            If .exists(ar1(j, 1)) Then
                s_ = .Item(ar1(j, 1))
                For k = 2 To 4
                    ar11(j, k - 1) = ar2(s_, k)
                Next k
            End If
        Next j
    End With
    Cells(r0_, 4).Resize(n1_, 3) = ar11
    Application.Calculation = 1
    Application.ScreenUpdating = 1
    MsgBox Timer - t_
End Sub
[/vba]


Скажи мне, кудесник, любимец ба’гов...
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995
 
Ответить
Сообщение
Ваш 12 СЕКУНД

Что-то долго он у Вас. У меня отрабатывает в среднем за 1,5 секунды (машинке уже лет 6)
Можно немного ускорить, не меняя логику
[vba]
Код
Sub tt1()
    t_ = Timer
    Application.ScreenUpdating = 0
    Application.Calculation = 3
    r0_ = 2 '
    n1_ = Cells(Rows.Count, 3).End(3).Row - r0_ + 1
    n2_ = Cells(Rows.Count, 9).End(3).Row - r0_ + 1
    ar1 = Cells(r0_, 3).Resize(n1_)
    ar11 = Cells(r0_, 9999).Resize(n1_, 3)
    ar2 = Cells(r0_, 9).Resize(n2_, 4)
    Set slov = CreateObject("Scripting.Dictionary")
    With slov
        For i = 1 To n2_
            .Item(ar2(i, 1)) = i
        Next i
        For j = 1 To n1_
            If .exists(ar1(j, 1)) Then
                s_ = .Item(ar1(j, 1))
                For k = 2 To 4
                    ar11(j, k - 1) = ar2(s_, k)
                Next k
            End If
        Next j
    End With
    Cells(r0_, 4).Resize(n1_, 3) = ar11
    Application.Calculation = 1
    Application.ScreenUpdating = 1
    MsgBox Timer - t_
End Sub
[/vba]

Автор - _Boroda_
Дата добавления - 06.10.2018 в 19:43
AVI Дата: Суббота, 06.10.2018, 19:52 | Сообщение № 6
Группа: Проверенные
Ранг: Ветеран
Сообщений: 523
Репутация: 17 ±
Замечаний: 0% ±

Excel 2016
_Boroda_, Так там два массивчика на 700 000 и 15000 поменял.
 
Ответить
Сообщение_Boroda_, Так там два массивчика на 700 000 и 15000 поменял.

Автор - AVI
Дата добавления - 06.10.2018 в 19:52
_Boroda_ Дата: Суббота, 06.10.2018, 20:15 | Сообщение № 7
Группа: Админы
Ранг: Местный житель
Сообщений: 16718
Репутация: 6505 ±
Замечаний: ±

2003; 2007; 2010; 2013 RUS
Так я тоже сделал массивы на 15000 и 700000. Ну ладно, не принципиально

* А, ну правильно, я второй массив-то сделал из повторяющихся значений, а нужно было уникальные. Тогда словарь заполняется на все 700000 и это, конечно же, дольше. Полминуты примерно на стареньком i3
Интересно будет проверить на работе на хорошей машине. Если не забуду


Скажи мне, кудесник, любимец ба’гов...
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995
 
Ответить
СообщениеТак я тоже сделал массивы на 15000 и 700000. Ну ладно, не принципиально

* А, ну правильно, я второй массив-то сделал из повторяющихся значений, а нужно было уникальные. Тогда словарь заполняется на все 700000 и это, конечно же, дольше. Полминуты примерно на стареньком i3
Интересно будет проверить на работе на хорошей машине. Если не забуду

Автор - _Boroda_
Дата добавления - 06.10.2018 в 20:15
AVI Дата: Суббота, 06.10.2018, 20:55 | Сообщение № 8
Группа: Проверенные
Ранг: Ветеран
Сообщений: 523
Репутация: 17 ±
Замечаний: 0% ±

Excel 2016
_Boroda_, Все равно поразительно. Эко словари справляются быстро
 
Ответить
Сообщение_Boroda_, Все равно поразительно. Эко словари справляются быстро

Автор - AVI
Дата добавления - 06.10.2018 в 20:55
Pelena Дата: Суббота, 06.10.2018, 21:25 | Сообщение № 9
Группа: Админы
Ранг: Местный житель
Сообщений: 19405
Репутация: 4555 ±
Замечаний: ±

Excel 365 & Mac Excel
Код от Pelena работа 15 минут

Чёт, как-то не верится. Неужели правда так долго?


"Черт возьми, Холмс! Но как??!!"
Ю-money 41001765434816
 
Ответить
Сообщение
Код от Pelena работа 15 минут

Чёт, как-то не верится. Неужели правда так долго?

Автор - Pelena
Дата добавления - 06.10.2018 в 21:25
AVI Дата: Суббота, 06.10.2018, 21:30 | Сообщение № 10
Группа: Проверенные
Ранг: Ветеран
Сообщений: 523
Репутация: 17 ±
Замечаний: 0% ±

Excel 2016
Pelena, Да, я думал, что это вполне нормально, учитывая объем, пока не пришел _Boroda_
 
Ответить
СообщениеPelena, Да, я думал, что это вполне нормально, учитывая объем, пока не пришел _Boroda_

Автор - AVI
Дата добавления - 06.10.2018 в 21:30
AVI Дата: Воскресенье, 07.10.2018, 05:51 | Сообщение № 11
Группа: Проверенные
Ранг: Ветеран
Сообщений: 523
Репутация: 17 ±
Замечаний: 0% ±

Excel 2016
Интересно будет проверить на работе на хорошей машине. Если не забуду

3,17 У меня все)

И подскажите, что за строчка добавилась во втором варианте? Если все остальное я примерно понял, то эта строчка. Куда-то на 9999 столбец что-то заливается, но там ничего нет...


Сообщение отредактировал AVI - Воскресенье, 07.10.2018, 06:36
 
Ответить
Сообщение
Интересно будет проверить на работе на хорошей машине. Если не забуду

3,17 У меня все)

И подскажите, что за строчка добавилась во втором варианте? Если все остальное я примерно понял, то эта строчка. Куда-то на 9999 столбец что-то заливается, но там ничего нет...

Автор - AVI
Дата добавления - 07.10.2018 в 05:51
_Boroda_ Дата: Воскресенье, 07.10.2018, 07:13 | Сообщение № 12
Группа: Админы
Ранг: Местный житель
Сообщений: 16718
Репутация: 6505 ±
Замечаний: ±

2003; 2007; 2010; 2013 RUS
Не заливается, а оттуда забирается пустой массив. Чтобы не стирать столбцы D:F. Берем пустой массив из пустых ячеек далеко сбоку справа, заполняем его по алгоритму и вставляем в D:F

3,17 - это что? Время вместо 12 секунд?


Скажи мне, кудесник, любимец ба’гов...
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995
 
Ответить
СообщениеНе заливается, а оттуда забирается пустой массив. Чтобы не стирать столбцы D:F. Берем пустой массив из пустых ячеек далеко сбоку справа, заполняем его по алгоритму и вставляем в D:F

3,17 - это что? Время вместо 12 секунд?

Автор - _Boroda_
Дата добавления - 07.10.2018 в 07:13
AVI Дата: Воскресенье, 07.10.2018, 08:42 | Сообщение № 13
Группа: Проверенные
Ранг: Ветеран
Сообщений: 523
Репутация: 17 ±
Замечаний: 0% ±

Excel 2016
_Boroda_, Да, я не знаю почему. Когда первый раз прогонял было 12. Потом 8. Щас 3,17. Я не знаю почему
 
Ответить
Сообщение_Boroda_, Да, я не знаю почему. Когда первый раз прогонял было 12. Потом 8. Щас 3,17. Я не знаю почему

Автор - AVI
Дата добавления - 07.10.2018 в 08:42
alex77755 Дата: Воскресенье, 07.10.2018, 09:57 | Сообщение № 14
Группа: Проверенные
Ранг: Обитатель
Сообщений: 362
Репутация: 64 ±
Замечаний: 0% ±

Цитата
[vba]
Код
ar11 = Cells(r0_, 9999).Resize(n1_, 3)
[/vba]

Цитата
а оттуда забирается пустой массив.

А не проще ли не забирать массив с листа, а просто создать его
[vba]
Код
Dim arr()
ReDim arr(r0_ To n1_, 3)
[/vba]


Могу помочь в VB6, VBA
Alex77755@mail.ru
 
Ответить
Сообщение
Цитата
[vba]
Код
ar11 = Cells(r0_, 9999).Resize(n1_, 3)
[/vba]

Цитата
а оттуда забирается пустой массив.

А не проще ли не забирать массив с листа, а просто создать его
[vba]
Код
Dim arr()
ReDim arr(r0_ To n1_, 3)
[/vba]

Автор - alex77755
Дата добавления - 07.10.2018 в 09:57
_Boroda_ Дата: Воскресенье, 07.10.2018, 11:42 | Сообщение № 15
Группа: Админы
Ранг: Местный житель
Сообщений: 16718
Репутация: 6505 ±
Замечаний: ±

2003; 2007; 2010; 2013 RUS
Проще, но дольше немного. Я проверял, в среднем на 0,1 секунды


Скажи мне, кудесник, любимец ба’гов...
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995
 
Ответить
СообщениеПроще, но дольше немного. Я проверял, в среднем на 0,1 секунды

Автор - _Boroda_
Дата добавления - 07.10.2018 в 11:42
boa Дата: Понедельник, 08.10.2018, 09:00 | Сообщение № 16
Группа: Друзья
Ранг: Ветеран
Сообщений: 559
Репутация: 167 ±
Замечаний: 0% ±

365
Добрый день,
в своей работе данный макрос использую для поиска по списку
"Словарь" - это то, что ищем, в вашем случае это список из колонки "с"


 
Ответить
СообщениеДобрый день,
в своей работе данный макрос использую для поиска по списку
"Словарь" - это то, что ищем, в вашем случае это список из колонки "с"

Автор - boa
Дата добавления - 08.10.2018 в 09:00
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!