Вставка диапазона со сдвигом ячеек вправо или вниз методом Insert объекта Range. Вставка и перемещение строк и столбцов из кода VBA Excel. Примеры.
Range.Insert – это метод, который вставляет диапазон пустых ячеек (в том числе одну ячейку) на рабочий лист Excel в указанное место, сдвигая существующие в этом месте ячейки вправо или вниз. Если в буфере обмена содержится объект Range, то вставлен будет он со своими значениями и форматами.
Синтаксис
Expression.Insert(Shift, CopyOrigin) |
Expression – выражение (переменная), возвращающее объект Range.
Параметры
Параметр | Описание | Значения |
---|---|---|
Shift | Необязательный параметр. Определяет направление сдвига ячеек. Если параметр Shift опущен, направление выбирается в зависимости от формы* диапазона. | xlShiftDown (-4121) – ячейки сдвигаются вниз; xlShiftToRight (-4161) – ячейки сдвигаются вправо. |
CopyOrigin | Необязательный параметр. Определяет: из каких ячеек копировать формат. По умолчанию формат копируется из ячеек сверху или слева. | xlFormatFromLeftOrAbove (0) – формат копируется из ячеек сверху или слева; xlFormatFromRightOrBelow (1) – формат копируется из ячеек снизу или справа. |
* Если диапазон горизонтальный или квадратный (количество строк меньше или равно количеству столбцов), ячейки сдвигаются вниз. Если диапазон вертикальный (количество строк больше количества столбцов), ячейки сдвигаются вправо.
Примеры
Простая вставка диапазона
Вставка диапазона ячеек в диапазон «F5:K9» со сдвигом исходных ячеек вправо:
Range(«F5:K9»).Insert Shift:=xlShiftToRight |
Если бы параметр Shift не был указан, сдвиг ячеек, по умолчанию, произошел бы вниз, так как диапазон горизонтальный.
Вставка вырезанного диапазона
Вставка диапазона, вырезанного в буфер обмена методом Range.Cut, из буфера обмена со сдвигом ячеек по умолчанию:
Range(«A1:B6»).Cut Range(«D2»).Insert |
Обратите внимание, что при использовании метода Range.Cut, точка вставки (в примере: Range("D2")
) не может находится внутри вырезанного диапазона, а также в строке или столбце левой верхней ячейки вырезанного диапазона вне вырезанного диапазона (в примере: строка 1 и столбец «A»).
Вставка скопированного диапазона
Вставка диапазона, скопированного в буфер обмена методом Range.Copy, из буфера обмена со сдвигом ячеек по умолчанию:
Range(«B2:D10»).Copy Range(«F2»).Insert |
Обратите внимание, что при использовании метода Range.Copy, точка вставки (в примере: Range("F2")
) не может находится внутри скопированного диапазона, но в строке или столбце левой верхней ячейки скопированного диапазона вне скопированного диапазона находится может.
Вставка и перемещение строк
Вставка одной строки на место пятой строки со сдвигом исходной строки вниз:
Вставка четырех строк на место пятой-восьмой строк со сдвигом исходных строк вниз:
Вставка строк с использованием переменных, указывающих над какой строкой осуществить вставку и количество вставляемых строк:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Sub Primer1() Dim n As Long, k As Long, s As String ‘Номер строки, над которой необходимо вставить строки n = 8 ‘Количесто вставляемых строк k = 4 ‘Указываем адрес диапазона строк s = n & «:» & (n + k — 1) ‘Вставляем строки Rows(s).Insert End Sub ‘или то же самое с помощью цикла Sub Primer2() Dim n As Long, k As Long, i As Long n = 8 k = 4 For i = 1 To k Rows(n).Insert Next End Sub |
Перемещение второй строки на место шестой строки:
Rows(2).Cut Rows(6).Insert |
Вторая строка окажется на месте пятой строки, так как третья строка заместит вырезанную вторую строку, четвертая встанет на место третьей и т.д.
Перемещение шестой строки на место второй строки:
Rows(6).Cut Rows(2).Insert |
В этом случае шестая строка окажется на месте второй строки.
Вставка и перемещение столбцов
Вставка одного столбца на место четвертого столбца со сдвигом исходного столбца вправо:
Вставка трех столбцов на место четвертого-шестого столбцов со сдвигом исходных столбцов вправо:
Перемещение третьего столбца на место седьмого столбца:
Columns(3).Cut Columns(7).Insert |
Третий столбец окажется на месте шестого столбца, так как четвертый столбец заместит вырезанный третий столбец, пятый встанет на место четвертого и т.д.
Перемещение седьмого столбца на место третьего столбца:
Columns(7).Cut Columns(3).Insert |
В этом случае седьмой столбец окажется на месте третьего столбца.
Вас может заинтересовать, а как можно сдвинуться влево или вправо назад или вперед от текущей ячейки. Для этого у объекта Range есть метод Offset, который и позволяет производить подобные действия.
Sub Test() Dim cur_range As Range Set cur_range = Range("A1") Set cur_range = cur_range.Offset(1, 0) Debug.Print cur_range.Address End Sub
А вот результат работы. Мы от текущего объекта сдвинулись влево на 1 колонку.
$A$2
Если вы хотите узнать максимальные размеры листа, то у Вас есть возможность это сделать используя UsedRange. У вас будет объект типа Range, из которого вы сможете узнать максимальную колонку или строку.
Sub Test() With ActiveSheet Dim cur_range As Range Set cur_range = .UsedRange Debug.Print cur_range.Address End With End Sub
Адресовать ячейки можно и двумя цифрами по колонки и сроке. Это избавляет Вас от утомительного разбора адресов типа $A10. Так как адрес строка придеться её резать и собирать. Использования Cells(x,y) очень гибко в использовании и позволяет строить легкие циклы. Пример ниже находит на листе левый верхний угол из всех ячеек с введенными данными и в эту ячейку записывает слово.
Sub Test() ' объект Range Dim cur_range As Range ' Весь лист With ActiveSheet Set cur_range = .UsedRange Debug.Print cur_range.Address ' у меня печатает $C$5:$J$48 Dim y_min As Integer ' минимальная колонка y_min = cur_range.Columns.Column Dim x_min As Integer ' минимальная строка x_min = cur_range.Rows.Row Set cur_range = Range(Cells(x_min, y_min), Cells(x_min, y_min)) cur_range = "lef up" End With End Sub
Синтаксис
- Set — оператор, используемый для установки ссылки на объект, например, на диапазон
- Для каждого — оператор, используемый для прокрутки каждого элемента в коллекции
замечания
Обратите внимание, что имена переменных r
, cell
и другие могут быть названы, как вам нравится, но должны быть названы соответствующим образом, чтобы код был более понятным для вас и других.
Создание диапазона
Диапазон нельзя создать или заполнить так же, как строка:
Sub RangeTest()
Dim s As String
Dim r As Range 'Specific Type of Object, with members like Address, WrapText, AutoFill, etc.
' This is how we fill a String:
s = "Hello World!"
' But we cannot do this for a Range:
r = Range("A1") '//Run. Err.: 91 Object variable or With block variable not set//
' We have to use the Object approach, using keyword Set:
Set r = Range("A1")
End Sub
Считается лучшей практикой, чтобы квалифицировать ваши ссылки , поэтому в дальнейшем мы будем использовать один и тот же подход.
Подробнее о создании объектных переменных (например, Range) в MSDN . Подробнее о Set Statement на MSDN .
Существуют разные способы создания одного и того же диапазона:
Sub SetRangeVariable()
Dim ws As Worksheet
Dim r As Range
Set ws = ThisWorkbook.Worksheets(1) ' The first Worksheet in Workbook with this code in it
' These are all equivalent:
Set r = ws.Range("A2")
Set r = ws.Range("A" & 2)
Set r = ws.Cells(2, 1) ' The cell in row number 2, column number 1
Set r = ws.[A2] 'Shorthand notation of Range.
Set r = Range("NamedRangeInA2") 'If the cell A2 is named NamedRangeInA2. Note, that this is Sheet independent.
Set r = ws.Range("A1").Offset(1, 0) ' The cell that is 1 row and 0 columns away from A1
Set r = ws.Range("A1").Cells(2,1) ' Similar to Offset. You can "go outside" the original Range.
Set r = ws.Range("A1:A5").Cells(2) 'Second cell in bigger Range.
Set r = ws.Range("A1:A5").Item(2) 'Second cell in bigger Range.
Set r = ws.Range("A1:A5")(2) 'Second cell in bigger Range.
End Sub
Обратите внимание на пример, что ячейки (2, 1) эквивалентны диапазону («A2»). Это происходит потому, что Cells возвращает объект Range.
Некоторые источники: Chip Pearson-Cells Within Ranges ; Объект диапазона MSDN ; John Walkenback — ссылка на диапазоны в коде VBA .
Также обратите внимание, что в любом случае, когда число используется в объявлении диапазона, а сам номер находится вне кавычек, например Range («A» & 2), вы можете поменять это число на переменную, содержащую целое число / долго. Например:
Sub RangeIteration()
Dim wb As Workbook, ws As Worksheet
Dim r As Range
Set wb = ThisWorkbook
Set ws = wb.Worksheets(1)
For i = 1 To 10
Set r = ws.Range("A" & i)
' When i = 1, the result will be Range("A1")
' When i = 2, the result will be Range("A2")
' etc.
' Proof:
Debug.Print r.Address
Next i
End Sub
Если вы используете двойные циклы, ячейки лучше:
Sub RangeIteration2()
Dim wb As Workbook, ws As Worksheet
Dim r As Range
Set wb = ThisWorkbook
Set ws = wb.Worksheets(1)
For i = 1 To 10
For j = 1 To 10
Set r = ws.Cells(i, j)
' When i = 1 and j = 1, the result will be Range("A1")
' When i = 2 and j = 1, the result will be Range("A2")
' When i = 1 and j = 2, the result will be Range("B1")
' etc.
' Proof:
Debug.Print r.Address
Next j
Next i
End Sub
Способы обращения к одной ячейке
Самый простой способ ссылаться на одну ячейку на текущем листе Excel — это просто вставить форму А1 в ссылку в квадратных скобках:
[a3] = "Hello!"
Обратите внимание, что квадратные скобки — это просто удобный синтаксический сахар для метода Evaluate
объекта Application
, так что технически это идентично следующему коду:
Application.Evaluate("a3") = "Hello!"
Вы также можете вызвать метод Cells
который принимает строку и столбец и возвращает ссылку на ячейку.
Cells(3, 1).Formula = "=A1+A2"
Помните, что всякий раз, когда вы передаете строку и столбец в Excel из VBA, строка всегда первая, за ней следует столбец, что запутывает, потому что это противоположно общей нотации A1
где сначала отображается столбец.
В обоих этих примерах мы не указали рабочий лист, поэтому Excel будет использовать активный лист (лист, который находится впереди в пользовательском интерфейсе). Вы можете указать активный лист явно:
ActiveSheet.Cells(3, 1).Formula = "=SUM(A1:A2)"
Или вы можете указать имя определенного листа:
Sheets("Sheet2").Cells(3, 1).Formula = "=SUM(A1:A2)"
Существует множество методов, которые можно использовать для перехода от одного диапазона к другому. Например, метод Rows
может использоваться для доступа к отдельным строкам любого диапазона, и метод Cells
может использоваться для доступа к отдельным ячейкам строки или столбца, поэтому следующий код относится к ячейке C1:
ActiveSheet.Rows(1).Cells(3).Formula = "hi!"
Сохранение ссылки на ячейку переменной
Чтобы сохранить ссылку на ячейку в переменной, вы должны использовать синтаксис Set
, например:
Dim R as Range
Set R = ActiveSheet.Cells(3, 1)
потом…
R.Font.Color = RGB(255, 0, 0)
Почему требуется ключевое слово Set
? Set
указывает Visual Basic, что значение в правой части =
означает объект.
Смещение недвижимости
- Смещение (строки, столбцы) — оператор, используемый для статической ссылки на другую точку из текущей ячейки. Часто используется в циклах. Следует понимать, что положительные числа в разделе строк перемещаются вправо, поскольку негативы перемещаются влево. С положительными позициями столбцов вниз и негативы двигаются вверх.
т.е.
Private Sub this()
ThisWorkbook.Sheets("Sheet1").Range("A1").Offset(1, 1).Select
ThisWorkbook.Sheets("Sheet1").Range("A1").Offset(1, 1).Value = "New Value"
ActiveCell.Offset(-1, -1).Value = ActiveCell.Value
ActiveCell.Value = vbNullString
End Sub
Этот код выбирает B2, помещает туда новую строку, затем перемещает эту строку обратно в A1 после очистки B2.
Как перемещать диапазоны (по горизонтали по вертикали и наоборот)
Sub TransposeRangeValues()
Dim TmpArray() As Variant, FromRange as Range, ToRange as Range
set FromRange = Sheets("Sheet1").Range("a1:a12") 'Worksheets(1).Range("a1:p1")
set ToRange = ThisWorkbook.Sheets("Sheet1").Range("a1") 'ThisWorkbook.Sheets("Sheet1").Range("a1")
TmpArray = Application.Transpose(FromRange.Value)
FromRange.Clear
ToRange.Resize(FromRange.Columns.Count,FromRange.Rows.Count).Value2 = TmpArray
End Sub
Примечание. Copy / PasteSpecial также имеет параметр «Вставить транспонирование», который также обновляет формулы транспонированных ячеек.
Перенос строки вверх или вниз |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
Марго_ 0 / 0 / 0 Регистрация: 30.11.2015 Сообщений: 8 |
||||
1 |
||||
Перемещение строки25.05.2018, 11:03. Показов 3349. Ответов 11 Метки нет (Все метки)
Добрый день! Пишу макрос, который должен вставлять на заранее опреденённое место (эта часть кода работает) строку, содержащую в ячейке с текст «ПСД», затем удалять её. Возникает ошибка на строке Selection.Insert Shift:=xlDown. Причём иногда макрос срабатывает, иногда нет. Также периодически выполнение останавливается на строке Selection.Copy. Помогите, пожалуйста, решить проблему
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
25.05.2018, 11:03 |
11 |
2630 / 1636 / 744 Регистрация: 23.03.2015 Сообщений: 5,141 |
|
25.05.2018, 11:48 |
2 |
Марго_, прикрепите файл- легче будет понять и помочь….
0 |
Vlad999 3827 / 2254 / 751 Регистрация: 02.11.2012 Сообщений: 5,930 |
||||
25.05.2018, 13:16 |
3 |
|||
избавляйтесь от не нужных селектов.
по вопросу, с файлом будет проще разобраться. pusto вы случаем не определяете последнюю заполненную ячейку?
0 |
Narimanych 2630 / 1636 / 744 Регистрация: 23.03.2015 Сообщений: 5,141 |
||||||||
25.05.2018, 13:43 |
4 |
|||||||
Марго_, строчка 27 вашего текста сдвигает все на 1 строку вниз, поэтому удалять вам надо не
строка 29
Попробуйте.
0 |
0 / 0 / 0 Регистрация: 30.11.2015 Сообщений: 8 |
|
25.05.2018, 13:48 [ТС] |
5 |
Про то, что удалить (строка +1) — исправила. Проблема именно со строкой Selection.Insert Shift:=xlDown. Через раз запускается, работает как надо, но бывает, что выдаёт ошибку Миниатюры
0 |
Narimanych 2630 / 1636 / 744 Регистрация: 23.03.2015 Сообщений: 5,141 |
||||
25.05.2018, 14:44 |
6 |
|||
Сообщение было отмечено Марго_ как решение РешениеМарго_,
Добавлено через 1 минуту
1 |
0 / 0 / 0 Регистрация: 30.11.2015 Сообщений: 8 |
|
25.05.2018, 14:53 [ТС] |
7 |
Большое спасибо! Теперь всё идеально. А если потребуется перенести строку не на тот же, а на другой лист?
0 |
1813 / 1135 / 346 Регистрация: 11.07.2014 Сообщений: 4,002 |
|
25.05.2018, 14:59 |
8 |
Марго_, думаю, что вы просто хотите вставить то, что скопировали
0 |
Марго_ 0 / 0 / 0 Регистрация: 30.11.2015 Сообщений: 8 |
||||
25.05.2018, 15:12 [ТС] |
9 |
|||
Напимер, скопировать Строку 8 Листа 7 на место Строки 7 Листа 2 Добавлено через 7 минут
0 |
Burk 1813 / 1135 / 346 Регистрация: 11.07.2014 Сообщений: 4,002 |
||||
25.05.2018, 15:20 |
10 |
|||
Сообщение было отмечено Марго_ как решение РешениеМарго_, как пример третья строка первого листа во вторую второго
1 |
Narimanych 2630 / 1636 / 744 Регистрация: 23.03.2015 Сообщений: 5,141 |
||||
25.05.2018, 15:24 |
11 |
|||
Марго_,
0 |
0 / 0 / 0 Регистрация: 30.11.2015 Сообщений: 8 |
|
25.05.2018, 15:56 [ТС] |
12 |
Большое спасибо за помощь!
0 |
Excel is the most commonly used spreadsheet management software. VBA , or Visual Basic for Applications, takes it a step further and makes it easy for you to automate just about anything in Excel (check out this tutorial for a quick into to VBA). In today’s tutorial, we’re going to show you how to use the Offset function in VBA, to select a cell or a range of cells. You require basic familiarity with both Excel and VBA.
If you’re new to them, no problem, you can try out our course for VBA with Excel.
What is the Offset Function
The OffSet() returns the value of the cell, at an offset that you’ve specified. The syntax of this function looks like this:
OffSet(Cell reference, rows, columns, height, width)
Here’s what each parameter means
- Cell reference: refers to a single cell or range of cells.
- Rows: specify the number of rows away from the given cell. If the value entered is negative, the given cell shifts to the left.
- Columns: specify the number of columns away from the given cell. If value is negative, the cell shifts up.
Note that height and width are optional. They are used to specify the height and width of the returned range in cells. You can insert the OffSet() formula in any cell in the worksheet, except obviously, the cells from which you want the offset.
Combining Range() with OffSet()
The OffSet property is usually used in tandem with the Range property to specify a new location. Let’s take a look at this example
Range("B1").Offset(RowOffSet:=1, ColumnOffset:=1).Select
This code will select C2. The parameter RowOffSet is used to move 1 row from cell B1. Similarly, the parameter ColumnOffSet is used to move 1 column from cell B1. Note that the parameters have to be separated by a comma.
An easier way to accomplish the same result is to use a shorthand method, like we show below
Range("A1").Offset(1, 1).Select.
Here we only specified the numbers for the row and column offset. VBA will internally “know” that the first one is for the row offset, while the second one is for the column offset. If you’d like to explore the Range() function more, you can take a look at our course on VBA macros. Now, let’s move on to some more examples.
How to Specify Only Rows
It’s possible to specify just the rows and not the columns. Here’s how you can do it.
Range("B1").Offset(1).Select
Here we’ve omitted the column parameter and its comma. This code results in only moving 1 row down from the original cell location. It will select the entire row, not just a single cell.
How to Specify Only Columns
Similarly it’s possible to just specify the columns and omit the rows. The code will look like this:
Range("B1").Offset(, 1 ).Select
The comma is necessary for Excel to know that only column offset has been set.
How to Specify Negative OffSet
Can you guess how to do this? It’s simple enough. Here’s the code
Range("D2").Offset(-1, -1 ).Select
This makes the selection go up 1 row and 1 column from the starting position. That is from cell D2 we move up to cell C1.
How to OffSet a Range of Cells
It is also possible to specify more than one cell for the Range. Say you want to select or get the offset for a range of cells
Range("B1:D4").Offset(1, 1).Select
Here, we start off with the range of cells from B1 to D4. The objective is to offset this complete range of cells by 1 row and 1 column. The new range of cells will be from C2 to E5.
Combining Active Cell with Offset
The active cell refers to the currently selected cell. Let’s check a few examples that involve active cells. Here is the code to move one cell down from the currently selected cells is
ActiveCell.Offset(1,0).Select
Combining Active Cell with Range() and Offset()
The following code selects a cell in addition to four more to the right which are to be copied/pasted in another location.
Range(ActiveCell,ActiveCell.Offset(0,4)).Copy
Take note that there is a comma after the first ActiveCell instance and a double closing parenthesis before the Copy. Let us now move on to cover simple programs that use OffSet functionality to obtain desired results.
Example 1: To Count the Rows in an Excel Worksheet
Sub CountNumRows() Dim Count1 as Long Count1 = 0 Do Count1 = Count1 + 1 ActiveCell.Offset(1, 0).Select Loop Until IsEmpty(ActiveCell.Offset(0, 1)) MsgBox "There are" Count1 "Rows" End Sub
In this program, we declared Count1 as a variable of type long. Count is incremented by 1. Then OffSet() is used to loop through the rows. When an empty row is encountered the loop terminates. The variable count1 contains the total number of rows.MsgBox() displays a pop-up box with the total number of rows.
Example 2: Combining Range with OffSet to Fill a Range of Cells with Even Numbers from 1 to 100.
Sub prog1() Dim Num Num = 0 For Row = 0 To 9 For Col = 0 To 9 Range(“A1”).Offset(Row, Col).Value = Num Num = Num + 2 Next Col Next Row End Sub
In this program, A1 is the given cell and the resultant range is from A1 to J10. Variable Num is initialized to zero and is incremented by the value 2 each time in the loop. The resultant range of cells contain each and every even number without duplicates from 1 to 100.
Hope you found the offset function useful, and can now use it in your own programs. We have just covered the tip of the iceberg. There’s lots more to it. You can check out more details with this ultimate VBA course, and if you’d like to hop over to advanced Macros we just the right course with Mr Excel!