Новости:

Название темы должно отражать суть задачи.
Темы типа "ПОМОГИТЕ!!!", "Срочно!" и т.п. будут удаляться без объяснения причин

Главное меню

Как скопировать в массив атрибуты ячеек из диапазона?

Автор mkharlanchuk, 10.02.2013, 17:08:18

« назад - далее »

mkharlanchuk

Добрый день!
Помогите, пожалуйста, решить задачу по оптимизации VBA-кода.
Исходная задача формулируется так:
в столбце B записаны цифры: 0 или 1;
в столбце C записаны логические значения: ИСТИНА или ЛОЖЬ;
для строк, у которых в столбце B стоит 1, необходимо в столбец A вставить чек-бокс, установить его значение в зависимости от значения в столбце C, связать чек-бокс с ячейкой в столбце С.

Я написал следующий макрос:
Private Sub Workbook_Open()
' Отключаем автоматические вычисления и обновление экрана.
Application.Calculation = xlCalculationManual 
Application.ScreenUpdating = False 
Application.EnableEvents = False 

    Dim FinalRow As Long
FinalRow = 3000
   
    For i = 1 To FinalRow
If Cells(i, 2).Value = 1 Then
            With ActiveSheet.CheckBoxes.Add(Cells(i, 1).Left, Cells(i, 1).Top, Cells(i, 1).Width, Cells(i, 1).Height)
                .Value = CBool(Cells(i, 3))
                .LinkedCell = Cells(i, 3).Address
                .Display3DShading = True
                .Caption = ""
            End With
End If
    Next i
   
' Восстанавливаем настройки
Application.Calculation = xlCalculationAutomatic 
Application.ScreenUpdating = True 
Application.EnableEvents = True 
End Sub

Он работает правильно, но долго. Почитав умных людей понял, что причина в частом обращении к ячейкам и что будет работать гораздо быстрее, если предварительно скопировать диапазон в массив.
Как быстро скопировать значения диапазона ячеек я нашел:
    Dim R_data As Variant
    R_data = ActiveSheet.Range(ActiveSheet.Cells(1, 1), ActiveSheet.Cells(FinalRow, 3))

Вопрос в том, как быстро (без использования цикла) скопировать в массив атрибуты ячеек из диапазона?
Мне нужно копировать свойства Left, Top, Width, Height   ячеек из столбца A и свойство Address ячеек из столбца C.

Кто-нибудь сталкивался с такой задачей?

vikttur

#1
Почему цикл в опале?
Для чего CheckBox? Может быть, конечная задача решается по другому, а Вы не знаете.

С Вашим файлом помощь пришла бы быстрее.

Дмитрий Щербаков(The_Prist)

Не получится без цикла скопировать в массив атрибуты ячеек. Но даже без них выполнение ускорится хотя в первом моменте: у Вас будет обращение к атрибутам ячеек только в том случае, если в массиве в третьем столбце будет ИСТИНА. Кстати, если у Вас все ячейки одинакового размера, то можно от ячеек получить только свойство Top. остальные получить перед циклом:
.Left, .Width, .Height

Left и Width можно получить перед циклом в любом случае, т.к. столбец для вставки у Вас не меняется, равно как и его ширина. А если высота строк у ячеек одинаковая - то и Height тоже можно получить до цикла. Таким образом нужен будет только Top. Хотя, если заморочиться можно получить Top только первой ячейки, а далее прибавлять к нему Height в цикле и по нему вставлять.

Cells(i, 3).Address
номер столбца известен - С. Значит в адресе нужна только строка. Тоже можно получтиь без обращения к ячейкам:
.LinkedCell = "C" & i
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...

mkharlanchuk

Цитата: vikttur от 10.02.2013, 17:30:37
Почему цикл в опале?
Циклы в опале потому что долго работают. Много времени тратится на обращение к каждой ячейке. Обращение же к элементу массива на порядок быстрее.
Цитата: vikttur от 10.02.2013, 17:30:37
Для чего CheckBox? Может быть, конечная задача решается по другому, а Вы не знаете.
Я разрабатываю отчет в Oracle BI Publisher, в котором будут выводиться сведения о сотрудниках организации. Некоторые из этих сведений (пол, обращение и т. п.) должны отображаться в виде чек-боксов. BI Publisher не умеет в цикле рисовать чек-боксы, поэтому приходится выводить данные в скрываемые столбцы и на их основе макросом добавлять чек-боксы.
Цитата: vikttur от 10.02.2013, 17:30:37
С Вашим файлом помощь пришла бы быстрее.

mkharlanchuk

Цитата: The_Prist от 10.02.2013, 18:02:33
Кстати, если у Вас все ячейки одинакового размера, то можно от ячеек получить только свойство Top.
Нет, высота ячеек разная, шаблон отчета довольно сложный.
В принципе, Width и Height можно не получать, а задать заранее размеры чек-бокса чуть меньше наименьшей из ячеек. Тем более они прозрачные и без подписи.
Left, согласен, можно вычислить заранее,  Addres тоже можно вычислить без обращения к ячейке.
Остается только Top и сама вставка чек бокса ... Ну что ж, думаю если использовать эти резервы оптимизации, то можно выйти на приемлемое время выполнения.
Просто на самом деле я упростил пример, в отчете надо вставлять чек-боксы в разные столбцы и привязывать их к разным столбцам. Думал, если есть возможность быстро скопировать свойства диапазона ячеек, то можно упростить задачу. Ну, нет так нет)
Спасибо за помощь!

Яндекс.Метрика Рейтинг@Mail.ru