Здравствуйте! Подскажите, пожалуйста, как решить следующую задачу: На Листе 1 есть большая таблица (количество строк около 16000, иногда чуть меньше, иногда больше). Нужно скопировать строки на 3 разных листа, в зависимости от данных в столбцах DA и EE. Но строки должны быть скопированы на листы не полностью, а только значения из некоторых столбцов для данных строк. Мой код такой: [vba]
Код
Sub Perenos()
Dim rw As Long 'счетчик для номера строки Dim i, j, t As Long 'счетчики Dim LastRow1 As Long 'переменная для номера последней заполненной строки Dim TD1 As Data
For rw = 3 To LastRow1 Step 1 'c 3-ей строки т.к. выше идет шапка таблицы If ([лист1].Cells(rw, "DA") = TD1) Then 'значение ячейки из столбца DA равно TD1 If Not IsError([лист1].Cells(rw, "EE")) Then 'и если значение ячейки из столбца EE не #Н/Д Vstavka_na_perere i, rw 'вставить на лист 6 i = i + 1 Else Vstavka_na_novii j, rw 'вставить на лист... j = j + 1 End If End If If ([лист1].Cells(rw, "DA") <> TD1) Then Vstavka_na_neperere t, rw t = t + 1 End If Next
Похоже выглядят процедуры Vstavka_na_novii и Vstavka_na_neperere
Понимаю, что выглядит ужасно. Такой код работает бесконечно долго, т.к. на обработку одной строки уходит 0,4 сек VBA раньше не занималась, не могу решить уже долгое время эту задачу((((. Пожалуйста, подскажите, как сделать Скорее всего, с помощью функции Find, но не могу понять как [moder]Код следует оформлять тегами (кнопка #). На первый раз исправила[/moder]
Здравствуйте! Подскажите, пожалуйста, как решить следующую задачу: На Листе 1 есть большая таблица (количество строк около 16000, иногда чуть меньше, иногда больше). Нужно скопировать строки на 3 разных листа, в зависимости от данных в столбцах DA и EE. Но строки должны быть скопированы на листы не полностью, а только значения из некоторых столбцов для данных строк. Мой код такой: [vba]
Код
Sub Perenos()
Dim rw As Long 'счетчик для номера строки Dim i, j, t As Long 'счетчики Dim LastRow1 As Long 'переменная для номера последней заполненной строки Dim TD1 As Data
For rw = 3 To LastRow1 Step 1 'c 3-ей строки т.к. выше идет шапка таблицы If ([лист1].Cells(rw, "DA") = TD1) Then 'значение ячейки из столбца DA равно TD1 If Not IsError([лист1].Cells(rw, "EE")) Then 'и если значение ячейки из столбца EE не #Н/Д Vstavka_na_perere i, rw 'вставить на лист 6 i = i + 1 Else Vstavka_na_novii j, rw 'вставить на лист... j = j + 1 End If End If If ([лист1].Cells(rw, "DA") <> TD1) Then Vstavka_na_neperere t, rw t = t + 1 End If Next
Похоже выглядят процедуры Vstavka_na_novii и Vstavka_na_neperere
Понимаю, что выглядит ужасно. Такой код работает бесконечно долго, т.к. на обработку одной строки уходит 0,4 сек VBA раньше не занималась, не могу решить уже долгое время эту задачу((((. Пожалуйста, подскажите, как сделать Скорее всего, с помощью функции Find, но не могу понять как [moder]Код следует оформлять тегами (кнопка #). На первый раз исправила[/moder]AnniS
Сообщение отредактировал Pelena - Среда, 27.01.2016, 22:32
AnniS, Тяжело понять что имено делает Ваш код. Посоветую загрузить масив данных в память и работать уже с ними так же как с листом Вот часть переделаного кода [vba]
For rw = 3 To LastRow1 Step 1 'c 3-ей строки т.к. выше идет шапка таблицы If (ArrDA(rw, 1) = TD1) Then 'значение ячейки из столбца DA равно TD1 If Not IsError(ArrEE(rw, 1)) Then 'и если значение ячейки из столбца EE не #Н/Д Vstavka_na_perere i, rw 'вставить на лист 6 i = i + 1 Else Vstavka_na_novii j, rw 'вставить на лист... j = j + 1 End If Else Vstavka_na_neperere t, rw t = t + 1 End If Next
[/vba]
AnniS, Тяжело понять что имено делает Ваш код. Посоветую загрузить масив данных в память и работать уже с ними так же как с листом Вот часть переделаного кода [vba]
For rw = 3 To LastRow1 Step 1 'c 3-ей строки т.к. выше идет шапка таблицы If (ArrDA(rw, 1) = TD1) Then 'значение ячейки из столбца DA равно TD1 If Not IsError(ArrEE(rw, 1)) Then 'и если значение ячейки из столбца EE не #Н/Д Vstavka_na_perere i, rw 'вставить на лист 6 i = i + 1 Else Vstavka_na_novii j, rw 'вставить на лист... j = j + 1 End If Else Vstavka_na_neperere t, rw t = t + 1 End If Next
Анна, еще такое дело - если Вы не планируете обращаться к макросу Vstavka_na_perere и ему подобным множество раз из разных частей кода (да даже если и планируете), то код лучше не выносить в отдельный макрос или функцию - это увеличивает время работы. Да, сам код может получиться значительно длиннее, но длина кода никак не влияет на скорость его работы (при прочих равных условиях). Поэтому я бы посоветовал все телодвижения делать внутри одного модуля. Сразу оговорюсь, что это касается только макросов с большим количеством обращений к другим макросам (функциям). В противном случае наличие таких выходов из макроса особой рояли не играет. Короче - если часто выходим из одного макроса в другой, то плохо, если не часто, то ничего страшного. И абсолютно согласен с Михаилом - первоначальные данные лучше загрузить в виртуальный массив. Кстати, можно пойти дальше - полученные в результате расчетов данные тоже грузить в массивы, а затем одним махом всё вытащить на лист. Львиная доля времени уходит именно на работу с данными на листах - с листа в макрос и из макроса на лист. Поэтому, по возможности, нужно как можно реже обращаться к реальным данным на листе. Опять же, это не очень актуально для небольших объемов - какая Вам разница, будет работать макрос 0,01 секунды или 0,0001 секунды? Вы все равно не заметите. Но это все теория, а вот практически Вам помочь мы сможем только при наличии Вашего файла и, желательно, объяснений что-откуда-куда-почему-зачем.
Анна, еще такое дело - если Вы не планируете обращаться к макросу Vstavka_na_perere и ему подобным множество раз из разных частей кода (да даже если и планируете), то код лучше не выносить в отдельный макрос или функцию - это увеличивает время работы. Да, сам код может получиться значительно длиннее, но длина кода никак не влияет на скорость его работы (при прочих равных условиях). Поэтому я бы посоветовал все телодвижения делать внутри одного модуля. Сразу оговорюсь, что это касается только макросов с большим количеством обращений к другим макросам (функциям). В противном случае наличие таких выходов из макроса особой рояли не играет. Короче - если часто выходим из одного макроса в другой, то плохо, если не часто, то ничего страшного. И абсолютно согласен с Михаилом - первоначальные данные лучше загрузить в виртуальный массив. Кстати, можно пойти дальше - полученные в результате расчетов данные тоже грузить в массивы, а затем одним махом всё вытащить на лист. Львиная доля времени уходит именно на работу с данными на листах - с листа в макрос и из макроса на лист. Поэтому, по возможности, нужно как можно реже обращаться к реальным данным на листе. Опять же, это не очень актуально для небольших объемов - какая Вам разница, будет работать макрос 0,01 секунды или 0,0001 секунды? Вы все равно не заметите. Но это все теория, а вот практически Вам помочь мы сможем только при наличии Вашего файла и, желательно, объяснений что-откуда-куда-почему-зачем._Boroda_
Спасибо большое!!! Все Ваши советы мне очень помогли! Сделала, как рекомендовал miver. Исходные данные заношу в массивы, работаю с ними и готовый результат уже переношу на лист Excel. И по совету Boroda процедуры Vstavka_na_perere и т.п. убрала и все перенесла в основной код. Все отлично работает. Еще раз спасибо большое!!!
Спасибо большое!!! Все Ваши советы мне очень помогли! Сделала, как рекомендовал miver. Исходные данные заношу в массивы, работаю с ними и готовый результат уже переношу на лист Excel. И по совету Boroda процедуры Vstavka_na_perere и т.п. убрала и все перенесла в основной код. Все отлично работает. Еще раз спасибо большое!!!AnniS