|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Доброго времени суток, уважаемые форумчане! В макросах не силен, по статейкам в инете написал код. Смысл такой, что в таблицу сначала вставляется необходимое количество строк, затем из буфера обмена (ранее скопированного диапазона в excel) вставляется в диапазон ячеек таблицы word (выбирается таблица №3). Далее перебираются ячейки 3 столбца и при условии, что в ячейке 3 символа, копируется в буфер содержимое ячейки второго столбца, строка очищается, ячейки в строке объединяются и затем в строку вставляется ранее скопированное содержимое ячейки второго столбца, ну и для красоты ячейка затемняется. Проблема в том, что в случае, например, двухста строк код выполняется более менее быстро, а вот когда строк, например, две тысячи, код выполняется настолько долго, что через 15-20 минут, не дождавшись окончания, снимаю задачу диспетчером. Не могу понять, что можно предпринять для исправления. Код: 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.
Подскажите, пожалуйста, в чем ошибка в коде, существует ли способ ли ускорить его выполнение? Заранее спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.06.2021, 10:40 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Во-первых, тут очень много копирования в буфер. Это занимает очень много времени. По возможности, нужно избежать копирования в буфер, лучше копировать в переменную (если речь идет о значении, если, конечно, речь идет только о значении, а не о формулах, оформлении и прочем) Во-вторых, любое взаимодействие с ячейками листа тоже достаточно медленное. Поэтому, лучше минимально задействовать такое взаимодействие в цикле и активно использовать массивы, копируя и вставляя значения разом из массива / в массив. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.06.2021, 10:58 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, большое Вам спасибо за отзыв. По первому пункту понятно в каком направлении работать, а на счет второго пункта я не совсем понял, каким образом должна происходить работа с массивом, разом копировать и вставлять, если по выполнению условия в ячейке изменяется строка. Буду очень благодарен, если немного подробней объясните как это должно работать. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 07:45 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Markovich21 каким образом должна происходить работа с массивом, разом копировать и вставлять, если по выполнению условия в ячейке изменяется строка. Она изменяется, потому что там имеется зависимая формула? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 08:33 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, столкнулся с таким кейсом-нужно обработать таблицу с листа Excel через предварительное загнание её в массив, но для обработки нет необходимости загонять всю таблицу в массив- нужно только 2 столбца из 20 к примеру. Но быстрым методом копирования диапазона в массив Код: vbnet 1.
можно загнать только всю таблицу целиком в массив. Получается, чтобы заполнить массив только 2 столбцами, а не всей таблицей, нужно делать цикл по ячейкам, который медленнее, чем Range.Value и вручную их копировать в массив. Соответственно, можно ли несколько Range склеить в один массив без цикла по ячейкам? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 09:05 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
vb_sub Но быстрым методом копирования диапазона в массив можно загнать только всю таблицу целиком в массив. А указать в Range только нужные столбцы идея не приходила? типа Код: vbnet 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 09:46 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Akina, Range это непрерывный диапазон, нельзя указать крайние столбцы и исключить некоторые промежуточные из них. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 09:51 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Akina, я может что то не понимаю, но у меня word и формулы в строке нет. Изменяется строка i (объединяются ячейки и в них вставляется текстовое значение из ячейки второго столбца), если в ячейке третьего столбца 3 символа ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 10:25 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
vb_sub Akina, Range это непрерывный диапазон Это не так. Код: vbnet 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 10:27 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Markovich21 у меня word Я не заметил слона! Думаю, что все вышестоящие ответы можно вычеркнуть. Автору - надо ЯВНО указывать среду разработки, но мы, конечно, тоже хороши! ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 10:39 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, виноват, каюсь, в будущем учту замечание. И все же для word существует решение данной проблемы? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 11:27 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
С вордом всё сложнее, надо возиться и пробовать. Попробуй для начала убрать работу с буфером внутри цикла. Может это решит проблему до приемлемой скорости. ЗЫ: Лучше работать с ThisDocument вместо ActiveDocument ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 14:19 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, спасибо за ответы с наводками. Использовал переменную внутри цикла вместо буфера, скорость выполнения кода действительно возрасла. Теперь хотя бы на двух тысячах строках можно дождаться завершения работы макроса. Код выглядит так: Код: 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.
Но возникла проблема, что после вставленной переменной отрабатывается Enter и ячейка становится как бы двустроковой. Можно этого как то избежать? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 21:09 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Для начала отформатируем, чтобы хоть читать код можно было Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 21:23 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Попробуй копировать в переменную не .Range а .Range.Text ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2021, 21:24 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, таким вот образом не помогло: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8.
Все-равно откуда то присутствует символ "конец абзаца" ... |
|||
:
Нравится:
Не нравится:
|
|||
18.06.2021, 08:12 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Ну значит надо его грохнуть прям в переменной ... |
|||
:
Нравится:
Не нравится:
|
|||
18.06.2021, 09:46 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
vb_sub Range это непрерывный диапазон, нельзя указать крайние столбцы и исключить некоторые промежуточные из них. Можно использовать несколько Range, по одному на каждую необходимую колонку. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.06.2021, 11:39 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, несколько другим способом пытаюсь решить проблему скорости выполнения цикла. Как Вы и советовали, отказался от копирования в буфер внутри цикла. Получился код: Код: 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.
В нем в строке, найденной по условию, сначала объединяются ячейки; в объединенной ячейке остается содержимое второй ячейки с множеством скрытых символов, которые обрезаются; в итоге как плюс - не сбивается форматирование. Скорость выполнения кода заметно выше, но все-равно когда строк две тысячи выполняется он очень долго. Не могу разобраться как работать с ThisDocument. Если с ним работать тоже должен быть прирост скорости? Есть еще варианты над чем поработать? Спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.06.2021, 01:38 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
можно еще ускорить, избавившись от двойного обращения к .Rows(i).Range чтобы ускорять еще - скорее всего уже нужно менять подход в принципе, а может это уже будет невозможно. Без файла образца сложно что-то сказать ... |
|||
:
Нравится:
Не нравится:
|
|||
19.06.2021, 07:22 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, двойное обращение к .Rows(i).Range исключил. Вставил таймер, цикл по обработке двух тысяч строк выполняется 85 сек. Код: 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.
Прилагаю файлы для примера. В таблице excel нажимаю кнопку "копировать в буфер", в word выполняю код. Т.к. два файла приложить не могу, поэтому выложил в архиве. Предполагаю, что можно сократить время, если передавать таблицу из excel в word напрямую, но как это сделать пока не знаю, да и все-таки основное время уходит на обработку строк в цикле, вот его бы ускорить ... |
|||
:
Нравится:
Не нравится:
|
|||
19.06.2021, 23:24 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro чтобы ускорять еще - скорее всего уже нужно менять подход в принципе, а может это уже будет невозможно. Shocker.Pro, в чем может заключаться подход с другой стороны, имеется ввиду отказаться от цикла перебора ячеек? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2021, 13:57 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Я поэкспериментировал с этим кодом. Даже если просто убрать все внутренности цикла, тормозит сама проверка Код: vbnet 1.
Попытки обращения к ячейке другими способами результата особо не дали. Я не знаю, какие у тебя возможности есть при манипуляции экселем, кроме копипасты По большому счету, нужно заранее вычислить номера строк для объединения ячеек ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2021, 14:29 |
|
Очень долгий перебор строк в цикле
|
|||
---|---|---|---|
#18+
Shocker.Pro, большое спасибо Вам за помощь и быстрые ответы. Может я делаю это криво, но в экселе, я специально ввожу в ячейку 3 символа, чтобы определить строку в которой нужно объединить ячейки, т.е. эти три символа в ячейке третьего столбца работают как маркер. Может есть какие то другие способы, более быстрые, по которым определить строку, в которой объединить ячейки? А про определение номеров строк для объединения в самом экселе... у меня в голове витала такая идея. Но она для меня какая то фантастическая. В самом экселе определить номера строк для определения сложностей нет (например, через те же три символа в ячейке), но фактически передать в ворд номера строк для объединения не представляю как реализовать. Количество строк и номера строк могут быть абсолютно разные. В экселе нужно выделить ячейку (диапазон) для номеров строк или как то через переменные эти номера передавать? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2021, 15:34 |
|
|
start [/forum/topic.php?fid=60&msg=40078892&tid=2154713]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
38ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
68ms |
get tp. blocked users: |
1ms |
others: | 15ms |
total: | 172ms |
0 / 0 |