powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Оптимизация работы алгоритма обработки диапазона ячеек Excel
7 сообщений из 7, страница 1 из 1
Оптимизация работы алгоритма обработки диапазона ячеек Excel
    #39326344
chikaginsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!
Для документа xls (97-2003) написал код макроса, который для каждого листа документа обрабатывает строки по следующим условиям:
- если в столбцах A, B, C текущей строки ячейки пустые, то убираем верхнюю границу в ячейках этих столбцов у этой строки;
- если в столбце D текущей строки ячейка заполнена словом "Всего", то делаем шрифт этой ячейки полужирным у этой строки.
Алгоритм следующий:
Код: 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.
Private Sub Workbook_Open()

Dim lLastRow As Long 'последняя заполненная строка на листе
Dim lCurRow As Long 'текущая строка
Dim i As Integer 'номер листа

For i = 2 To Sheets.Count
    
    Sheets(i).Activate
    
    lLastRow = Cells(Rows.Count, 1).End(xlUp).Row 'последняя строка листа
    lLastRow = lLastRow - 1 'предпоследняя строка листа
    
    If lLastRow > 13 Then
    
    For lCurRow = 13 To lLastRow
        
        'границы ячеек
        If Cells(lCurRow, 1) = "" And Cells(lCurRow, 2) = "" And Cells(lCurRow, 3) = "" And lCurRow > 13 Then
            Range(Cells(lCurRow, 1), Cells(lCurRow, 3)).Borders(xlEdgeTop).LineStyle = xlLineStyleNone
        End If
        
          'выделение шрифта полужирным
        If Cells(lCurRow, 4) = "Всего" Then
            Cells(lCurRow, 4).Font.Bold = True
        End If
        
    Next
    
    End If

Next i

Sheets(2).Activate

End Sub


Сильно не пинайте, только начал осваивать VBA.
Вопрос вот в чём: можно ли как-то оптимизировать (ускорить выполнение) данный код?
В xls документе бывает очень много строк (65000 и больше), да ещё и не на одном листе.
Может как-то можно выделять весь диапазон строк для столбцов A, B, C, D и по условиям вносить изменения в нужных ячейках диапазона, а не перебирать строки диапазона по-порядку?
...
Рейтинг: 0 / 0
Оптимизация работы алгоритма обработки диапазона ячеек Excel
    #39326436
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для начала попробуйте application.ScreenUpdating=False перед началом обработки и application.ScreenUpdating=True по окончании.
...
Рейтинг: 0 / 0
Оптимизация работы алгоритма обработки диапазона ячеек Excel
    #39326547
Фотография by-pass
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chikaginsk,

Перебор всегда будет долгим. Можно попробовать использовать встроенный механизм Find. Попробуйте записать макрос в своем экселе и посмотреть что он делает.
...
Рейтинг: 0 / 0
Оптимизация работы алгоритма обработки диапазона ячеек Excel
    #39326560
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chikaginsk, попробуйте кусок "границы ячеек" в таком виде:
Код: vbnet
1.
2.
3.
4.
5.
6.
        'границы ячеек
        With Cells(lCurRow, 1).Resize(, 3)
          If .Text = "" And lCurRow > 13 Then
            .Borders(xlEdgeTop).LineStyle = xlLineStyleNone
          End If
        End With
...
Рейтинг: 0 / 0
Оптимизация работы алгоритма обработки диапазона ячеек Excel
    #39326579
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А еще лучше получить массив значений True/False, вычислив в коде формулу листа типа =A1:A19&B1:B19&C1:C19="" (здесь lLastRow=19). И значения ст. D тоже загрузить в массив.
Код: 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.
Private Sub Workbook_Open()

Dim lLastRow As Long  'последняя заполненная строка на листе
Dim lCurRow As Long   'текущая строка
Dim i As Integer      'номер листа
Dim v(), d()          'массив значений, возвращаемый формулой, и значения ст. D

For i = 2 To Sheets.Count
  lLastRow = Cells(Rows.Count, 1).End(xlUp).Row - 1 'предпоследняя строка листа
    
  If lLastRow > 13 Then
    v = Evaluate(Replace("A1:A~&B1:B~&C1:C~=""""", "~", lLastRow))
    d = Range("D1:D" & lLastRow).Value
    For lCurRow = 13 To lLastRow
        
        'границы ячеек
        If v(lCurRow, 1) And lCurRow > 13 Then
            Cells(lCurRow, 1).Resize(, 3).Borders(xlEdgeTop).LineStyle = xlLineStyleNone
        End If
        
          'выделение шрифта полужирным
        If d(lCurRow, 1) = "Всего" Then
            Cells(lCurRow, 4).Font.Bold = True
        End If
        
    Next
  End If
Next i

Sheets(2).Activate

End Sub


Вообще, метод Evaluate учитывает текущий стиль ссылок приложения (А1 или R1C1). Поэтому формулу лучше привести к текущему стилю ссылок, "обернув" ее в метод ConvertFormula:
Код: vbnet
1.
    v = Evaluate(Application.ConvertFormula(Replace("A1:A~&B1:B~&C1:C~=""""", "~", lLastRow), xlA1, Application.ReferenceStyle))
...
Рейтинг: 0 / 0
Оптимизация работы алгоритма обработки диапазона ячеек Excel
    #39326708
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: vbnet
1.
2.
3.
For lCurRow = 13 To lLastRow
    Cells(lCurRow, 1)
    Cells(lCurRow, 4)

Вместо этого получить Range из строк, обойти его через For Each row In и обращаться к ячейке как row.Cells(1)

Так можно сэкономить еще пару копеек
...
Рейтинг: 0 / 0
Оптимизация работы алгоритма обработки диапазона ячеек Excel
    #39326772
chikaginsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Благодарю за наводки. Буду пробовать представленные варианты. Пока с кодом в примерах разберусь.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Оптимизация работы алгоритма обработки диапазона ячеек Excel
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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