|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
добрый день вот настряпал цикл на проверку и замену пустых значений в рабочем диапазоне на 0 но цикл отрабатывает сравнительно долго(таблица 58 столбцов и 5800 строк): Set MyWo = DAOEx.Workbooks.Open("Workbook_sourse") Slist = "list_sourse" Frow = MyWo.Sheets(Slist).UsedRange.Row Fcolumn = MyWo.Sheets(Slist).UsedRange.Column Lrow = MyWo.Sheets(Slist).Cells(Frow, Fcolumn).End(xlDown).Row Lcolumn = MyWo.Sheets(Slist).Cells(Frow, Fcolumn).End(xlEnd).Column For y = Fcolumn To Lcolumn For i = Frow To Lrow If MyWo.Sheets(Slist).Cells(i, y).Value = Empty Then MyWo.Sheets(Slist).Cells(i, y) = 0 Next i Next y с оптимизацией как то напряг, в голову приходит только метод с Find, но очень сомневаюсь что он будет работать быстрее помогите плз) ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2014, 14:43 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
l-freemanв голову приходит только метод с Find, но очень сомневаюсь что он будет работать быстрее помогите плз) А Вы попробовали? А долго это сколько? Сколько по времени он меняет значения, если просто Ctrl+H? Можно еще попробовать прогонять через: Код: vbnet 1. 2. 3. 4. 5.
Этот перебор должен быстрее работать. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2014, 15:54 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Maxim12345678Этот перебор должен быстрее работатьВ общем-то вряд ли, т.к. львиную долю времени забирает именно обращение к каждой ячейке. А как это будет происходить по большому счету в данном случае неважно. Выигрыш в скорости будет минимален. А вот если проходить по массиву, а к ячейкам обращать исключительно по необходимости - здесь уже можно выиграть скорость. А если при этом не сразу менять, а сначала в отдельный объект через Union - вообще быстро будет: Код: vbnet 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.
P.S. Заменил Ваше чудное определение последней строки и столбца. Если лист пустой или содержит лишь одну строку - получится ой как нехорошо - весь лист нулями заполнять... Почитайте на досуге: Как определить последнюю ячейку на листе через VBA? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.09.2014, 00:29 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Maxim12345678, изменил на: For Each acc In Range(Cells(Frow, Fcolumn), Cells(Lrow, Lcolumn)) If acc = Empty Then Cells(acc.Row, acc.Column) = 0 Next acc вот только теперь не знаю как записать в ячейку на шаге acc нужное мне значения Cells(acc.Row, acc.Column) - не работает, та в принципе думаю и не должно было бы) ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2014, 16:49 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
The_Prist, спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2014, 16:53 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
l-freemanCells(acc.Row, acc.Column) - не работает, та в принципе думаю и не должно было бы) Cells(acc.Row, acc.Column).value - работает, но как сказал тов. Прист, выигрыш во времени не заметен а код тов.Приста конечно для меня, ламера, сложноват он конечно работает, но я не понимаю некоторых моментов ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2014, 17:40 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
l-freeman, Код: vbnet 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2014, 19:38 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Прошу прощения, что вмешиваюсь. А вам не кажется, что простая замена будет работать быстрее приведенных алгоритмов? Код: vbnet 1. 2. 3. 4. 5. 6. 7.
А специальная вставка будет еще быстрее работать? Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Книгу для теста прилагаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2014, 01:16 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Dmitri Krizhanovski, 1. Замена не заменит пустые ячейки, в которых пусто(Empty), а не строка нулевой длины. И работает нестабильно. Плюс, если в ячейке нечто вроде формулы: ="", то замена опять не сработает. 2. Ячейки со строкой нулевой длины останутся "пустыми", т.е. там так и останется строка нулевой длины. Плюс при Вашем подходе к спец.вставке есть большой шанс, что поедут формулы. Поэтому вставлять тогда уж надо Paste:=xlPasteValues. Формулы все равно вряд ли нужны, т.к. лист готовят к выгрузке в БД. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2014, 12:22 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Dmitri Krizhanovski, Не пойму зачем гонять объекты cells и проверять их значения. Ведь можно Код: vbnet 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.04.2015, 21:01 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Доброе время суток По мотивам Bobgos , естественно пологая, что реальные данные по структуре соответствуют примеру. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2015, 01:55 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
l-freeman, скачал книгу, выложенную Dmitri Krizhanovski для экспериментов. запустил ваш код, поправленный до такого вида: Код: vbnet 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.
время работы на моем стареньком компьютере - 20.6 секунды в выложенном примере задействован диапазон в 84 * 5708 = 479472 Чтобы только добраться до value с целью сравнения вы сначала 479472 говорите: (на каждом шаге!!!) Эксель, в книге MyWo найди лист с именем slist и на нем отыщи клетку с координатами i,y У вас просто нет права рассчитывать на быстрое выполнение. Хотите скорости - научитесь выражаться короче. ваша попытка Код: vbnet 1. 2. 3.
не просто неудачна, если она работает, то работает у вас случайно. Т.к. отношение имеет не к тому листу, который вы slist назвали, а к тому, в который сейчас глазками смотрите. При этом это хуже первоначального варианта. Там вы хоть точно знаете в какой книге искать. А здесь вам не понравилось, что excel слишком быстро считает и вы решили наказать его за это, приказывая строкой Cells(acc.Row, acc.Column) = 0 следующее. Эксель, всякий раз, когда найдешь в цикле обработки пустую клетку, определи, в какой книге находится текущий лист, который я вижу глазами. На этом листе найди клетку с координатами такими же, какие у текущей клетки в цикле обработки (мы помним - откуда взятой - взятой из книги MyWo с листа slist), и в эту клетку (той книги, страницу которой я вижу глазами) запиши ноль. Вы какого уроста ожидаете, если просите сделать работы больше, чем в своем первоначальном варианте? При этом не просто больше, а близко не то-же самое по смыслу. Это издевательство какое-то, ничем не прикрытое. Толстый троллинг безответного экселя. Начинаем сначала. Хотите скорости - научитесь разговаривать коротко. Складываем "по складам": клетки занятого диапазона листа slist книги MyWo == MyWo.Sheets(Slist).UsedRange Для каждой клетки == For Each rr Все вместе слитно: == For Each rr In MyWo.Sheets(Slist).UsedRange Вот код, который должен у вас получиться. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Этот вариант у меня отрабатывает за 7 секунд против первоначальных 20.6 Еще немного (около секунды на выложенном примере) можно сэкономить при выключении автоматического пересчета и обновления экрана. В данном случае немного, т.к. доля обновляемых клеток в примере невелика. Вариант, который предложил Bobgos отработает быстрее. Но на больших объемах данных им следует пользоваться с некоторой осмотрительностью. И помнить, что он критичнее по отношению к отключению пересчета и обновлению экрана, т.к. обновляется весь массив данных, а не некоторые клетки (предположительно - меньшинство). такой вариант Код: vbnet 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.
на примере от Dmitri Krizhanovski у меня отработал за 1.6 сек. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2015, 02:12 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
booby, вау!!! все по полочкам. Красавец! 1. интересно мнение экспертов - если перед вводом в массив диапазона еще и отсортировать диапазон? например: поможет или навредит экселевская сортировка листа по столбцу (а лучше расширенная по... скажем 3-м столбцам), в котором опять же экселевской функцией (не vba) будет найдено максимальное количество пустых значений. При этом если будет 10000 строк и всего 10 пустых значений то не придется перебирать все 10000. 2. подозрение есть, что манипуляции с .screenupdating и .Calculation значительно меньше влияют на скорость в последнем Варианте -1,6сек.. Пересчет в обоих случаях производится один раз при включении .Calculation или при присвоению диапазону значений массива v. Поправьте пожалуйста, если ошибаюсь. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2015, 21:22 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Bobgos1. интересно мнение экспертов - если перед вводом в массив диапазона еще и отсортировать диапазон? ... При этом если будет 10000 строк и всего 10 пустых значений то не придется перебирать все 10000. Конечно, если отсортировать диапазон так, чтобы пустые значения образовали как можно меньшее количество областей, то выгоднее будет пробежаться по областям: Код: vbnet 1. 2. 3. 4.
Однако при слишком большом числе областей (как в приложенном файле) метод SpecialCells дает сбой и возвращает весь диапазон, и весь он обнуляется :( Так по крайней мере в Excel 2007, может в более поздних поправили. Bobgos2. подозрение есть, что манипуляции с .screenupdating и .Calculation значительно меньше влияют на скорость в последнем Варианте -1,6сек.. Пересчет в обоих случаях производится один раз при включении .Calculation или при присвоению диапазону значений массива v. Поправьте пожалуйста, если ошибаюсь.Верно. Есть еще способ с вычислением формулы листа: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9.
По моим замерам, скорость такая же, как при работе с массивом - 2,2с. Если в диапазоне могут быть нечисловые значения, придется использовать более сложную формулу Код: vbnet 1.
и результат 2,5-2,6с. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.04.2015, 11:53 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
А самый быстрый способ - PasteSpecial, но не как предложил Dmitri Krizhanovski, а скопировать ячейку с 0 и задать операцию сложения. При этом нечисловые значения игнорируются, числовые, очевидно, не меняются, к формулам, возвращающим число, дописывается "+0", пустые становятся 0: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Мой результат 0,28с . ... |
|||
:
Нравится:
Не нравится:
|
|||
17.04.2015, 12:11 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
КазанскийА самый быстрый способ - PasteSpecial, но не как предложил Dmitri Krizhanovski, а скопировать ячейку с 0 и задать операцию сложения. При этом нечисловые значения игнорируются, числовые, очевидно, не меняются, к формулам, возвращающим число, дописывается "+0", пустые становятся 0: Мой результат 0,28с . the best ... |
|||
:
Нравится:
Не нравится:
|
|||
17.04.2015, 20:52 |
|
оптимизация замены пустых ячеек на 0 (Excel)
|
|||
---|---|---|---|
#18+
Bobgos, авторthe best - опять антоновка? ( Сидит Ньютон под деревом. На Ньютона падает яблоко. Вдруг, разверзлась Земля, из земли выперла Жопа, и яблоко исчезло в недрах ея. - Что это было? - отдает в пространство вопрос Ньютон. Вдруг, опять разверзлась Земля, из Земли выперла Жопа, и прозвучало: - Антоновка! ) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.04.2015, 01:43 |
|
|
start [/forum/topic.php?fid=61&msg=38741568&tid=2173531]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
32ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 153ms |
0 / 0 |