This is one of those things that I’m sure there’s a built-in function for (and I may well have been told it in the past), but I’m scratching my head to remember it.
How do I loop through each row of a multi-column range using Excel VBA? All the tutorials I’ve been searching up seem only to mention working through a one-dimensional range…
asked Sep 22, 2009 at 23:53
1
Dim a As Range, b As Range
Set a = Selection
For Each b In a.Rows
MsgBox b.Address
Next
answered Sep 23, 2009 at 0:19
MikeMike
2,9751 gold badge18 silver badges14 bronze badges
0
Something like this:
Dim rng As Range
Dim row As Range
Dim cell As Range
Set rng = Range("A1:C2")
For Each row In rng.Rows
For Each cell in row.Cells
'Do Something
Next cell
Next row
answered Sep 22, 2009 at 23:58
David AndresDavid Andres
31.2k7 gold badges45 silver badges36 bronze badges
1
Just stumbled upon this and thought I would suggest my solution. I typically like to use the built in functionality of assigning a range to an multi-dim array (I guess it’s also the JS Programmer in me).
I frequently write code like this:
Sub arrayBuilder()
myarray = Range("A1:D4")
'unlike most VBA Arrays, this array doesn't need to be declared and will be automatically dimensioned
For i = 1 To UBound(myarray)
For j = 1 To UBound(myarray, 2)
Debug.Print (myarray(i, j))
Next j
Next i
End Sub
Assigning ranges to variables is a very powerful way to manipulate data in VBA.
answered Dec 9, 2015 at 1:33
tc_NYCtc_NYC
1921 gold badge2 silver badges11 bronze badges
1
In Loops, I always prefer to use the Cells
class, using the R1C1 reference method, like this:
Cells(rr, col).Formula = ...
This allows me to quickly and easily loop over a Range of cells easily:
Dim r As Long
Dim c As Long
c = GetTargetColumn() ' Or you could just set this manually, like: c = 1
With Sheet1 ' <-- You should always qualify a range with a sheet!
For r = 1 To 10 ' Or 1 To (Ubound(MyListOfStuff) + 1)
' Here we're looping over all the cells in rows 1 to 10, in Column "c"
.Cells(r, c).Value = MyListOfStuff(r)
'---- or ----
'...to easily copy from one place to another (even with an offset of rows and columns)
.Cells(r, c).Value = Sheet2.Cells(r + 3, 17).Value
Next r
End With
answered Aug 20, 2015 at 16:50
LimaNightHawkLimaNightHawk
6,5033 gold badges40 silver badges60 bronze badges
0
0 / 0 / 0 Регистрация: 27.08.2017 Сообщений: 12 |
|
1 |
|
30.11.2017, 06:13. Показов 13192. Ответов 6
Добрый день! Имеется список из 3х столбцов в excel:
0 |
11482 / 3773 / 677 Регистрация: 13.02.2009 Сообщений: 11,145 |
|
30.11.2017, 06:53 |
2 |
Да не собирали эти типы мандарины!
0 |
es geht mir gut 11264 / 4746 / 1183 Регистрация: 27.07.2011 Сообщений: 11,437 |
|
30.11.2017, 07:02 |
3 |
Да не собирали эти типы мандарины! Их вообще в первой таблице нет. Как они во второй оказались ?
0 |
0 / 0 / 0 Регистрация: 27.08.2017 Сообщений: 12 |
|
30.11.2017, 07:42 [ТС] |
4 |
Желательно макросом, а может кто-нибудь написать как выглядит код?
0 |
SoftIce es geht mir gut 11264 / 4746 / 1183 Регистрация: 27.07.2011 Сообщений: 11,437 |
||||
30.11.2017, 08:17 |
5 |
|||
кто-нибудь написать как выглядит код?
Миниатюры
0 |
Казанский 15136 / 6410 / 1730 Регистрация: 24.09.2011 Сообщений: 9,999 |
||||
30.11.2017, 09:12 |
6 |
|||
Darlas80, или так
1 |
0 / 0 / 0 Регистрация: 27.08.2017 Сообщений: 12 |
|
04.12.2017, 05:13 [ТС] |
7 |
SoftIce, не работает((( Добавлено через 14 минут
0 |
Цикл For Each… Next в VBA Excel, его синтаксис и описание отдельных компонентов. Примеры использования цикла For Each… Next.
Цикл For Each… Next в VBA Excel предназначен для выполнения блока операторов по отношению к каждому элементу из группы элементов (диапазон, массив, коллекция). Этот замечательный цикл применяется, когда неизвестно количество элементов в группе и их индексация, в противном случае, более предпочтительным считается использование цикла For…Next.
For Each element In group [ statements ] [ Exit For ] [ statements ] Next [ element ] |
В квадратных скобках указаны необязательные атрибуты цикла For Each… Next.
Компоненты цикла For Each… Next
Компонент | Описание |
---|---|
element | Обязательный атрибут в операторе For Each, необязательный атрибут в операторе Next. Представляет из себя переменную, используемую для циклического прохода элементов группы (диапазон, массив, коллекция), которая предварительно должна быть объявлена с соответствующим типом данных*. |
group | Обязательный атрибут. Группа элементов (диапазон, массив, коллекция), по каждому элементу которой последовательно проходит цикл For Each… Next. |
statements | Необязательный** атрибут. Операторы вашего кода. |
Exit For | Необязательный атрибут. Оператор выхода из цикла до его окончания. |
*Если цикл For Each… Next используется в VBA Excel для прохождения элементов коллекции (объект Collection) или массива, тогда переменная element должна быть объявлена с типом данных Variant, иначе цикл работать не будет.
**Если не использовать в цикле свой код, смысл применения цикла теряется.
Примеры циклов For Each… Next
Цикл для диапазона ячеек
На активном листе рабочей книги Excel выделите диапазон ячеек и запустите на выполнение следующую процедуру:
Sub test1() Dim element As Range, a As String a = «Данные, полученные с помощью цикла For Each… Next:» For Each element In Selection a = a & vbNewLine & «Ячейка « & element.Address & _ » содержит значение: « & CStr(element.Value) Next MsgBox a End Sub |
Информационное окно MsgBox выведет адреса выделенных ячеек и их содержимое, если оно есть. Если будет выбрано много ячеек, то полностью информация по всем ячейкам выведена не будет, так как максимальная длина параметра Prompt функции MsgBox составляет примерно 1024 знака.
Цикл для коллекции листов
Скопируйте следующую процедуру VBA в стандартный модуль книги Excel:
Sub test2() Dim element As Worksheet, a As String a = «Список листов, содержащихся в этой книге:» For Each element In Worksheets a = a & vbNewLine & element.Index _ & «) « & element.Name Next MsgBox a End Sub |
Информационное окно MsgBox выведет список наименований всех листов рабочей книги Excel по порядковому номеру их ярлычков, соответствующих их индексам.
Цикл для массива
Присвоим массиву список наименований животных и в цикле For Each… Next запишем их в переменную a. Информационное окно MsgBox выведет список наименований животных из переменной a.
Sub test3() Dim element As Variant, a As String, group As Variant group = Array(«бегемот», «слон», «кенгуру», «тигр», «мышь») ‘или можно присвоить массиву значения диапазона ячеек ‘рабочего листа, например, выбранного: group = Selection a = «Массив содержит следующие значения:» & vbNewLine For Each element In group a = a & vbNewLine & element Next MsgBox a End Sub |
Повторим ту же процедуру VBA, но всем элементам массива в цикле For Each… Next присвоим значение «Попугай». Информационное окно MsgBox выведет список наименований животных, состоящий только из попугаев, что доказывает возможность редактирования значений элементов массива в цикле For Each… Next.
Sub test4() Dim element As Variant, a As String, group As Variant group = Array(«бегемот», «слон», «кенгуру», «тигр», «мышь») ‘или можно присвоить массиву значения диапазона ячеек ‘рабочего листа, например, выделенного: group = Selection a = «Массив содержит следующие значения:» & vbNewLine For Each element In group element = «Попугай» a = a & vbNewLine & element Next MsgBox a End Sub |
Этот код, как и все остальные в этой статье, тестировался в Excel 2016.
Цикл для коллекции подкаталогов и выход из цикла
В этом примере мы будем добавлять в переменную a названия подкаталогов на диске C вашего компьютера. Когда цикл дойдет до папки Program Files, он добавит в переменную a ее название и сообщение: «Хватит, дальше читать не буду! С уважением, Ваш цикл For Each… Next.».
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Sub test5() Dim FSO As Object, myFolders As Object, myFolder As Object, a As String ‘Создаем новый FileSystemObject и присваиваем его переменной «FSO» Set FSO = CreateObject(«Scripting.FileSystemObject») ‘Извлекаем список подкаталогов на диске «C» и присваиваем ‘его переменной «myFolders» Set myFolders = FSO.GetFolder(«C:») a = «Папки на диске C:» & vbNewLine ‘Проходим циклом по списку подкаталогов и добавляем в переменную «a« ‘их имена, дойдя до папки «Program Files«, выходим из цикла For Each myFolder In myFolders.SubFolders a = a & vbNewLine & myFolder.Name If myFolder.Name = «Program Files» Then a = a & vbNewLine & vbNewLine & «Хватит, дальше читать не буду!» _ & vbNewLine & vbNewLine & «С уважением,» & vbNewLine & _ «Ваш цикл For Each... Next.« Exit For End If Next Set FSO = Nothing MsgBox a End Sub |
Информационное окно MsgBox выведет список наименований подкаталогов на диске C вашего компьютера до папки Program Files включительно и сообщение цикла о прекращении своей работы.
В результате работы программы будут выведены не только наименования подкаталогов, видимых при переходе в проводнике к диску C, но и скрытые и служебные папки. Для просмотра списка всех подкаталогов на диске C, закомментируйте участок кода от If до End If включительно и запустите выполнение процедуры в редакторе VBA Excel.
EDIT Summary and reccomendations
Using a for each cell in range
construct is not in itself slow. What is slow is repeated access to Excel in the loop (be it reading or writing cell values, format etc, inserting/deleting rows etc).
What is too slow depends entierly on your needs. A Sub that takes minutes to run might be OK if only used rarely, but another that takes 10s might be too slow if run frequently.
So, some general advice:
- keep it simple at first. If the result is too slow for your needs, then optimise
- focus on optimisation of the content of the loop
- don’t just assume a loop is needed. There are sometime alternatives
- if you need to use cell values (a lot) inside the loop, load them into a variant array outside the loop.
- a good way to avoid complexity with inserts is to loop the range from the bottom up
(for index = max to min step -1
) - if you can’t do that and your ‘insert a row here and there’ is not too many, consider reloading the array after each insert
- If you need to access cell properties other than
value
, you are stuck with cell references - To delete a number of rows consider building a range reference to a multi area range in the loop, then delete that range in one go after the loop
eg (not tested!)
Dim rngToDelete as range
for each rw in rng.rows
if need to delete rw then
if rngToDelete is nothing then
set rngToDelete = rw
else
set rngToDelete = Union(rngToDelete, rw)
end if
endif
next
rngToDelete.EntireRow.Delete
Original post
Conventional wisdom says that looping through cells is bad and looping through a variant array is good. I too have been an advocate of this for some time. Your question got me thinking, so I did some short tests with suprising (to me anyway) results:
test data set: a simple list in cells A1
.. A1000000
(thats 1,000,000 rows)
Test case 1: loop an array
Dim v As Variant
Dim n As Long
T1 = GetTickCount
Set r = Range("$A$1", Cells(Rows.Count, "A").End(xlUp)).Cells
v = r
For n = LBound(v, 1) To UBound(v, 1)
'i = i + 1
'i = r.Cells(n, 1).Value 'i + 1
Next
Debug.Print "Array Time = " & (GetTickCount - T1) / 1000#
Debug.Print "Array Count = " & Format(n, "#,###")
Result:
Array Time = 0.249 sec
Array Count = 1,000,001
Test Case 2: loop the range
T1 = GetTickCount
Set r = Range("$A$1", Cells(Rows.Count, "A").End(xlUp)).Cells
For Each c In r
Next c
Debug.Print "Range Time = " & (GetTickCount - T1) / 1000#
Debug.Print "Range Count = " & Format(r.Cells.Count, "#,###")
Result:
Range Time = 0.296 sec
Range Count = 1,000,000
So,looping an array is faster but only by 19% — much less than I expected.
Test 3: loop an array with a cell reference
T1 = GetTickCount
Set r = Range("$A$1", Cells(Rows.Count, "A").End(xlUp)).Cells
v = r
For n = LBound(v, 1) To UBound(v, 1)
i = r.Cells(n, 1).Value
Next
Debug.Print "Array Time = " & (GetTickCount - T1) / 1000# & " sec"
Debug.Print "Array Count = " & Format(i, "#,###")
Result:
Array Time = 5.897 sec
Array Count = 1,000,000
Test case 4: loop range with a cell reference
T1 = GetTickCount
Set r = Range("$A$1", Cells(Rows.Count, "A").End(xlUp)).Cells
For Each c In r
i = c.Value
Next c
Debug.Print "Range Time = " & (GetTickCount - T1) / 1000# & " sec"
Debug.Print "Range Count = " & Format(r.Cells.Count, "#,###")
Result:
Range Time = 2.356 sec
Range Count = 1,000,000
So event with a single simple cell reference, the loop is an order of magnitude slower, and whats more, the range loop is twice as fast!
So, conclusion is what matters most is what you do inside the loop, and if speed really matters, test all the options
FWIW, tested on Excel 2010 32 bit, Win7 64 bit
All tests with
ScreenUpdating
off,Calulation
manual,Events
disabled.
О чём пойдёт речь?
Знакомство с объектной моделью Excel следует начинать с такого замечательного объекта, как Range. Поскольку любая ячейка — это Range, то без знания, как с этим объектом эффективно взаимодействовать, вам будет затруднительно программировать для Excel. Это очень ладно-скроенный объект. При некоторой сноровке вы найдёте его весьма удобным в эксплуатации.
Что такое объекты?
Мы собираемся изучать объект Range, поэтому пару слов надо сказать, что такое, собственно, «объект«. Всё, что вы наблюдаете в Excel, всё с чем вы работаете — это набор объектов. Например, лист рабочей книги Excel — не что иное, как объект типа WorkSheet. Однотипные объекты объединяют в коллекции себе подобных. Например, листы объединены в коллекцию Sheets. Чтобы не путать друг с другом объекты одного и того же типа, они имеют отличающиеся имена, а также номер индекса в коллекции. Объекты имеют свойства, методы и события.
Свойства — это информация об объекте. Часто эти свойства можно менять, что автоматически влечет изменения внешнего вида объекта или его поведения. Например свойство Visible объекта Worksheet отвечает за видимость листа на экране. Если ему присвоить значение xlSheetHidden (это константа, которая по факту равно нулю), то лист будет скрыт.
Методы — это то, что объект может делать. Например, метод Delete объекта Worksheet удаляет себя из книги. Метод Select делает лист активным.
События — это механизм, при помощи которого вы можете исполнять свой код VBA сразу по факту возникновения того или иного события с вашим объектом. Например, есть возможность выполнять ваш код, как только пользователь сделал текущим определенный лист рабочей книги, либо как только пользователь что-то изменил на этом листе.
Range это диапазон ячеек. Минимум — одна ячейка, максимум — весь лист, теоретически насчитывающий более 17 миллиардов ячеек (строки 2^20 * столбцы 2^14 = 2^34).
В Excel объявлены глобально и всегда готовы к использованию несколько коллекций, имеющий членами объекты типа Range, либо свойства это же типа.
Коллекции глобального объекта Application: Cells, Columns, Rows, а также свойства Range, Selection, ActiveCell, ThisCell.
ActiveCell — активная ячейка текущего листа, ThisCell — если вы написали пользовательскую функцию рабочего листа, то через это свойство вы можете определить какая конкретно ячейка в данный момент пересчитывает вашу функцию. Об остальных перечисленных объектов речь пойдёт ниже.
Работа с отдельными ячейками
Синтаксическая форма | Комментарии по использованию |
Range(«D5«) или [D5] |
Ячейка D5 текущего листа. Полная и краткая формы. Тут применим только синтаксис типа A1, но не R1C1. То есть такая конструкция Range(«R1C2«) — вызовет ошибку, даже если в книге Excel включен режим формул R1C1. Разумеется после этой формы вы можете обратиться к свойствам соответствующей ячейки. Например, Range(«D5«).Interior.Color = RGB(0, 255, 0). |
Cells(5, 4) или Cells(5, «D») | Ячейка D5 текущего листа через свойство Cells. 5 — строка (row), 4 — столбец (column). Допустимость второй формы мало кому известна. |
Cells(65540) | Ячейку D5 можно адресовать и через указание только одного параметра свойсва Cells. При этом нумерация идёт слева направо, потом сверху вниз. То есть сначала нумеруется вся строка (2^14=16384 колонок) и только потом идёт переход на следующую строку. То есть Cells(16385) вернёт вам ячейку A2, а D5 будет Cells(65540). Пока данный способ выглядит не очень удобным. |
Работа с диапазоном ячеек
Синтаксическая форма | Комментарии по использованию |
Range(«A1:B4«) или [A1:B4] | Диапазон ячеек A1:B4 текущего листа. Обратите внимание, что указываются координаты верхнего левого и правого нижнего углов диапазона. Причём первый указываемый угол вполне может быть правым нижним, это не имеет значения. |
Range(Cells(1, 1), Cells(4, 2)) | Диапазон ячеек A1:B4 текущего листа. Удобно, когда вы знаете именно цифровые координаты углов диапазона. |
Работа со строками
Синтаксическая форма | Комментарии по использованию |
Range(«3:5«) или [3:5] | Строки 3, 4 и 5 текущего листа целиком. |
Range(«A3:XFD3«) или [A3:XFD3] | Строка 3, но с указанием колонок. Просто, чтобы вы понимали, что это тождественные формы. XFD — последняя колонка листа. |
Rows(«3:3«) | Строка 3 через свойство Rows. Параметр в виде диапазона строк. Двоеточие — это символ диапазона. |
Rows(3) | Тут параметр — индекс строки в массиве строк. Так можно сослаться только не конкретную строку. Обратите внимание, что в предыдущем примере параметр текстовая строка «3:3» и она взята в кавычки, а тут — чистое число. |
Работа со столбцами
Синтаксическая форма | Комментарии по использованию |
Range(«B:B«) или [B:B] | Колонка B текущего листа. |
Range(«B1:B1048576«) или [B1:B1048576] | То же самое, но с указанием номеров строк, чтобы вы понимали, что это тождественные формы. 2^20=1048576 — максимальный номер строки на листе. |
Columns(«B:B«) | То же самое через свойство Columns. Параметр — текстовая строка. |
Columns(2) | То же самое. Параметр — числовой индекс столбца. «A» -> 1, «B» -> 2, и т.д. |
Весь лист
Синтаксическая форма | Комментарии по использованию |
Range(«A1:XFD1048576«) или [A1:XFD1048576] | Диапазон размером во всё адресное пространство листа Excel. Воспринимайте эту таблицу лишь как теорию — так работать с листами вам не придётся — слишком большое количество ячеек. Даже современные компьютеры не смогут помочь Excel быстро работать с такими массивами информации. Тут проблема больше даже в самом приложении. |
Range(«1:1048576«) или [1:1048576] | То же самое, но через строки. |
Range(«A:XFD«) или [A:XFD] | Аналогично — через адреса столбцов. |
Cells | Свойство Cells включает в себя ВСЕ ячейки. |
Rows | Все строки листа. |
Columns | Все столбцы листа. |
Следует иметь в виду, что свойства Range, Cells, Columns и Rows имеют как объекты типа Worksheet, так и объекты Range. Соответственно в первом случае эти коллекции будут относиться ко всему листу и отсчитываться будут от A1, а вот в случае конкретного объекта Range эти коллекции будут относиться только к ячейкам этого диапазона и отсчитываться будут от левого верхнего угла диапазона. Например Cells(2,2) указывает на ячейку B2, а Range(«C3:D5»).Cells(2,2) укажет на D4.
Также много путаницы в умы вносит тот факт, что объект Range имеет одноименное свойство range. К примеру, Range(«A100:D500»).Range(«A2») — тут выражение до точки ( Range(«A100:D500») ) является объектом Range, выражение после точки ( Range(«A2») ) — свойство range упомянутого объекта, но возвращает это свойство тоже объект типа Range. Вот такие пироги. Из этого следует, что такая цепочка может иметь и более двух членов. Практического смысла в этом будет не много, но синтаксически это будут совершенно корректно, например, так: Range(«CV100:GR200»).Range(«J10:T20»).Range(«A1:B2») укажет на диапазон DE109:DF110.
Ещё один сюрприз таится в том, что объекты Range имеют свойство по-умолчанию Item( RowIndex [, ColumnIndex] ). По правилам VBA при ссылке на default свойства имя свойства (Item) можно опускать. Кстати говоря, то что вы привыкли видеть в скобках после Cells, есть не что иное, как это дефолтовое свойство Item, а не родные параметры Cells, который их не имеет вовсе. Ну ладно к Cells все привыкли и это никакого отторжения не вызывает, но если вы увидите нечто подобное — Range(«C3:D5»)(2,2), то, скорее всего, будете несколько озадачены, а тем временем — это буквально тоже самое, что и у Cells — всё то же дефолтовое свойство Item. Последняя конструкция ссылается на D4. А вот для Columns и Rows свойство Item может быть только одночленным, например Columns(1) — и к этой форме мы тоже вполне привыкли. Однако конструкции вида Columns(2)(3)(4) могут сильно удивить (столбец 7 будет выделен).
Примеры кода
Скачать
Типовые задачи
-
Перебор ячеек в диапазоне (вариант 1)
В данном примере организован цикл For…Next и доступ к ячейкам осуществляется по их индексу. Вместо parRange(i) мы могли бы написать parRange.Item(i) (выше это объяснялось). Обратите внимание, что мы в этом примере успешно применяем, как вариант с parRange(i,c), так и parRange(i). То есть, если мы применяем одночленную форму свойства Item, то диапазон перебирается по строкам (A1, B1, C1, A2, …), а если двухчленную, то столбец у нас зафиксирован и каждая итерация цикла — на новой строке. Это очень интересный эффект, его можно применять для вытягивания таблиц по вертикали. Но — продолжим!
Количество ячеек в диапазоне получено при помощи свойства .Count. Как .Item, так и .Count — это всё атрибуты коллекций, которые широко применяются в объектой модели MS Office и, в частности, Excel.
Sub Handle_Cells_1(parRange As Range) For i = 1 To parRange.Count parRange(i, 5) = parRange(i).Address & " = " & parRange(i) Next End Sub
-
Перебор ячеек в диапазоне (вариант 2)
В этом примере мы использовали цикл For each…Next, что выглядит несколько лаконичней. Однако, в некоторых случаях вам может потребоваться переменная i из предыдущего примера, например, для вывода результатов в определенные строки листа, поэтому выбирайте удробную вам форму оператора For. Тут в цикле мы «вытягивали» все ячейки диапазона в текстовую строку, чтобы потом отобразить её через функцию MsgBox.
Sub Handle_Cells_2(parRange As Range) For Each c In parRange strLine = strLine & c.Address & "=" & c & "; " Next MsgBox strLine End Sub
-
Перебор ячеек в диапазоне (вариант 3)
Если необходимо перебирать ячейки в порядке A1, A2, A3, B1, …, а не A1, B1, C1, A2, …, то вы можете это организовать при помощи 2-х циклов For. Обратите внимание, как мы узнали количество столбцов (parRange.Columns.Count) и строк (parRange.Rows.Count) в диапазоне, а также на использование свойства Cells. Тут Cells относится к листу и никак не связано с диапазоном parRange.
Sub Handle_Cells_3(parRange As Range) colNum = parRange.Columns.Count For i = 1 To parRange.Rows.Count For j = 1 To colNum Cells(i + (j - 1) * colNum, colNum + 2) = parRange(i, j) Next j Next i End Sub
-
Перебор строк диапазона
В цикле For each…Next перебираем коллекцию Rows объекта parRange. Для каждой строки формируем цвет на основе первых трёх ячеек каждой строки. Поскульку у нас в ячейках формула, присваивающая ячейке случайное число от 1 до 255, то цвета получаются всегда разные. Оператор With позволяет нам сократить код и, к примеру, вместо Line.Cells(2) написать просто .Cells(2).
Sub Handle_Rows_1(parRange As Range) For Each Line In parRange.Rows With Line .Interior.Color = RGB(.Cells(1), .Cells(2), .Cells(3)) End With Next End Sub
-
Перебор столбцов
Перебираем коллекцию Columns. Тоже используем оператор With. В последней ячейке каждого столбца у нас хранится размер шрифта для всей колонки, который мы и применяем к свойству Line.Font.Size.
Sub Handle_Columns_1(parRange As Range) For Each Line In parRange.Columns With Line .Font.Size = .Cells(.Cells.Count) End With Next End Sub
-
Перебор областей диапазона
Как вы знаете, в Excel можно выделить несвязанные диапазоны и проделать с ними какие-то операции. Поддерживает это и объект Range. Получить диапазон, состоящий из нескольких областей (area) очень легко — достаточно перечислить через запятую адреса соответствующих диапазонов: Range(«A1:B3, B5:D8, Z1:AA12«).
Вот такой составной диапазон и разбирается процедурой, показанной ниже. Организован цикл по коллекции Areas, настроен оператор with на текущий элемент коллекции, и ниже и правее относительно ячейки J1 мы собираем некоторые сведения о свойствах областей составного диапазона (которые каждый по себе, конечно же, тоже являются объектами типа Range). Для задания смещения от ячейки J1 нами впервые использовано очень полезное свойство Offset. Каждый диапазон получает случайный цвет, плюс мы заносим в таблицу порядковый номер диапазона (i), его адрес (.Address), количество ячеек (.Count) и цвет (.Interior.Color) после того, как он вычислен.Sub Handle_Areas_1(parRange As Range) For i = 1 To parRange.Areas.Count With parRange.Areas(i) Cells(1, 10).Offset(i, 0) = i Cells(1, 10).Offset(i, 1) = .Address Cells(1, 10).Offset(i, 2) = .Count .Interior.Color = RGB(Int(Rnd * 255), Int(Rnd * 255), Int(Rnd * 255)) Cells(1, 10).Offset(i, 3) = .Interior.Color End With Next End Sub
Продолжение следует…
Читайте также:
-
Поиск границ текущей области
-
Массивы в VBA
-
Структуры данных и их эффективность
-
Автоматическое скрытие/показ столбцов и строк