Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как оптимизировать данный код? Копирование данных / 25 сообщений из 53, страница 1 из 3
14.07.2010, 10:45
    #36740042
snap2111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Добрый день, подскажите пожалуйста как оптимизировать данный код. Т.к. на листе "222" 12 000 записей а на листе СводМи 800. Если делать так, то все происходит очень медленно...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
Sub Месяц2()
    Dim mStr As String 'искомая стр
    Dim mRowNum As Long 'номер стр
    Dim mRowCnt As Long 'число стр
    Dim mColCnt As Long 'число колонок
        Dim qs As Long
    mCopNum =  0 
    ActiveWorkbook.Sheets("222").Activate
    mRowCnt = ActiveCell.SpecialCells(xlLastCell).Row
    mColCnt = ActiveCell.SpecialCells(xlLastCell).Column
    mColCnt = mColCnt -  2 
    For qs =  2  To mRowCnt
            ActiveWorkbook.Sheets("222").Activate
            mStr = Cells(qs,  1 ).Value
            Worksheets("СводМИ").Activate
            Cells( 6 ,  1 ).Activate
            
                For mRowNum =  2  To mRowCnt
                If Worksheets("СводМи").Cells(mRowNum,  1 ).Value = mStr Then
                   Worksheets("СводМи").Range(Cells(mRowNum, mColCnt - (mColCnt -  3 )).Address & ":" & Cells(mRowNum, mColCnt -  2 ).Address).Copy
                    Worksheets("222").Range(Cells(qs,  7 ).Address).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
                    :=False, Transpose:=False
                End If
            Next mRowNum
    Next qs
End Sub
...
Рейтинг: 0 / 0
14.07.2010, 10:46
    #36740051
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
snap2111,

Избавиться от Activate прежде всего
...
Рейтинг: 0 / 0
14.07.2010, 11:05
    #36740117
Shamanus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
Sub Месяц2()
    Dim mStr As String 'искомая стр
    Dim mRowNum As Long 'номер стр
    Dim mRowCnt As Long 'число стр
    Dim mColCnt As Long 'число колонок
        Dim qs As Long
    mCopNum =  0 
    ActiveWorkbook.Sheets("222").Activate ' выделить лист - ну положим можно оставить для подсчета строк
 ' хотя можно посчитать строки не активируя лист
    mRowCnt = ActiveCell.SpecialCells(xlLastCell).Row ' подсчет строк - на быстродействие не влияет
    mColCnt = ActiveCell.SpecialCells(xlLastCell).Column ' - также
    mColCnt = mColCnt -  2   ' - тоже не влияет но почему не вставить в код, ну Вам виднее

    For qs =  2  To mRowCnt
            ActiveWorkbook.Sheets("222").Activate ' активация листа - зачем теперь выделять лист 
'  если нужно всего лишь получить с него ячейку. Адрес ячейки нужно всего лишь указать с индексом листа
            mStr = Cells(qs,  1 ).Value ' иными словами тут  -  mStr =  ActiveWorkbook.Sheets("222").Cells(qs, 1).Value
' тем более это Вы уже делаете в 19 строке своего кода
            Worksheets("СводМИ").Activate  ' не нужный текст
            Cells( 6 ,  1 ).Activate  ' не нужный текст
            
                For mRowNum =  2  To mRowCnt
                If Worksheets("СводМи").Cells(mRowNum,  1 ).Value = mStr Then
                   Worksheets("СводМи").Range(Cells(mRowNum, mColCnt - (mColCnt -  3 )).Address & ":" & Cells(mRowNum, mColCnt -  2 ).Address).Copy
                    Worksheets("222").Range(Cells(qs,  7 ).Address).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
                    :=False, Transpose:=False
                End If
            Next mRowNum
    Next qs
End Sub

кстати это не вникая в суть задачи, возможно еще можно оптимизировать
- не пошагово выполнять копирование, а целиком
- процесс копирования диапазона не через копи пасту, а присвоение диапазонов

кстати это не вникая в суть задачи, возможно реализация будет быстрее за счет того, что диапа
...
Рейтинг: 0 / 0
14.07.2010, 11:14
    #36740154
Shamanus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
В конце хотел добавить про кошерный
Код: plaintext
Application.ScreenUpdating= False
который всегда надо помнить
...
Рейтинг: 0 / 0
14.07.2010, 11:36
    #36740242
snap2111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Shamanus,

а его вставлять в какой части кода?
...
Рейтинг: 0 / 0
14.07.2010, 11:41
    #36740263
Shamanus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
snap2111,

ну если Вам лениво гуглить

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
' начало кода
Application.ScreenUpdating = False
............
............
............
' конец кода
Application.ScreenUpdating = True

прогнал Ваш код с моей оптимизацией по 1500 записям
Ваш код 55 секунд
Мой код 32 секунды

ну т.е. если учесть процессорную погрешность и особенность версии ОС и Office можно смело сказать почти в 2 раза
...
Рейтинг: 0 / 0
14.07.2010, 11:52
    #36740315
snap2111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Shamanus,

После оптимизации 2 500 записей обработал за 9 минут.
С учетом того что целевой лист содержит 12 000, а откуда копируем 5800 шт.
...
Рейтинг: 0 / 0
14.07.2010, 12:01
    #36740339
Hugo121
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
snap2111,
ещё быстрее было бы - перекинуть данные в массивы и работать с ними.
Не вникая в задачу - или преобразовать один из массивов, или создать третий, а в конце выгрузить на лист.
...
Рейтинг: 0 / 0
14.07.2010, 12:49
    #36740454
Shamanus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
snap2111,

ну во первых 2500 записей это прогон 6 250 000 циклов сравнения
исходя из Вашего кода и времени 11,5 тыс итераций в секунду....

ммм...маловато... у меня получается 1500 записей за 32 секунды это 2 250 000 циклов или 70 тыс итераций в секунду

даже исходя из погрешностей и кеширования все равно маловато

если скинете исходные данные могу покопаться в Вашем коде
...
Рейтинг: 0 / 0
14.07.2010, 12:53
    #36740461
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Shamanusесли скинете исходные данные могу покопаться в Вашем коде

а также желательно скинуть железо, на котором это обрабатывается
...
Рейтинг: 0 / 0
14.07.2010, 12:56
    #36740475
Игорь Горбонос
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
> Автор: Shocker.Pro
> а также желательно скинуть железо, на котором это обрабатывается

Да не обязательно :)
Мне кажется ТС не договаривает что ему нужно в действительности и предлагает оптимизировать его видиние алгоритма. И не
желает озвучить полную задачу. А насчет кардинальных ускорений уже предлагали, но ТС продолжает гнуть свою "правильную"
линию партии :)

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
14.07.2010, 13:12
    #36740530
snap2111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Сейчас все скину )
...
Рейтинг: 0 / 0
14.07.2010, 13:33
    #36740579
snap2111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Вот он
...
Рейтинг: 0 / 0
14.07.2010, 13:39
    #36740595
snap2111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Еще раз
...
Рейтинг: 0 / 0
14.07.2010, 14:40
    #36740763
Игорь Горбонос
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
> Автор: snap2111
> Еще раз

ВопросЫ:
Данные в столбце ID повторятся могут?
Если могут, почему перетираешь ранее найденные данные, если не могут - зачем тогда внутренний цикл по всему массиву
данных?
Почему бы не воспользоватся функцией ВПР?
Код: plaintext
=ЕСЛИ(ЕОШИБКА(ВПР($A3;СводМи!$A$ 3 :$V$ 85 ;СТОЛБЕЦ()- 1 ;ЛОЖЬ));"";ВПР($A3;СводМи!$A$ 3 :$V$ 85 ;СТОЛБЕЦ()- 1 ;ЛОЖЬ))
Размнож эту формулу на весь нужный диапазон и будет тебе счастье великое :)

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
14.07.2010, 14:43
    #36740775
Игорь Горбонос
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
> Автор: Игорь Горбонос
> Размнож эту формулу

Да формула для ячейки C3. Если нужно, подкорректировать пространство таблицы искомых данных - СводМи!$A$3:$V$85
А дальше протяни в сторону и вниз.

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
14.07.2010, 14:50
    #36740810
snap2111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Игорь Горбонос,
(ID из первой строки уникальны)
на данный момент оно так и выполняется - функцией впр, вот только я пытаюсь сделать отчет полностью автоматизированным, это один из этапов его выполнения, там потом много чего с ним делается дальше... Т.е. что бы нажать на кнопочку а оно все построило, без всяких там формул в экселе....
...
Рейтинг: 0 / 0
14.07.2010, 15:15
    #36740900
Hugo121
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
snap2111,

Для таких задач я универсальный код написал, сейчас проверил - быстро нашло 84 совпадения и скопировало данные.
Но т.к. Вам надо это в другой процесс встраивать, то ссылку не дам.
Одно могу сказать - два цикла не нужно. Хватит одного и поиска.
Т.е. цикл по одному листу(222), поиск значения mStr = Cells(qs, 1).Value на листе СводМи по первой колонке, если нашли - копируем диапазон. Тем более, если повторов быть не должно.
Можно чуть ускорить, закинув диапазон листа 222 в массив и перебирать массив.
Получится лёгкий код и живенько работать будет. Имхо.
...
Рейтинг: 0 / 0
14.07.2010, 15:17
    #36740909
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
snap2111, попробуй так. Протестировал на глаз, нужно ещё доработать. Но зато быстрее работает.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
Private Type uDataCache
    ID As Long
    RangeData As Range
End Type

Public Sub TEST_ALG()
    Dim SvodMI As Worksheet, Report As Worksheet
    
    Dim mReportCnt As Long, mSvodCnt As Long, I As Long, J As Long
    Dim SvodMICached() As uDataCache, CurrID As Long
    
    Set SvodMI = ActiveWorkbook.Worksheets("СводМИ")
    Set Report = ActiveWorkbook.Worksheets("222")
    
    mReportCnt = Report.Cells( 1 ,  1 ).SpecialCells(xlLastCell).Row  'Высота ID 12000+
    mSvodCnt =  85   'SvodMI.Cells(1, 1).SpecialCells(xlLastCell).Row 'Высота ID 85 (Но их 5500+)
    ReDim SvodMICached(mSvodCnt -  3 )
    
    Application.ScreenUpdating = False
    
    'Load Data
    For I =  3  To mSvodCnt
        SvodMICached(I -  3 ).ID = SvodMI.Cells(I,  1 ) 'ID
        Set SvodMICached(I -  3 ).RangeData = SvodMI.Range("B" & I & ":V" & I)  'Здесь подправить нужно
    Next
    
    'По всем ID
    For I =  2  To mReportCnt
        CurrID = Report.Cells(I,  1 ).Value
            
        'По всей структуре в кеше
        For J =  0  To mSvodCnt -  3 
            If SvodMICached(J).ID = CurrID Then
                Report.Range("C" & I & ":V" & I).Value = SvodMICached(J).RangeData.Value
                Exit For 'Для оптимизации
            End If
        Next
    Next

    Application.ScreenUpdating = True
End Sub
...
Рейтинг: 0 / 0
14.07.2010, 15:26
    #36740944
Игорь Горбонос
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
> Автор: snap2111
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
Option Explicit

Sub Месяц2()
    Dim mStr As String 'искомая стр
    Dim mRowNum As Long 'номер строки
    Dim mRowCnt As Long 'число строк
    Dim mColCnt As Long 'число колонок
    Dim mCopNum As Long 'номер копии
    Dim str As Variant
    Dim qs As Long
    Dim shSource As Worksheet, shDest As Worksheet
    str = Time
    Application.ScreenUpdating = False
    'qs = 4
    mCopNum =  0 
    Set shSource = ActiveWorkbook.Worksheets("СводМИ")
    Set shDest = ActiveWorkbook.Sheets("222")
    mRowCnt = shSource.Cells.SpecialCells(xlLastCell).Row
    mColCnt = shDest.Cells.SpecialCells(xlLastCell).Column

    For qs =  2  To mRowCnt
        mStr = shSource.Cells(qs,  1 ).Value
        For mRowNum =  2  To mRowCnt
            If shDest.Cells(mRowNum,  1 ).Value = mStr Then
                    With shDest
                        .Range(.Cells(qs,  3 ), .Cells(qs, mColCnt)).Value = shSource.Range(shSource.Cells(mRowNum,  2 ), 
shSource.Cells(mRowNum, mColCnt)).Value
                    End With
                 Exit For
             End If
        Next mRowNum
    Next qs
Application.ScreenUpdating = True
MsgBox Format(Time - str, "hh:mm:ss")
End Sub


Sub Месяц2_find()
    Dim mStr As String 'искомая стр
    Dim mRowNum As Long 'номер строки
    Dim mRowCnt As Long 'число строк
    Dim mColCnt As Long 'число колонок
    Dim mCopNum As Long 'номер копии
    Dim str As Variant
    Dim qs As Long

    Dim shSource As Worksheet, shDest As Worksheet, r As Range
    str = Time
    Application.ScreenUpdating = False
    'qs = 4
    mCopNum =  0 
    Set shSource = ActiveWorkbook.Worksheets("СводМИ")
    Set shDest = ActiveWorkbook.Sheets("222")
    mRowCnt = shDest.Cells.SpecialCells(xlLastCell).Row
    mColCnt = shSource.Cells.SpecialCells(xlLastCell).Column

    For qs =  2  To mRowCnt
        Set r = shSource.Range("A:A").Find(What:=shDest.Cells(qs,  1 ).Text, LookIn:=xlValues, LookAt _
        :=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase _
        :=False, SearchFormat:=False)
        If Not r Is Nothing Then
            With shDest
                .Range(.Cells(qs,  3 ), .Cells(qs, mColCnt)).Value = shSource.Range(shSource.Cells(r.Row,  2 ), 
shSource.Cells(r.Row, mColCnt)).Value
            End With
        End If
    Next qs
Application.ScreenUpdating = True
MsgBox Format(Time - str, "hh:mm:ss")
End Sub
У меня первый вариант отрабатывает на приложенном файле за 22 секунды, второй за 13 секунд

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
14.07.2010, 15:31
    #36740961
Shamanus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
не успел ответить автору.
p.s. очередное подтверждение того, что форум активнее на реальных примерах, а не на гипотетических кодах
...
Рейтинг: 0 / 0
14.07.2010, 15:33
    #36740975
Hugo121
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Sub МесяцHUGO()

Dim a()
Dim iLastrow As Long, i As Long, f As Range
Dim tm
tm = Timer
Application.ScreenUpdating = False
 iLastrow = Sheets( 2 ).Cells(Rows.Count,  1 ).End(xlUp).Row
 a = Range(Sheets( 2 ).Cells( 2 ,  1 ), Sheets( 2 ).Cells(iLastrow,  1 ))
For i = LBound(a) To UBound(a)
Set f = Sheets( 1 ).Columns( 1 ).Find(a(i,  1 ), , xlValues, xlWhole)
If Not f Is Nothing Then
Sheets( 1 ).Range(Sheets( 1 ).Cells(f.Row,  2 ), Sheets( 1 ).Cells(f.Row,  20 )).Copy Sheets( 2 ).Cells(i,  3 )
End If
Next
tm = Timer - tm
Debug.Print tm
Application.ScreenUpdating = True
End Sub

6,671875
...
Рейтинг: 0 / 0
14.07.2010, 15:34
    #36740978
Игорь Горбонос
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
> Автор: Shamanus
> не успел ответить автору.



Я забыл добавить
Код: plaintext
1.
2.
3.
4.
Application.ScreenUpdating = False
> > >    Application.Calculation = xlCalculationManual
....
> > >Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
C этими вставками первый работает 17 секунд, второй - 3(три) секунды

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
14.07.2010, 15:37
    #36740991
Shamanus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Игорь Горбонос,

правда не успел :)
у меня был вариант с сортировкой... но супротив варианта за 3 сек не попрет :)
...
Рейтинг: 0 / 0
14.07.2010, 15:40
    #36741007
Hugo121
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать данный код? Копирование данных
Shamanus,
у меня наверное комп в 10 раз слабее - 31 сек. А мой 6!
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как оптимизировать данный код? Копирование данных / 25 сообщений из 53, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]