powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Медленная вставка изображений в отчет > 3000 значений
9 сообщений из 9, страница 1 из 1
Медленная вставка изображений в отчет > 3000 значений
    #38489051
endurance
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Ситуация такая: есть рабочая книга Excel 2007, в которой в определенном столбце хранятся коды товаров. На локальном диске лежит папка с изображениями каждого товара, если код товара оncутствует в названии картинки, то вместо нее вставляется картинка "Нет фото".

Проблема: отчет отрабатывает очень долго, 6-8 минут. Есть список кодов > 3 000 товаров, для каждого товара вставляется картинка. Изображение само по себе небольшое, уменьшать уже некуда.
Вес изображения: 1,5-2 Кб
Размер: 61х39 пикселей.

Отключил перерисовки объектов на экране, чтобы ничего не мигало, отключил вычисления формул и прочее. Время отработки немного уменьшилось, НО, по мере вставки картинок, скорость все меньше и меньше. Мне кажется, проблема в том, что я обращаюсь к каждой ячейке в рабочей книге используя цикл While. Просто обычный перебор кодов и 2 условия на вставку. Как можно существенно ускорить процесс вставки изображений? Может нужно каким-то образом использовать массивы?

Код на VBA очень простой. Один цикл While и два условия.

Код: 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.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
Sub OnRefresh()

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    ActiveSheet.DisplayPageBreaks = False
    Application.DisplayStatusBar = False
    Application.DisplayAlerts = False


Dim rgResult As Range
Set rgResult = Range("A1:IV65536").Find("material", , xlValues)
If rgResult Is Nothing Then
MsgBox "material not found"
End If

Dim f As Shape
For Each f In ActiveSheet.Shapes
If Not Intersect(Range(f.BottomRightCell.Address), Range("L16:L65536")) Is Nothing Then
f.Delete
End If
Next

i = 1
var01 = Range(rgResult.Address).Offset(i, 0)
While var01 <> ""
If Dir("D:\_foto\" & var01 & ".JPG") = "" Then
With ActiveSheet.Pictures.Insert("D:\_foto\nothing.JPG")
                    .Top = Range(rgResult.Address).Offset(i, 6).Top
                    .Left = Range(rgResult.Address).Offset(i, 6).Left
                    
End With
Rows(rgResult.Row + i).Select
Selection.RowHeight = 50
Else
With ActiveSheet.Pictures.Insert("D:\_foto\" & var01 & ".JPG")
                    .Top = Range(rgResult.Address).Offset(i, 6).Top
                    .Left = Range(rgResult.Address).Offset(i, 6).Left

End With
Rows(rgResult.Row + i).Select
Selection.RowHeight = 50
End If

i = i + 1
var01 = Range(rgResult.Address).Offset(i, 0)
Wend

   Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    ActiveSheet.DisplayPageBreaks = True
    Application.DisplayStatusBar = True
    Application.DisplayAlerts = True


End Sub


...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38489714
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endurance,

Вместо Pictures.Insert попробуйте Shapes.AddPicture. Метод Insert может свободно влепить и линк заодно.
...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38490108
endurance
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VladConn, спасибо за ответ. Попробовал, в принципе, одинаково, те же 6 минут.

Почитал на счет массивов, мол, они намного быстрее работают, так как все вычисления производятся в памяти, но у меня никаких вычислений нет, никаких формул и рассчетов. Просмотрев еще раз код, заметил, что у меня не работает удаление старых картинок (когда макрос запускается), подумал, наверно в этом проблема, поскольку изображения накладывались друг на друга, пофиксил, но результат такой же.
...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38490397
Фотография alex77755
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Бежать на фиг от этих тормознутых "ленейчатых" офисов. В 2003 эта процедура (вставка 5050 картинок по 4360Бт) заняла 15с.
Из низ 3с удаление предыдущих 5050 картинок. Правда без проверки. Тупо все подряд.
2. Если уж никак не избавиться от риббоновских, то:
1. Никогда не делать Select. Тем более в цикле для каждой строки. Надо увеличить высоту строки - увеличь до цикла без select сразу для всех строк.
2. Много времени занимает и передвижка картинки. Вставляй картинку сразу в нужное место и без выбора (With):
Код: vbnet
1.
2.
3.
        Call Лист1.Shapes.AddPicture("D:\_foto\nothing.JPG", msoTrue, msoTrue, _
                                    Range(rgResult.Address).Offset(i, 6).Left, _
                                    Range(rgResult.Address).Offset(i, 6).Top, 100, 50)


Ширину (100) и высоту (50) установи нужную тебе
...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38490465
Фотография alex77755
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Удалить все картинки можно быстрей:
Код: vbnet
1.
2.
ActiveSheet.Shapes.SelectAll
Selection.Delete
...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38490624
Фотография alex77755
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня картинок нет поэтому и строки вставки не изменял. Работает только первая часть (с nothing.JPG)"
Код: 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.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
Sub OnRefresh()
Dim LR

Dim ttt
ttt = Time
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    ActiveSheet.DisplayPageBreaks = False
    Application.DisplayStatusBar = False
    Application.DisplayAlerts = False
    
ActiveSheet.Shapes.SelectAll
Selection.Delete

Dim rgResult As Range, i, var01
Set rgResult = Range("A1:IV65536").Find("material", , xlValues)

If rgResult Is Nothing Then
MsgBox "material not found"
End If

LR = Cells(Rows.Count, rgResult.Column).End(xlUp).Row
Лист1.Rows(1 & ":" & LR).RowHeight = 50

var01 = Range(rgResult.Address).Offset(i, 0)

i = 1
While var01 <> ""
    If Dir("D:\_foto\" & var01 & ".JPG") = "" Then
        Call Лист1.Shapes.AddPicture("D:\_foto\nothing.JPG", msoTrue, msoTrue, _
                                    Range(rgResult.Address).Offset(i, 6).Left, _
                                    Range(rgResult.Address).Offset(i, 6).Top, 100, 50)
    Else
        With ActiveSheet.Pictures.Insert("D:\_foto\" & var01 & ".JPG")
                            .Top = Range(rgResult.Address).Offset(i, 6).Top
                            .Left = Range(rgResult.Address).Offset(i, 6).Left
        End With
    End If
    
    i = i + 1
    var01 = Range(rgResult.Address).Offset(i, 0)
Wend

   Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    ActiveSheet.DisplayPageBreaks = True
    Application.DisplayStatusBar = True
    Application.DisplayAlerts = True

MsgBox Format(Time - ttt, "hh:nn:ss") & vbCrLf & "Вставлено " & i & " картинок размером 4360 Бт", 64, ""

End Sub

...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38490741
endurance
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex77755, спасибо большое, сделал все как вы сказали, убрал селект, убрал with, заменил метод и в итоге 50 секунд на 3 000 значений.

На счет удаления, это у меня пока тестовый вариант, поэтому сношу все картинки, которые есть в рабочей книге, но в действительности наверно придется удалять только выбранный диапазон (пока не работает). Есть ли тут какие-то подводные камни? Поскольку, если книгу обратно откроют, то нужно будет сначала удалить имеющиеся картинки, а потом заново по нужному фильтру прогрузить.
...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38493837
endurance
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще такой вопрос возник. Необходимо, чтобы изображения были по центру ячейки. Но при вставке, они не становятся привязанными к этой ячейке, то есть я не могу их выровнять используя метод для выравнивая текста. К тому же не могу использоваться Selection в цикле. Как быть?
...
Рейтинг: 0 / 0
Медленная вставка изображений в отчет > 3000 значений
    #38494223
endurance
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разобрался, параметр Range(rgResult.Address).Offset(i, 6).Left подогнал под свои размеры и программно увеличил размеры столбцов.

alex77755 , а нет ничего по шустрее, чем удаление таким способом?
Код: vbnet
1.
2.
ActiveSheet.Shapes.SelectAll
Selection.Delete
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Медленная вставка изображений в отчет > 3000 значений
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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