Обращение к ячейке на листе Excel из кода VBA по адресу, индексу и имени. Чтение информации из ячейки. Очистка значения ячейки. Метод ClearContents объекта Range.
Обращение к ячейке по адресу
Допустим, у нас есть два открытых файла: «Книга1» и «Книга2», причем, файл «Книга1» активен и в нем находится исполняемый код VBA.
В общем случае при обращении к ячейке неактивной рабочей книги «Книга2» из кода файла «Книга1» прописывается полный путь:
Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Range(«C5») Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Cells(5, 3) Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Cells(5, «C») Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).[C5] |
Удобнее обращаться к ячейке через свойство рабочего листа Cells(номер строки, номер столбца), так как вместо номеров строк и столбцов можно использовать переменные. Обратите внимание, что при обращении к любой рабочей книге, она должна быть открыта, иначе произойдет ошибка. Закрытую книгу перед обращением к ней необходимо открыть.
Теперь предположим, что у нас в активной книге «Книга1» активны «Лист1» и ячейка на нем «A1». Тогда обращение к ячейке «A1» можно записать следующим образом:
ActiveCell Range(«A1») Cells(1, 1) Cells(1, «A») [A1] |
Точно также можно обращаться и к другим ячейкам активного рабочего листа, кроме обращения ActiveCell, так как активной может быть только одна ячейка, в нашем примере – это ячейка «A1».
Если мы обращаемся к ячейке на неактивном листе активной рабочей книги, тогда необходимо указать этот лист:
‘по основному имени листа Лист2.Cells(2, 7) ‘по имени ярлыка Sheets(«Имя ярлыка»).Cells(3, 8) |
Имя ярлыка может совпадать с основным именем листа. Увидеть эти имена можно в окне редактора VBA в проводнике проекта. Без скобок отображается основное имя листа, в скобках – имя ярлыка.
Обращение к ячейке по индексу
К ячейке на рабочем листе можно обращаться по ее индексу (порядковому номеру), который считается по расположению ячейки на листе слева-направо и сверху-вниз.
Например, индекс ячеек в первой строке равен номеру столбца. Индекс ячеек во второй строке равен количеству ячеек в первой строке (которое равно общему количеству столбцов на листе, зависящему от версии Excel) плюс номер столбца. Индекс ячеек в третьей строке равен количеству ячеек в двух первых строках плюс номер столбца. И так далее.
Для примера, Cells(4) та же ячейка, что и Cells(1, 4). Используется такое обозначение редко, тем более, что у разных версий Excel может быть разным количество столбцов и строк на рабочем листе.
По индексу можно обращаться к ячейке не только на всем рабочем листе, но и в отдельном диапазоне. Нумерация ячеек осуществляется в пределах заданного диапазона по тому же правилу: слева-направо и сверху-вниз. Вот индексы ячеек диапазона Range(«A1:C3»):
Обращение к ячейке Range("A1:C3").Cells(5)
соответствует выражению Range("B2")
.
Обращение к ячейке по имени
Если ячейке на рабочем листе Excel присвоено имя (Формулы –> Присвоить имя), то обращаться к ней можно по присвоенному имени.
Допустим одной из ячеек присвоено имя – «Итого», тогда обратиться к ней можно – Range("Итого")
.
Запись информации в ячейку
Содержание ячейки определяется ее свойством «Value», которое в VBA Excel является свойством по умолчанию и его можно явно не указывать. Записывается информация в ячейку при помощи оператора присваивания «=»:
Cells(2, 4).Value = 15 Cells(2, 4) = 15 Range(«A1») = «Этот текст записываем в ячейку» ActiveCell = 28 + 10*36 |
Вместе с числами и текстом можно использовать переменные. Примеры здесь и ниже приведены для активного листа. Для неактивных листов дополнительно необходимо указывать имя листа, как в разделе «Обращение к ячейке».
Чтение информации из ячейки
Считать информацию из ячейки в переменную можно также при помощи оператора присваивания «=»:
Sub Test() Dim a1 As Integer, a2 As Integer, a3 As Integer Range(«A3») = 6 Cells(2, 5) = 15 a1 = Range(«A3») a2 = Cells(2, 5) a3 = a1 * a2 MsgBox a3 End Sub |
Точно также можно обмениваться информацией между ячейками:
Cells(2, 2) = Range(«A4») |
Очистка значения ячейки
Очищается ячейка от значения с помощью метода ClearContents. Кроме того, можно присвоить ячейке значение нуля. пустой строки или Empty:
Cells(10, 2).ClearContents Range(«D23») = 0 ActiveCell = «» Cells(5, «D») = Empty |
METHOD 1. Excel INDEX Function using hardcoded values
EXCEL
Result in cell E14 ($5.40) — returns the value in the forth row and second column relative to the specified range. |
=INDEX((B5:C8,B9:C11),3,2,2) |
Result in cell E15 ($7.40) — returns the value in the third row and second column relative to the second range specified in the formula. |
=INDEX((B5:D8,B9:D11),2,3,2) |
Result in cell E16 ($3.00) — returns the value in the second row and third column relative to the second range specified in the formula. |
=INDEX((B5:C8,B9:C11,Index_Defined_Name),2,3,3) |
Result in cell E17 ($2.10) — returns the value in the second row and third column relative to the range specified by the defined name named Index_Defined_Name which comprises a B5:D11 range. |
METHOD 2. Excel INDEX Function using links
EXCEL
=INDEX(B5:C11,B14,C14) |
Result in cell E14 ($5.40) — returns the value in the forth row and second column relative to the specified range. |
=INDEX((B5:C8,B9:C11),B15,C15,D15) |
Result in cell E15 ($7.40) — returns the value in the third row and second column relative to the second range specified in the formula. |
=INDEX((B5:D8,B9:D11),B16,C16,D16) |
Result in cell E16 ($3.00) — returns the value in the second row and third column relative to the second range specified in the formula. |
=INDEX((B5:C8,B9:C11,Index_Defined_Name),B17,C17,D17) |
Result in cell E17 ($2.10) — returns the value in the second row and third column relative to the range specified by the defined name named Index_Defined_Name which comprises a B5:D11 range. |
METHOD 3. Excel INDEX function using the Excel built-in function library with hardcoded values
EXCEL
Formulas tab > Function Library group > Lookup & Reference > INDEX > populate the input box
=INDEX(B5:C11,4,2) Note: in this example we are populating the Array, Row_num and Column_num INDEX function arguments. |
=INDEX((B5:C8,B9:C11),3,2,2) Note: in this example we are only populating all of the INDEX function arguments. |
METHOD 4. Excel INDEX function using the Excel built-in function library with links
EXCEL
Formulas tab > Function Library group > Lookup & Reference > INDEX > populate the input boxes
=INDEX(B5:C11,B14,C14) Note: in this example we are populating the Array, Row_num and Column_num INDEX function arguments. |
=INDEX((B5:C8,B9:C11),B15,C15,D15) Note: in this example we are only populating all of the INDEX function arguments. |
METHOD 1. Excel INDEX function using VBA with hardcoded values
VBA
Sub Excel_Index_Function_Using_Hardcoded_Values()
Dim ws As Worksheet
Set ws = Worksheets(«INDEX»)
ws.Range(«E14»).Value = Application.WorksheetFunction.Index(Range(«B5:C11»), 4, 2)
ws.Range(«E15»).Value = Application.WorksheetFunction.Index(Range(«B5:C8,B9:C11»), 3, 2, 2)
ws.Range(«E16»).Value = Application.WorksheetFunction.Index(Range(«B5:D8,B9:D11»), 2, 3, 2)
ws.Range(«E17»).Value = Application.WorksheetFunction.Index(Range(«B5:C8,B9:C11,Index_Defined_Name»), 2, 3, 3)
End Sub
OBJECTS
Worksheets: The Worksheets object represents all of the worksheets in a workbook, excluding chart sheets.
Range: The Range object is a representation of a single cell or a range of cells in a worksheet.
PREREQUISITES
Worksheet Name: Have a worksheet named INDEX.
Defined Name: Have a defined name named Index_Defined_Name that comprises a B5:D11 range.
ADJUSTABLE PARAMETERS
Output Range: Select the output range by changing the cell references («E14»), («E15»), («E16») and («E17») in the VBA code to any cell in the worksheet, that doesn’t conflict with the formula.
METHOD 2. Excel INDEX function using VBA with links
VBA
Sub Excel_Index_Function_Using_Links()
Dim ws As Worksheet
Set ws = Worksheets(«INDEX»)
ws.Range(«E14»).Value = Application.WorksheetFunction.Index(Range(«B5:C11»), Range(«B14»), Range(«C14»))
ws.Range(«E15»).Value = Application.WorksheetFunction.Index(Range(«B5:C8,B9:C11»), Range(«B15»), Range(«C15»), Range(«D15»))
ws.Range(«E16»).Value = Application.WorksheetFunction.Index(Range(«B5:D8,B9:D11»), Range(«B16»), Range(«C16»), Range(«D16»))
ws.Range(«E17»).Value = Application.WorksheetFunction.Index(Range(«B5:C8,B9:C11,Index_Defined_Name»), Range(«B17»), Range(«C17»), Range(«D17»))
End Sub
OBJECTS
Worksheets: The Worksheets object represents all of the worksheets in a workbook, excluding chart sheets.
Range: The Range object is a representation of a single cell or a range of cells in a worksheet.
PREREQUISITES
Worksheet Name: Have a worksheet named INDEX.
Defined Name: Have a defined name named Index_Defined_Name that comprises a B5:D11 range.
ADJUSTABLE PARAMETERS
Output Range: Select the output range by changing the cell references («E14»), («E15»), («E16») and («E17») in the VBA code to any cell in the worksheet, that doesn’t conflict with the formula.
Indexes in Programming
“Index” is a common term used in all programming languages. It basically acts like a serial number of which an item or value can be referenced. For example, in the picture below, “Great Wall of China” is the 5th item in the series. In programming we say that its index is “5.” In some programming languages the index numbering starts with “0.” If such is the case, the index of the same “Great Wall of China” would be “4” (0, 1 , 2, 3, 4).
In general, “index” can be used to reference the values of an array or a range (in Excel).
The Index Formula in Excel
In MS Excel, index is a formula that helps us find the value in a specified array.
Syntax of the formula:
Index(< array name >, < row number >, [< col number>])
Where
- Array is an array of values (a list of one or more dimensions)/ a reference to an array.
- Row number is the row index being referred to
- Col number is the column index being referred to
Example 1
In this example we are trying to find the value in the 7th position of the lookup range (the parameter used in the formula).
Here the range is B2 to B9 i.e. Starting from the value “Taj Mahal” (position 1) in B2 until “Great Pyramid of Giza” (position in B9. Visually we can see that Petra is the 7th value in the selected range. Hence, it is the value returned by the formula.
Note: S.no is given in the example for easy understanding and it has nothing to do with the Index formula.
Example 2
Let us try to find the price of the 7th item (“Sambar Idly”) sold at a snack bar. There are two columns here, one with the list of items and the other with the respective price.
Note: Paste this table starting with cell A1 on the Excel sheet for the formula’s range to work.
Item | Price |
Ice cream | 5 |
Sweet corn | 6 |
Spinach Candy | 8 |
Banana Cake | 3 |
Peas Pulao | 40 |
Methi Roti | 30 |
Sambar Idly with ghee | 20 |
Veg clear Soup | 40 |
Masala Papad | 10 |
The formula would be =INDEX(A2:B10,7,2)
Where
A2:B10 is the range of data in the table
7 because we are looking for the 7th item (row-wise)
2 because we want the price of the item. The price is in the 2nd col. And the answer would be 20.
The Index Function in VBA
The Index function in VBA is very simple. Just as in the formula, here we also have to pass the array and the position as parameters. The function then returns the value in that position.
Example 1
In the example below, there is an array of students in a class. Let us assume that we know the roll number of the student who has obtained Rank 1. We are asked to find his/her name.
Sub index_demo() ' declare variables Dim arr_students() Dim first_rank ' initialize the arrayarr_students = Array("John Capps", "Michel Pinny", "Kanya Dhan", "Ron Dincy", "Bella", "Mayur", "Jack finner", "Emi Thinner") ' We know that the fourth student in the array has got the first rank. We need to find his name first_rank = Application.WorksheetFunction.Index(arr_students, 4) 'Display the name of the first rank holder in a messagebox MsgBox first_rank & " is the student who got the first rank." End Sub
Example explained:
To start with, we have declared the required variables. Then we have initiated an array (arr_students) with the list of student names as values.
In order to use the Index function, we should have the array and required position number as parameters. As we have created the array already (arr_students) and we know that the name of the student with the roll number “4” is to be fetched, we proceed to use the function.
Application.WorksheetFunction.Index
(arr_students, 4)
Application refers to the Excel application being used currently.
Worksheetfunction refers to the bunch of functions offered by Excel for any worksheet.
Index is also a worksheetfunction which we are learning to use here.
The output/return value of this function is passed/caught in the variable declared earlier — first_rank
.
Finally, the value of the variable is displayed with a description in a message box.
Example 2
In this example, we will use the worksheetfunction index in VBA but the array that we refer to will be a Range of Excel cells.
Scenario: Some sports personalities ran a race and reached the finish line in a particular order. The array of players is in the finishing order. We are asked to find the runner of the race.
Let’s try to find the person who wins the second place in the competition. This will be our position value in the function.
The range of the array is Range(“B2:B9”).
Knowing the required values, we can proceed with writing the code.
Sub index_demo2() ' declare variables Dim arr_players() Dim runner ' initialize the array arr_players = Range("B2:C9") ' We know that the second player in the array is the runner. We need to find his name runner = Application.WorksheetFunction.Index(arr_players, 2) 'Display the name of the runner in a messagebox MsgBox runner(1) & " is the player who won the second place. His email id is " & runner(2) End Sub
Code explained:
As mentioned in Example 1, we have declared and initialized the variables. Then we use the Index function to find runner (2nd place) of the match.
The flow of the program is the same with the difference that here we have been forced to use runner(1) to display value.
Reason: An Excel range is considered a multidimensional array. Because of this, the return value is not just a string. Instead, it is also an array. To find a value in that array, we have to specify index.
(1) is used here since there is only one value (or we have specified only 1 column in the range).
To understand it better, if we had used the range Range (“B2:C9” ) in our code, then the return value of the index would have both values in Range (“B2”) and Range(“C2”) i.e. All values of (various columns) of the second row (position parameter given in the Index function).
The image above clearly shows the value of the runner object (the returned value). It has both the name and the email address. Suppose, I want to display the email address of the runner, I will have to display runner(2) in the messagebox.
MsgBox runner(1) & " is the player who won the second place. His email id is " & runner(2) <!-- /wp:shortcode --> <!-- wp:image {"id":14452,"sizeSlug":"large","linkDestination":"none"} --> <figure class="wp-block-image size-large"><img src="https://software-solutions-online.com/wp-content/uploads/2021/06/unnamed-11.png" alt="Excel message box that reads &quot;Fred is the player who won the second place. His email id is [email protected]&quot;" class="wp-image-14452"/></figure> <!-- /wp:image --> <!-- wp:heading {"level":3} --> <h3>Example 3</h3> <!-- /wp:heading --> <!-- wp:paragraph --> <p>In the example below, we get the capital of a state whose index is known. So, we are using an array of two dimensions. If we use formula, we refer to the 4<sup>th</sup> row and 2<sup>nd</sup> column of the selected range. So the value of the cell turns out to be “Patna”.</p> <!-- /wp:paragraph --> <!-- wp:image {"id":14457,"sizeSlug":"large","linkDestination":"none"} --> <figure class="wp-block-image size-large"><img src="https://software-solutions-online.com/wp-content/uploads/2021/06/unnamed-12-1024x266.png" alt="Example of using array to find capital states." class="wp-image-14457"/></figure> <!-- /wp:image --> <!-- wp:paragraph --> <p>Let us do the same using VBA.</p> <!-- /wp:paragraph --> <!-- wp:shortcode --> Sub IndexMatch_demo1() ' declare variables Dim required_pos, str_capital, arr_states_cap, capital_col ' initialize variables required_pos = 4 capital_col = 2 arr_states_cap = Range("B2:C16") 'use the function to get the capital str_capital = Application.WorksheetFunction.Index([arr_states_cap], required_pos, 2) ' display the result MsgBox str_capital End Sub
Code explained:
Post declaration and initialization of variables, the Index function is used to get the value in the 4th row, 2nd column of the selected state, capital range of cells on the Excel sheet.
Finally, the output that we see in the message box would be “Patna” which is the capital of Bihar.
The Match Formula and Function
Here is my article about the Match formula in Excel and Match function in VBA:
Using the Match Function in VBA and Excel – VBA and VB.Net Tutorials, Education and Programming Services (software-solutions-online.com)
Using the Index Function with the Match Function
As we have already understood, the Index function gives the value in the known index of an array. The Match function does the opposite. It provides the index value of an item in an array or range of values.
It is possible to use one of these functions within the other. i.e. Match within Index (or) Index within Match.
Example 1
Here is a table that has details of States, Capitals and another column to describe when it was formed (“Founded on”). We are asked to find the “Founded on” value of the state “Maharashtra”.
Let us assume that we do not know its index. So, initially we will use the Match function to find its index.
Once we get that index, using Index we can get the respective values of that index (rows) against all columns.
Sub IndexMatch_demo() 'declare variables Dim strstate, arr_states, arr_capitals, arr_founded, rowposition_state, str_capital, str_founded ' initialize variables ( set values for them ) strstate = "Maharashtra" arr_states = Range("B2:B30") arr_capitals = Range("C2:C30") arr_founded = Range("D2:D30") ' find the position of the state in the first array ( 0 here states an exact match) rowposition_state = Application.WorksheetFunction.Match(strstate, ([arr_states]), 0) 'Find the respective capital and "founded on" values of the said state. str_capital = Application.WorksheetFunction.Index([arr_capitals], rowposition_state) str_founded = Application.WorksheetFunction.Index([arr_founded], rowposition_state) ' display all values Debug.Print str_capital(1) Debug.Print str_founded(1) End Sub
Code explained:
The required variables are first declared and then initialized. From these lines, we infer that we are supposed to find the capital and “Founded on” values of the state “Maharashtra.” So, using the Match function in VBA, we find the position of the state ”Maharashtra.” Then using the same value as the index, we find the capital and “Founded on” values from the respective arrays and display the same in the Immediate window (using the debug.print statement).
In order to explain this further, three arrays were created in the example. If the ranges quoted for each of these arrays are not within the same range ( row values), then this concept of using the same index (row num here) for finding values in other arrays will not work. So, let us redo the same with one range as a subset of another range to understand the concept better.
Sub IndexMatch_demo3() 'declare variables Dim strstate, arr_states, start_pos, end_pos, rowposition_state, str_capital, arr_states_captials ' initialize variables ( set values for them ) strstate = "Maharashtra" start_pos = 2 end_pos = 30 'dynamic defining of the arrays from the excel sheet. The rows values are not hardcoded here. arr_states_captials = Range("B" & start_pos & ":D" & end_pos) arr_states = Range("B" & start_pos & ":B" & end_pos) ' find the position of the state in the states array ( 0 here states an exact match) rowposition_state = Application.WorksheetFunction.Match(strstate, [arr_states], 0) 'Find the respective capital and "founded on" values of the said state. str_capital = Application.WorksheetFunction.Index([arr_states_captials], rowposition_state, 2) str_founded = Application.WorksheetFunction.Index([arr_states_captials], rowposition_state, 3) ' display all values Debug.Print str_capital Debug.Print str_founded End Sub
Code explained:
The difference in this modified code lies in the dynamic building of array range. A single dimensional array is defined in order to find the index using the Match function. Then we find the respective values from the other two columns. The Index function here uses both the row position and col position parameter since the array is multidimensional (a complete picture of this is available in the image above).
Conclusion
In my experience, I see that the Index function can be used with multidimensional arrays but when it comes to the Match function, multidimensional arrays have to be sliced using loops and conditions before being passed as parameters. Using a combination of both these functions (Index and Match), it is possible and easy to point to any value/index/any target in a table or an array or a range of Excel cells. Using them wisely can produce great results.
title | keywords | f1_keywords | ms.prod | api_name | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|---|
WorksheetFunction.Index method (Excel) |
vbaxl10.chm137090 |
vbaxl10.chm137090 |
excel |
Excel.WorksheetFunction.Index |
4656985a-2864-93ed-31c7-e7a551d68e96 |
05/23/2019 |
medium |
WorksheetFunction.Index method (Excel)
Returns a value or the reference to a value from within a table or range. There are two forms of the Index function: the array form and the reference form.
Syntax
expression.Index (Arg1, Arg2, Arg3, Arg4)
expression A variable that represents a WorksheetFunction object.
Parameters
Name | Required/Optional | Data type | Description |
---|---|---|---|
Arg1 | Required | Variant | Array or Reference — a range of cells or an array constant. For references, it is the reference to one or more cell ranges. |
Arg2 | Required | Double | Row_num — selects the row in array from which to return a value. If row_num is omitted, column_num is required. For references, the number of the row in reference from which to return a reference. |
Arg3 | Optional | Variant | Column_num — selects the column in array from which to return a value. If column_num is omitted, row_num is required. For reference, the number of the column in reference from which to return a reference. |
Arg4 | Optional | Variant | Area_num — only used when returning references. Selects a range in reference from which to return the intersection of row_num and column_num. The first area selected or entered is numbered 1, the second is 2, and so on. If area_num is omitted, Index uses area 1. |
Return value
Variant
Remarks
Array form
Returns the value of an element in a table or an array, selected by the row and column number indexes.
Use the array form if the first argument to Index is an array constant.
If both the row_num and column_num arguments are used, Index returns the value in the cell at the intersection of row_num and column_num.
If you set row_num or column_num to 0 (zero), Index returns the array of values for the entire column or row, respectively. To use values returned as an array, enter the Index function as an array formula in a horizontal range of cells for a row, and in a vertical range of cells for a column. To enter an array formula, press Ctrl+Shift+Enter.
Row_num and column_num must point to a cell within array; otherwise, Index returns the #REF! error value.
Reference form
Returns the reference of the cell at the intersection of a particular row and column. If the reference is made up of nonadjacent selections, you can pick the selection to look in. If each area in reference contains only one row or column, the row_num or column_num argument, respectively, is optional. For example, for a single row reference, use INDEX(reference,column_num).
After reference and area_num have selected a particular range, row_num and column_num select a particular cell: row_num 1 is the first row in the range, column_num 1 is the first column, and so on. The reference returned by Index is the intersection of row_num and column_num.
If you set row_num or column_num to 0 (zero), Index returns the reference for the entire column or row, respectively.
Row_num, column_num, and area_num must point to a cell within reference; otherwise, Index returns the #REF! error value. If row_num and column_num are omitted, Index returns the area in reference specified by area_num.
The result of the Index function is a reference and is interpreted as such by other formulas. Depending on the formula, the return value of Index may be used as a reference or as a value. For example, the formula CELL("width",INDEX(A1:B2,1,2))
is equivalent to CELL("width",B1)
. The CELL function uses the return value of Index as a cell reference. On the other hand, a formula such as 2*INDEX(A1:B2,1,2)
translates the return value of Index into the number in cell B1.
[!includeSupport and feedback]
Содержание
- WorksheetFunction.Index method (Excel)
- Syntax
- Parameters
- Return value
- Remarks
- Array form
- Reference form
- Support and feedback
- Объект Range (Excel)
- Примечания
- Пример
- Методы
- Свойства
- См. также
- Поддержка и обратная связь
WorksheetFunction.Index method (Excel)
Returns a value or the reference to a value from within a table or range. There are two forms of the Index function: the array form and the reference form.
Syntax
expression A variable that represents a WorksheetFunction object.
Parameters
Name | Required/Optional | Data type | Description |
---|---|---|---|
Arg1 | Required | Variant | Array or Reference — a range of cells or an array constant. For references, it is the reference to one or more cell ranges. |
Arg2 | Required | Double | Row_num — selects the row in array from which to return a value. If row_num is omitted, column_num is required. For references, the number of the row in reference from which to return a reference. |
Arg3 | Optional | Variant | Column_num — selects the column in array from which to return a value. If column_num is omitted, row_num is required. For reference, the number of the column in reference from which to return a reference. |
Arg4 | Optional | Variant | Area_num — only used when returning references. Selects a range in reference from which to return the intersection of row_num and column_num. The first area selected or entered is numbered 1, the second is 2, and so on. If area_num is omitted, Index uses area 1. |
Return value
Variant
Array form
Returns the value of an element in a table or an array, selected by the row and column number indexes.
Use the array form if the first argument to Index is an array constant.
If both the row_num and column_num arguments are used, Index returns the value in the cell at the intersection of row_num and column_num.
If you set row_num or column_num to 0 (zero), Index returns the array of values for the entire column or row, respectively. To use values returned as an array, enter the Index function as an array formula in a horizontal range of cells for a row, and in a vertical range of cells for a column. To enter an array formula, press Ctrl+Shift+Enter.
Row_num and column_num must point to a cell within array; otherwise, Index returns the #REF! error value.
Reference form
Returns the reference of the cell at the intersection of a particular row and column. If the reference is made up of nonadjacent selections, you can pick the selection to look in. If each area in reference contains only one row or column, the row_num or column_num argument, respectively, is optional. For example, for a single row reference, use INDEX(reference,column_num).
After reference and area_num have selected a particular range, row_num and column_num select a particular cell: row_num 1 is the first row in the range, column_num 1 is the first column, and so on. The reference returned by Index is the intersection of row_num and column_num.
If you set row_num or column_num to 0 (zero), Index returns the reference for the entire column or row, respectively.
Row_num, column_num, and area_num must point to a cell within reference; otherwise, Index returns the #REF! error value. If row_num and column_num are omitted, Index returns the area in reference specified by area_num.
The result of the Index function is a reference and is interpreted as such by other formulas. Depending on the formula, the return value of Index may be used as a reference or as a value. For example, the formula CELL(«width»,INDEX(A1:B2,1,2)) is equivalent to CELL(«width»,B1) . The CELL function uses the return value of Index as a cell reference. On the other hand, a formula such as 2*INDEX(A1:B2,1,2) translates the return value of Index into the number in cell B1.
Support and feedback
Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.
Источник
Объект Range (Excel)
Представляет ячейку, строку, столбец или группу ячеек, содержащую один или несколько смежных блоков ячеек или объемный диапазон.
Хотите создавать решения, которые расширяют возможности Office на разнообразных платформах? Ознакомьтесь с новой моделью надстроек Office. Надстройки Office занимают меньше места по сравнению с надстройками и решениями VSTO, и вы можете создавать их, используя практически любую технологию веб-программирования, например HTML5, JavaScript, CSS3 и XML.
Примечания
Элемент по умолчанию объекта Range направляет вызовы без параметров в свойство Value, а вызовы с параметрами — в элемент Item. Таким образом, someRange = someOtherRange соответствует someRange.Value = someOtherRange.Value , someRange(1) соответствует someRange.Item(1) и someRange(1,1) соответствует someRange.Item(1,1) .
В разделе Пример описаны следующие свойства и методы для возврата объекта Range:
- Свойства Range и Cells объекта Worksheet
- Свойства Range и Cells объекта Range
- Свойства Rows и Columns объекта Worksheet
- Свойства Rows и Columns объекта Range
- Свойство Offset объекта Range
- Метод Union объекта Application
Пример
Чтобы вернуть объект Range, представляющий одну ячейку или диапазон ячеек, используйте синтаксис Range ( arg ), где arg обозначает диапазон. В следующем примере значение ячейки A1 помещается в ячейку A5.
В следующем примере диапазон A1:H8 заполняется случайными числами путем задания формулы для каждой ячейки в диапазоне. При использовании без квалификатора объекта (объекта слева от точки) свойство Range возвращает диапазон на активном листе. Если активное окно не является листом, метод завершается с ошибкой.
Используйте метод Activate объекта Worksheet, чтобы активировать лист перед использованием свойства Range без явного квалификатора объекта.
В следующем примере очищается содержимое диапазона Criteria.
Если используется текстовый аргумент для адреса диапазона, необходимо указать адрес в нотации стиля A1 (нельзя использовать нотацию в стиле R1C1).
Чтобы получить диапазон, содержащий все отдельные ячейки листа, используйте свойство Cells на листе. Вы можете обращаться к отдельным ячейкам, используя синтаксис Item(строка, столбец), где строка — индекс строки, а столбец — индекс столбца. Свойство Item можно пропустить, так как вызов направляется к нему с помощью элемента по умолчанию объекта Range. В следующем примере на первом листе активной книги ячейке A1 присваивается значение 24, а в ячейке B1 — значение 42.
В следующем примере задается формула для ячейки A2.
Хотя также можно использовать Range(«A1») , чтобы вернуть значение ячейки A1, иногда свойство Cells может быть удобнее, так как позволяет использовать переменную для строки или столбца. В следующем примере создаются заголовки столбцов и строк на листе Sheet1. Обратите внимание, что после активации листа можно использовать свойство Cells без явного объявления листа (оно возвращает ячейку на активном листе).
Хотя для изменения ссылок в стиле A1 можно использовать строковые функции Visual Basic, проще (и лучше при программировании) использовать нотацию Cells(1, 1) .
Используйте синтаксис_выражение_.Cells, где выражение возвращает объект Range, чтобы получить диапазон с тем же адресом, состоящий из отдельных ячеек. В таком диапазоне отдельные ячейки доступны с помощью синтаксиса Item(строка, столбец) относительно левого верхнего угла первой области диапазона. Свойство Item можно пропустить, так как вызов направляется к нему с помощью элемента по умолчанию объекта Range. В следующем примере на первом листе активной книги в ячейках C5 и D5 указывается формула.
Чтобы вернуть объект Range, используйте синтаксис Range ( ячейка1, ячейка2 ), где ячейка1 и ячейка2 — это объекты Range, указывающие начальную и конечную ячейки. В следующем примере устанавливается тип линии границы для ячеек A1:J10.
Имейте в виду, что точка перед каждым появлением свойства Cells является обязательной, если результат предыдущего оператора With нужно применять к свойству Cells. В данном случае указано, что ячейки расположены на листе один (без точки свойство Cells будет возвращать ячейки активного листа).
Чтобы получить диапазон, содержащий все строки листа, используйте свойство Rows на листе. Вы можете обращаться к отдельным строкам с помощью синтаксиса Item(строка), где строка — это индекс строки. Свойство Item можно пропустить, так как вызов направляется к нему с помощью элемента по умолчанию объекта Range.
Недопустимо указывать второй параметр свойства Item для диапазонов, состоящих из строк. Сначала нужно преобразовать их в отдельные ячейки, используя свойство Cells.
В следующем примере удаляются строки 5 и 10 первого листа активной книги.
Чтобы получить диапазон, содержащий все столбцы листа, используйте свойство Columns на листе. Вы можете обращаться к отдельным столбцам с помощью синтаксиса Item(строка) [sic], где строка — это индекс столбца в виде числа или адреса столбца в формате А1. Свойство Item можно пропустить, так как вызов направляется к нему с помощью элемента по умолчанию объекта Range.
Недопустимо указывать второй параметр свойства Item для диапазонов, состоящих из столбцов. Сначала нужно преобразовать их в отдельные ячейки, используя свойство Cells.
В следующем примере удаляются столбцы B, C, E и J первого листа активной книги.
Используйте синтаксис_выражение_.Rows, где выражение возвращает объект Range, чтобы получить диапазон, состоящий из строк первой области диапазона. Вы можете обращаться к отдельным строкам с помощью синтаксиса Item(строка), где строка — это относительный индекс строки от верхнего края первой области диапазона. Свойство Item можно пропустить, так как вызов направляется к нему с помощью элемента по умолчанию объекта Range.
Недопустимо указывать второй параметр свойства Item для диапазонов, состоящих из строк. Сначала нужно преобразовать их в отдельные ячейки, используя свойство Cells.
В следующем примере удаляются диапазоны C8:D8 и C6:D6 первого листа активной книги.
Используйте синтаксис_выражение_.Columns, где выражение возвращает объект Range, чтобы получить диапазон, состоящий из столбцов первой области диапазона. Вы можете обращаться к отдельным столбцам с помощью синтаксиса Item(строка) [sic], где строка — это относительный индекс столбца от левого края первой области диапазона, указанный в виде числа или адреса столбца в формате A1. Свойство Item можно пропустить, так как вызов направляется к нему с помощью элемента по умолчанию объекта Range.
Недопустимо указывать второй параметр свойства Item для диапазонов, состоящих из столбцов. Сначала нужно преобразовать их в отдельные ячейки, используя свойство Cells.
В следующем примере удаляются диапазоны L2:L10, G2:G10, F2:F10 и D2:D10 первого листа активной книги.
Чтобы вернуть диапазон с указанным смещением относительно другого диапазона, используйте синтаксис Offset ( строка, столбец ), где строка и столбец — это смещения строк и столбцов. В следующем примере выделяются ячейки, расположенные на три строки вниз и на один столбец вправо от ячейки в левом верхнем углу текущего выделенного фрагмента. Нельзя выбрать ячейку, которая находится не на активном листе, поэтому сначала необходимо активировать лист.
Используйте синтаксис Union ( диапазон1, диапазон2, . ) для возврата диапазонов из нескольких областей, то есть диапазонов, состоящих из двух или более смежных блоков ячеек. В следующем примере создается объект, определенный как объединение диапазонов A1:B2 и C3:D4, а затем выбирается определенный диапазон.
При работе с выделенными фрагментами, содержащими несколько областей, удобно применять свойство Areas. Оно разделяет выделенный фрагмент с несколькими областями на отдельные объекты Range, а затем возвращает объекты в виде коллекции. Используйте свойство Count в возвращенной коллекции, чтобы убедиться, что выделение содержит более одной области, как показано в следующем примере.
В этом примере используется метод AdvancedFilter объекта Range для создания списка уникальных значений, а также количества появлений этих уникальных значений в диапазоне столбца A.
Методы
Свойства
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
Всё о работе с ячейками в Excel-VBA: обращение, перебор, удаление, вставка, скрытие, смена имени.
Содержание:
Table of Contents:
- Что такое ячейка Excel?
- Способы обращения к ячейкам
- Выбор и активация
- Получение и изменение значений ячеек
- Ячейки открытой книги
- Ячейки закрытой книги
- Перебор ячеек
- Перебор в произвольном диапазоне
- Свойства и методы ячеек
- Имя ячейки
- Адрес ячейки
- Размеры ячейки
- Запуск макроса активацией ячейки
2 нюанса:
- Я почти везде стараюсь использовать ThisWorkbook (а не, например, ActiveWorkbook) для обращения к текущей книге, в которой написан этот код (считаю это наиболее безопасным для новичков способом обращения к книгам, чтобы случайно не внести изменения в другие книги). Для экспериментов можете вставлять этот код в модули, коды книги, либо листа, и он будет работать только в пределах этой книги.
- Я использую английский эксель и у меня по стандарту листы называются Sheet1, Sheet2 и т.д. Если вы работаете в русском экселе, то замените Thisworkbook.Sheets(«Sheet1») на Thisworkbook.Sheets(«Лист1»). Если этого не сделать, то вы получите ошибку в связи с тем, что пытаетесь обратиться к несуществующему объекту. Можно также заменить на Thisworkbook.Sheets(1), но это менее безопасно.
Что такое ячейка Excel?
В большинстве мест пишут: «элемент, образованный пересечением столбца и строки». Это определение полезно для людей, которые не знакомы с понятием «таблица». Для того, чтобы понять чем на самом деле является ячейка Excel, необходимо заглянуть в объектную модель Excel. При этом определения объектов «ряд», «столбец» и «ячейка» будут отличаться в зависимости от того, как мы работаем с файлом.
Объекты в Excel-VBA. Пока мы работаем в Excel без углубления в VBA определение ячейки как «пересечения» строк и столбцов нам вполне хватает, но если мы решаем как-то автоматизировать процесс в VBA, то о нём лучше забыть и просто воспринимать лист как «мешок» ячеек, с каждой из которых VBA позволяет работать как минимум тремя способами:
- по цифровым координатам (ряд, столбец),
- по адресам формата А1, B2 и т.д. (сценарий целесообразности данного способа обращения в VBA мне сложно представить)
- по уникальному имени (во втором и третьем вариантах мы будем иметь дело не совсем с ячейкой, а с объектом VBA range, который может состоять из одной или нескольких ячеек). Функции и методы объектов Cells и Range отличаются. Новичкам я бы порекомендовал работать с ячейками VBA только с помощью Cells и по их цифровым координатам и использовать Range только по необходимости.
Все три способа обращения описаны далее
Как это хранится на диске и как с этим работать вне Excel? С точки зрения хранения и обработки вне Excel и VBA. Сделать это можно, например, сменив расширение файла с .xls(x) на .zip и открыв этот архив.
Пример содержимого файла Excel:
Далее xl -> worksheets и мы видим файл листа
Содержимое файла:
То же, но более наглядно:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac xr xr2 xr3" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" xr:uid="{00000000-0001-0000-0000-000000000000}">
<dimension ref="B2:F6"/>
<sheetViews>
<sheetView tabSelected="1" workbookViewId="0">
<selection activeCell="D12" sqref="D12"/>
</sheetView>
</sheetViews>
<sheetFormatPr defaultRowHeight="14.4" x14ac:dyDescent="0.3"/>
<sheetData>
<row r="2" spans="2:6" x14ac:dyDescent="0.3">
<c r="B2" t="s">
<v>0</v>
</c>
</row>
<row r="3" spans="2:6" x14ac:dyDescent="0.3">
<c r="C3" t="s">
<v>1</v>
</c>
</row>
<row r="4" spans="2:6" x14ac:dyDescent="0.3">
<c r="D4" t="s">
<v>2</v>
</c>
</row>
<row r="5" spans="2:6" x14ac:dyDescent="0.3">
<c r="E5" t="s">
<v>0</v></c>
</row>
<row r="6" spans="2:6" x14ac:dyDescent="0.3">
<c r="F6" t="s"><v>3</v>
</c></row>
</sheetData>
<pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
</worksheet>
Как мы видим, в структуре объектной модели нет никаких «пересечений». Строго говоря рабочая книга — это архив структурированных данных в формате XML. При этом в каждую «строку» входит «столбец», и в нём в свою очередь прописан номер значения данного столбца, по которому оно подтягивается из другого XML файла при открытии книги для экономии места за счёт отсутствия повторяющихся значений. Почему это важно. Если мы захотим написать какой-то обработчик таких файлов, который будет напрямую редактировать данные в этих XML, то ориентироваться надо на такую модель и структуру данных. И правильное определение будет примерно таким: ячейка — это объект внутри столбца, который в свою очередь находится внутри строки в файле xml, в котором хранятся данные о содержимом листа.
Способы обращения к ячейкам
Выбор и активация
Почти во всех случаях можно и стоит избегать использования методов Select и Activate. На это есть две причины:
- Это лишь имитация действий пользователя, которая замедляет выполнение программы. Работать с объектами книги можно напрямую без использования методов Select и Activate.
- Это усложняет код и может приводить к неожиданным последствиям. Каждый раз перед использованием Select необходимо помнить, какие ещё объекты были выбраны до этого и не забывать при необходимости снимать выбор. Либо, например, в случае использования метода Select в самом начале программы может быть выбрано два листа вместо одного потому что пользователь запустил программу, выбрав другой лист.
Можно выбирать и активировать книги, листы, ячейки, фигуры, диаграммы, срезы, таблицы и т.д.
Отменить выбор ячеек можно методом Unselect:
Selection.Unselect
Отличие выбора от активации — активировать можно только один объект из раннее выбранных. Выбрать можно несколько объектов.
Если вы записали и редактируете код макроса, то лучше всего заменить Select и Activate на конструкцию With … End With. Например, предположим, что мы записали вот такой макрос:
Sub Macro1()
' Macro1 Macro
Range("F4:F10,H6:H10").Select 'выбрали два несмежных диапазона зажав ctrl
Range("H6").Activate 'показывает только то, что я начал выбирать второй диапазон с этой ячейки (она осталась белой). Это действие ни на что не влияет
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535 'залили желтым цветом, нажав на кнопку заливки на верхней панели
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End Sub
Почему макрос записался таким неэффективным образом? Потому что в каждый момент времени (в каждой строке) программа не знает, что вы будете делать дальше. Поэтому в записи выбор ячеек и действия с ними — это два отдельных действия. Этот код лучше всего оптимизировать (особенно если вы хотите скопировать его внутрь какого-нибудь цикла, который должен будет исполняться много раз и перебирать много объектов). Например, так:
Sub Macro11()
'
' Macro1 Macro
Range("F4:F10,H6:H10").Select '1. смотрим, что за объект выбран (что идёт до .Select)
Range("H6").Activate
With Selection.Interior '2. понимаем, что у выбранного объекта есть свойство interior, с которым далее идёт работа
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End Sub
Sub Optimized_Macro()
With Range("F4:F10,H6:H10").Interior '3. переносим объект напрямую в конструкцию With вместо Selection
' ////// Здесь я для надёжности прописал бы ещё Thisworkbook.Sheet("ИмяЛиста") перед Range,
' ////// чтобы минимизировать риск любых случайных изменений других листов и книг
' ////// With Thisworkbook.Sheet("ИмяЛиста").Range("F4:F10,H6:H10").Interior
.Pattern = xlSolid '4. полностью копируем всё, что было записано рекордером внутрь блока with
.PatternColorIndex = xlAutomatic
.Color = 55555 '5. здесь я поменял цвет на зеленый, чтобы было видно, работает ли код при поочерёдном запуске двух макросов
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End Sub
Пример сценария, когда использование Select и Activate оправдано:
Допустим, мы хотим, чтобы во время исполнения программы мы одновременно изменяли несколько листов одним действием и пользователь видел какой-то определённый лист. Это можно сделать примерно так:
Sub Select_Activate_is_OK()
Thisworkbook.Worksheets(Array("Sheet1", "Sheet3")).Select 'Выбираем несколько листов по именам
Thisworkbook.Worksheets("Sheet3").Activate 'Показываем пользователю третий лист
'Далее все действия с выбранными ячейками через Select будут одновременно вносить изменения в оба выбранных листа
'Допустим, что тут мы решили покрасить те же два диапазона:
Range("F4:F10,H6:H10").Select
Range("H6").Activate
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End Sub
Единственной причиной использовать этот код по моему мнению может быть желание зачем-то показать пользователю определённую страницу книги в какой-то момент исполнения программы. С точки зрения обработки объектов, опять же, эти действия лишние.
Получение и изменение значений ячеек
Значение ячеек можно получать/изменять с помощью свойства value.
'Если нужно прочитать / записать значение ячейки, то используется свойство Value
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value 'записать значение ячейки А1 листа "Sheet1" в переменную "a"
ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value = 1 'задать значение ячейки А1 (первый ряд, первый столбец) листа "Sheet1"
'Если нужно прочитать текст как есть (с форматированием), то можно использовать свойство .text:
ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text = "1"
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text
'Когда проявится разница:
'Например, если мы считываем дату в формате "31 декабря 2021 г.", хранящуюся как дата
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value 'эапишет как "31.12.2021"
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text 'запишет как "31 декабря 2021 г."
Ячейки открытой книги
К ячейкам можно обращаться:
'В книге, в которой хранится макрос (на каком-то из листов, либо в отдельном модуле или форме)
ThisWorkbook.Sheets("Sheet1").Cells(1,1).Value 'По номерам строки и столбца
ThisWorkbook.Sheets("Sheet1").Cells(1,"A").Value 'По номерам строки и букве столбца
ThisWorkbook.Sheets("Sheet1").Range("A1").Value 'По адресу - вариант 1
ThisWorkbook.Sheets("Sheet1").[A1].Value 'По адресу - вариант 2
ThisWorkbook.Sheets("Sheet1").Range("CellName").Value 'По имени ячейки (для этого ей предварительно нужно его присвоить)
'Те же действия, но с использованием полного названия рабочей книги (книга должна быть открыта)
Workbooks("workbook.xlsm").Sheets("Sheet1").Cells(1,1).Value 'По номерам строки и столбца
Workbooks("workbook.xlsm").Sheets("Sheet1").Cells(1,"A").Value 'По номерам строки и букве столбца
Workbooks("workbook.xlsm").Sheets("Sheet1").Range("A1").Value 'По адресу - вариант 1
Workbooks("workbook.xlsm").Sheets("Sheet1").[A1].Value 'По адресу - вариант 2
Workbooks("workbook.xlsm").Sheets("Sheet1").Range("CellName").Value 'По имени ячейки (для этого ей предварительно нужно его присвоить)
Ячейки закрытой книги
Если нужно достать или изменить данные в другой закрытой книге, то необходимо прописать открытие и закрытие книги. Непосредственно работать с закрытой книгой не получится, потому что данные в ней хранятся отдельно от структуры и при открытии Excel каждый раз производит расстановку значений по соответствующим «слотам» в структуре. Подробнее о том, как хранятся данные в xlsx см выше.
Workbooks.Open Filename:="С:closed_workbook.xlsx" 'открыть книгу (она становится активной)
a = ActiveWorkbook.Sheets("Sheet1").Cells(1,1).Value 'достать значение ячейки 1,1
ActiveWorkbook.Close False 'закрыть книгу (False => без сохранения)
Скачать пример, в котором можно посмотреть, как доставать и как записывать значения в закрытую книгу.
Код из файла:
Option Explicit
Sub get_value_from_closed_wb() 'достать значение из закрытой книги
Dim a, wb_path, wsh As String
wb_path = ThisWorkbook.Sheets("Sheet1").Cells(2, 3).Value 'get path to workbook from sheet1
wsh = ThisWorkbook.Sheets("Sheet1").Cells(3, 3).Value
Workbooks.Open Filename:=wb_path
a = ActiveWorkbook.Sheets(wsh).Cells(3, 3).Value
ActiveWorkbook.Close False
ThisWorkbook.Sheets("Sheet1").Cells(4, 3).Value = a
End Sub
Sub record_value_to_closed_wb() 'записать значение в закрытую книгу
Dim wb_path, b, wsh As String
wsh = ThisWorkbook.Sheets("Sheet1").Cells(3, 3).Value
wb_path = ThisWorkbook.Sheets("Sheet1").Cells(2, 3).Value 'get path to workbook from sheet1
b = ThisWorkbook.Sheets("Sheet1").Cells(5, 3).Value 'get value to record in the target workbook
Workbooks.Open Filename:=wb_path
ActiveWorkbook.Sheets(wsh).Cells(4, 4).Value = b 'add new value to cell D4 of the target workbook
ActiveWorkbook.Close True
End Sub
Перебор ячеек
Перебор в произвольном диапазоне
Скачать файл со всеми примерами
Пройтись по всем ячейкам в нужном диапазоне можно разными способами. Основные:
- Цикл For Each. Пример:
Sub iterate_over_cells() For Each c In ThisWorkbook.Sheets("Sheet1").Range("B2:D4").Cells MsgBox (c) Next c End Sub
Этот цикл выведет в виде сообщений значения ячеек в диапазоне B2:D4 по порядку по строкам слева направо и по столбцам — сверху вниз. Данный способ можно использовать для действий, в который вам не важны номера ячеек (закрашивание, изменение форматирования, пересчёт чего-то и т.д.).
- Ту же задачу можно решить с помощью двух вложенных циклов — внешний будет перебирать ряды, а вложенный — ячейки в рядах. Этот способ я использую чаще всего, потому что он позволяет получить больше контроля над исполнением: на каждой итерации цикла нам доступны координаты ячеек. Для перебора всех ячеек на листе этим методом потребуется найти последнюю заполненную ячейку. Пример кода:
Sub iterate_over_cells() Dim cl, rw As Integer Dim x As Variant 'перебор области 3x3 For rw = 1 To 3 ' цикл для перебора рядов 1-3 For cl = 1 To 3 'цикл для перебора столбцов 1-3 x = ThisWorkbook.Sheets("Sheet1").Cells(rw + 1, cl + 1).Value MsgBox (x) Next cl Next rw 'перебор всех ячеек на листе. Последняя ячейка определена с помощью UsedRange 'LastRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count - 1 'LastCol = ActiveSheet.UsedRange.Column + ActiveSheet.UsedRange.Columns.Count - 1 'For rw = 1 To LastRow 'цикл перебора всех рядов ' For cl = 1 To LastCol 'цикл для перебора всех столбцов ' Действия ' Next cl 'Next rw End Sub
- Если нужно перебрать все ячейки в выделенном диапазоне на активном листе, то код будет выглядеть так:
Sub iterate_cell_by_cell_over_selection() Dim ActSheet As Worksheet Dim SelRange As Range Dim cell As Range Set ActSheet = ActiveSheet Set SelRange = Selection 'if we want to do it in every cell of the selected range For Each cell In Selection MsgBox (cell.Value) Next cell End Sub
Данный метод подходит для интерактивных макросов, которые выполняют действия над выбранными пользователем областями.
- Перебор ячеек в ряду
Sub iterate_cells_in_row() Dim i, RowNum, StartCell As Long RowNum = 3 'какой ряд StartCell = 0 ' номер начальной ячейки (минус 1, т.к. в цикле мы прибавляем i) For i = 1 To 10 ' 10 ячеек в выбранном ряду ThisWorkbook.Sheets("Sheet1").Cells(RowNum, i + StartCell).Value = i '(i + StartCell) добавляет 1 к номеру столбца при каждом повторении Next i End Sub
- Перебор ячеек в столбце
Sub iterate_cells_in_column() Dim i, ColNum, StartCell As Long ColNum = 3 'какой столбец StartCell = 0 ' номер начальной ячейки (минус 1, т.к. в цикле мы прибавляем i) For i = 1 To 10 ' 10 ячеек ThisWorkbook.Sheets("Sheet1").Cells(i + StartCell, ColNum).Value = i ' (i + StartCell) добавляет 1 к номеру ряда при каждом повторении Next i End Sub
Свойства и методы ячеек
Имя ячейки
Присвоить новое имя можно так:
Thisworkbook.Sheets(1).Cells(1,1).name = "Новое_Имя"
Для того, чтобы сменить имя ячейки нужно сначала удалить существующее имя, а затем присвоить новое. Удалить имя можно так:
ActiveWorkbook.Names("Старое_Имя").Delete
Пример кода для переименования ячеек:
Sub rename_cell()
old_name = "Cell_Old_Name"
new_name = "Cell_New_Name"
ActiveWorkbook.Names(old_name).Delete
ThisWorkbook.Sheets(1).Cells(2, 1).Name = new_name
End Sub
Sub rename_cell_reverse()
old_name = "Cell_New_Name"
new_name = "Cell_Old_Name"
ActiveWorkbook.Names(old_name).Delete
ThisWorkbook.Sheets(1).Cells(2, 1).Name = new_name
End Sub
Адрес ячейки
Sub get_cell_address() ' вывести адрес ячейки в формате буква столбца, номер ряда
'$A$1 style
txt_address = ThisWorkbook.Sheets(1).Cells(3, 2).Address
MsgBox (txt_address)
End Sub
Sub get_cell_address_R1C1()' получить адрес столбца в формате номер ряда, номер столбца
'R1C1 style
txt_address = ThisWorkbook.Sheets(1).Cells(3, 2).Address(ReferenceStyle:=xlR1C1)
MsgBox (txt_address)
End Sub
'пример функции, которая принимает 2 аргумента: название именованного диапазона и тип желаемого адреса
'(1- тип $A$1 2- R1C1 - номер ряда, столбца)
Function get_cell_address_by_name(str As String, address_type As Integer)
'$A$1 style
Select Case address_type
Case 1
txt_address = Range(str).Address
Case 2
txt_address = Range(str).Address(ReferenceStyle:=xlR1C1)
Case Else
txt_address = "Wrong address type selected. 1,2 available"
End Select
get_cell_address_by_name = txt_address
End Function
'перед запуском нужно убедиться, что в книге есть диапазон с названием,
'адрес которого мы хотим получить, иначе будет ошибка
Sub test_function() 'запустите эту программу, чтобы увидеть, как работает функция
x = get_cell_address_by_name("MyValue", 2)
MsgBox (x)
End Sub
Размеры ячейки
Ширина и длина ячейки в VBA меняется, например, так:
Sub change_size()
Dim x, y As Integer
Dim w, h As Double
'получить координаты целевой ячейки
x = ThisWorkbook.Sheets("Sheet1").Cells(2, 2).Value
y = ThisWorkbook.Sheets("Sheet1").Cells(3, 2).Value
'получить желаемую ширину и высоту ячейки
w = ThisWorkbook.Sheets("Sheet1").Cells(6, 2).Value
h = ThisWorkbook.Sheets("Sheet1").Cells(7, 2).Value
'сменить высоту и ширину ячейки с координатами x,y
ThisWorkbook.Sheets("Sheet1").Cells(x, y).RowHeight = h
ThisWorkbook.Sheets("Sheet1").Cells(x, y).ColumnWidth = w
End Sub
Прочитать значения ширины и высоты ячеек можно двумя способами (однако результаты будут в разных единицах измерения). Если написать просто Cells(x,y).Width или Cells(x,y).Height, то будет получен результат в pt (привязка к размеру шрифта).
Sub get_size()
Dim x, y As Integer
'получить координаты ячейки, с которой мы будем работать
x = ThisWorkbook.Sheets("Sheet1").Cells(2, 2).Value
y = ThisWorkbook.Sheets("Sheet1").Cells(3, 2).Value
'получить длину и ширину выбранной ячейки в тех же единицах измерения, в которых мы их задавали
ThisWorkbook.Sheets("Sheet1").Cells(2, 6).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).ColumnWidth
ThisWorkbook.Sheets("Sheet1").Cells(3, 6).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).RowHeight
'получить длину и ширину с помощью свойств ячейки (только для чтения) в поинтах (pt)
ThisWorkbook.Sheets("Sheet1").Cells(7, 9).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).Width
ThisWorkbook.Sheets("Sheet1").Cells(8, 9).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).Height
End Sub
Скачать файл с примерами изменения и чтения размера ячеек
Запуск макроса активацией ячейки
Для запуска кода VBA при активации ячейки необходимо вставить в код листа нечто подобное:
3 важных момента, чтобы это работало:
1. Этот код должен быть вставлен в код листа (здесь контролируется диапазон D4)
2-3. Программа, ответственная за запуск кода при выборе ячейки, должна называться Worksheet_SelectionChange и должна принимать значение переменной Target, относящейся к триггеру SelectionChange. Другие доступные триггеры можно посмотреть в правом верхнем углу (2).
Скачать файл с базовым примером (как на картинке)
Скачать файл с расширенным примером (код ниже)
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' имеем в виду, что триггер SelectionChange будет запускать эту Sub после каждого клика мышью (после каждого клика будет проверяться:
'1. количество выделенных ячеек и
'2. не пересекается ли выбранный диапазон с заданным в этой программе диапазоном.
' поэтому в эту программу не стоит без необходимости писать никаких других тяжелых операций
If Selection.Count = 1 Then 'запускаем программу только если выбрано не более 1 ячейки
'вариант модификации - брать адрес ячейки из другой ячейки:
'Dim CellName as String
'CellName = Activesheet.Cells(1,1).value 'брать текстовое имя контролируемой ячейки из A1 (должно быть в формате Буква столбца + номер строки)
'If Not Intersect(Range(CellName), Target) Is Nothing Then
'для работы этой модификации следующую строку надо закомментировать/удалить
If Not Intersect(Range("D4"), Target) Is Nothing Then
'если заданный (D4) и выбранный диапазон пересекаются
'(пересечение диапазонов НЕ равно Nothing)
'можно прописать диапазон из нескольких ячеек:
'If Not Intersect(Range("D4:E10"), Target) Is Nothing Then
'можно прописать несколько диапазонов:
'If Not Intersect(Range("D4:E10"), Target) Is Nothing or Not Intersect(Range("A4:A10"), Target) Is Nothing Then
Call program 'выполняем программу
End If
End If
End Sub
Sub program()
MsgBox ("Program Is running") 'здесь пишем код того, что произойдёт при выборе нужной ячейки
End Sub