Vba excel вставить диапазон ячеек

Вырезание, перемещение, копирование и вставка ячеек (диапазонов) в VBA Excel. Методы Cut, Copy и PasteSpecial объекта Range, метод Paste объекта Worksheet.

Метод Range.Cut

Range.Cut – это метод, который вырезает объект Range (диапазон ячеек) в буфер обмена или перемещает его в указанное место на рабочем листе.

Синтаксис

Параметры

Параметры Описание
Destination Необязательный параметр. Диапазон ячеек рабочего листа, в который будет вставлен (перемещен) вырезанный объект Range (достаточно указать верхнюю левую ячейку диапазона). Если этот параметр опущен, объект вырезается в буфер обмена.

Для вставки на рабочий лист диапазона ячеек, вырезанного в буфер обмена методом Range.Cut, следует использовать метод Worksheet.Paste.

Метод Range.Copy

Range.Copy – это метод, который копирует объект Range (диапазон ячеек) в буфер обмена или в указанное место на рабочем листе.

Синтаксис

Параметры

Параметры Описание
Destination Необязательный параметр. Диапазон ячеек рабочего листа, в который будет вставлен скопированный объект Range (достаточно указать верхнюю левую ячейку диапазона). Если этот параметр опущен, объект копируется в буфер обмена.

Метод Worksheet.Paste

Worksheet.Paste – это метод, который вставляет содержимое буфера обмена на рабочий лист.

Синтаксис

Worksheet.Paste (Destination, Link)

Метод Worksheet.Paste работает как с диапазонами ячеек, вырезанными в буфер обмена методом Range.Cut, так и скопированными в буфер обмена методом Range.Copy.

Параметры

Параметры Описание
Destination Необязательный параметр. Диапазон (ячейка), указывающий место вставки содержимого буфера обмена. Если этот параметр не указан, используется текущий выделенный объект.
Link Необязательный параметр. Булево значение, которое указывает, устанавливать ли ссылку на источник вставленных данных: True – устанавливать, False – не устанавливать (значение по умолчанию).

В выражении с методом Worksheet.Paste можно указать только один из параметров: или Destination, или Link.

Для вставки из буфера обмена отдельных компонентов скопированных ячеек (значения, форматы, примечания и т.д.), а также для проведения транспонирования и вычислений, используйте метод Range.PasteSpecial (специальная вставка).

Примеры

Вырезание и вставка диапазона одной строкой (перемещение):

Range(«A1:C3»).Cut Range(«E1»)

Вырезание ячеек в буфер обмена и вставка методом ActiveSheet.Paste:

Range(«A1:C3»).Cut

ActiveSheet.Paste Range(«E1»)

Копирование и вставка диапазона одной строкой:

Range(«A18:C20»).Copy Range(«E18»)

Копирование ячеек в буфер обмена и вставка методом ActiveSheet.Paste:

Range(«A18:C20»).Copy

ActiveSheet.Paste Range(«E18»)

Копирование одной ячейки и вставка ее данных во все ячейки заданного диапазона:

Range(«A1»).Copy Range(«B1:D10»)


На чтение 18 мин. Просмотров 75.2k.

VBA Range

сэр Артур Конан Дойл

Это большая ошибка — теоретизировать, прежде чем кто-то получит данные

Эта статья охватывает все, что вам нужно знать об использовании ячеек и диапазонов в VBA. Вы можете прочитать его от начала до конца, так как он сложен в логическом порядке. Или использовать оглавление ниже, чтобы перейти к разделу по вашему выбору.

Рассматриваемые темы включают свойство смещения, чтение
значений между ячейками, чтение значений в массивы и форматирование ячеек.

Содержание

  1. Краткое руководство по диапазонам и клеткам
  2. Введение
  3. Важное замечание
  4. Свойство Range
  5. Свойство Cells рабочего листа
  6. Использование Cells и Range вместе
  7. Свойство Offset диапазона
  8. Использование диапазона CurrentRegion
  9. Использование Rows и Columns в качестве Ranges
  10. Использование Range вместо Worksheet
  11. Чтение значений из одной ячейки в другую
  12. Использование метода Range.Resize
  13. Чтение Value в переменные
  14. Как копировать и вставлять ячейки
  15. Чтение диапазона ячеек в массив
  16. Пройти через все клетки в диапазоне
  17. Форматирование ячеек
  18. Основные моменты

Краткое руководство по диапазонам и клеткам

Функция Принимает Возвращает Пример Вид
Range адреса
ячеек
диапазон
ячеек
.Range(«A1:A4») $A$1:$A$4
Cells строка,
столбец
одна
ячейка
.Cells(1,5) $E$1
Offset строка,
столбец
диапазон .Range(«A1:A2»)
.Offset(1,2)
$C$2:$C$3
Rows строка (-и) одна или
несколько
строк
.Rows(4)
.Rows(«2:4»)
$4:$4
$2:$4
Columns столбец
(-цы)
один или
несколько
столбцов
.Columns(4)
.Columns(«B:D»)
$D:$D
$B:$D

Введение

Это третья статья, посвященная трем основным элементам VBA. Этими тремя элементами являются Workbooks, Worksheets и Ranges/Cells. Cells, безусловно, самая важная часть Excel. Почти все, что вы делаете в Excel, начинается и заканчивается ячейками.

Вы делаете три основных вещи с помощью ячеек:

  1. Читаете из ячейки.
  2. Пишите в ячейку.
  3. Изменяете формат ячейки.

В Excel есть несколько методов для доступа к ячейкам, таких как Range, Cells и Offset. Можно запутаться, так как эти функции делают похожие операции.

В этой статье я расскажу о каждом из них, объясню, почему они вам нужны, и когда вам следует их использовать.

Давайте начнем с самого простого метода доступа к ячейкам — с помощью свойства Range рабочего листа.

Важное замечание

Я недавно обновил эту статью, сейчас использую Value2.

Вам может быть интересно, в чем разница между Value, Value2 и значением по умолчанию:

' Value2
Range("A1").Value2 = 56

' Value
Range("A1").Value = 56

' По умолчанию используется значение
Range("A1") = 56

Использование Value может усечь число, если ячейка отформатирована, как валюта. Если вы не используете какое-либо свойство, по умолчанию используется Value.

Лучше использовать Value2, поскольку он всегда будет возвращать фактическое значение ячейки.

Свойство Range

Рабочий лист имеет свойство Range, которое можно использовать для доступа к ячейкам в VBA. Свойство Range принимает тот же аргумент, что и большинство функций Excel Worksheet, например: «А1», «А3: С6» и т.д.

В следующем примере показано, как поместить значение в ячейку с помощью свойства Range.

Sub ZapisVYacheiku()

    ' Запишите число в ячейку A1 на листе 1 этой книги
    ThisWorkbook.Worksheets("Лист1").Range("A1").Value2 = 67

    ' Напишите текст в ячейку A2 на листе 1 этой рабочей книги
    ThisWorkbook.Worksheets("Лист1").Range("A2").Value2 = "Иван Петров"

    ' Запишите дату в ячейку A3 на листе 1 этой книги
    ThisWorkbook.Worksheets("Лист1").Range("A3").Value2 = #11/21/2019#

End Sub

Как видно из кода, Range является членом Worksheets, которая, в свою очередь, является членом Workbook. Иерархия такая же, как и в Excel, поэтому должно быть легко понять. Чтобы сделать что-то с Range, вы должны сначала указать рабочую книгу и рабочий лист, которому она принадлежит.

В оставшейся части этой статьи я буду использовать кодовое имя для ссылки на лист.

code name worksheet

Следующий код показывает приведенный выше пример с использованием кодового имени рабочего листа, т.е. Лист1 вместо ThisWorkbook.Worksheets («Лист1»).

Sub IspKodImya ()

    ' Запишите число в ячейку A1 на листе 1 этой книги    
     Sheet1.Range("A1").Value2 = 67

    ' Напишите текст в ячейку A2 на листе 1 этой рабочей книги
    Sheet1.Range("A2").Value2 = "Иван Петров"

    ' Запишите дату в ячейку A3 на листе 1 этой книги
    Sheet1.Range("A3").Value2 = #11/21/2019#

End Sub

Вы также можете писать в несколько ячеек, используя свойство
Range

Sub ZapisNeskol()

    ' Запишите число в диапазон ячеек
    Sheet1.Range("A1:A10").Value2 = 67

    ' Написать текст в несколько диапазонов ячеек
    Sheet1.Range("B2:B5,B7:B9").Value2 = "Иван Петров"

End Sub

Свойство Cells рабочего листа

У Объекта листа есть другое свойство, называемое Cells, которое очень похоже на Range . Есть два отличия:

  1. Cells возвращают диапазон только одной ячейки.
  2. Cells принимает строку и столбец в качестве аргументов.

В приведенном ниже примере показано, как записывать значения
в ячейки, используя свойства Range и Cells.

Sub IspCells()

    ' Написать в А1
    Sheet1.Range("A1").Value2 = 10
    Sheet1.Cells(1, 1).Value2  = 10

    ' Написать в А10
    Sheet1.Range("A10").Value2 = 10
    Sheet1.Cells(10, 1).Value2  = 10

    ' Написать в E1
    Sheet1.Range("E1").Value2 = 10
    Sheet1.Cells(1, 5).Value2  = 10

End Sub

Вам должно быть интересно, когда использовать Cells, а когда Range. Использование Range полезно для доступа к одним и тем же ячейкам при каждом запуске макроса.

Например, если вы использовали макрос для вычисления суммы и
каждый раз записывали ее в ячейку A10, тогда Range подойдет для этой задачи.

Использование свойства Cells полезно, если вы обращаетесь к
ячейке по номеру, который может отличаться. Проще объяснить это на примере.

В следующем коде мы просим пользователя указать номер столбца. Использование Cells дает нам возможность использовать переменное число для столбца.

Sub ZapisVPervuyuPustuyuYacheiku()

    Dim UserCol As Integer
    
    ' Получить номер столбца от пользователя
    UserCol = Application.InputBox("Пожалуйста, введите номер столбца...", Type:=1)
    
    ' Написать текст в выбранный пользователем столбец
    Sheet1.Cells(1, UserCol).Value2 = "Иван Петров"

End Sub

В приведенном выше примере мы используем номер для столбца,
а не букву.

Чтобы использовать Range здесь, потребуется преобразовать эти значения в ссылку на
буквенно-цифровую ячейку, например, «С1». Использование свойства Cells позволяет нам
предоставить строку и номер столбца для доступа к ячейке.

Иногда вам может понадобиться вернуть более одной ячейки, используя номера строк и столбцов. В следующем разделе показано, как это сделать.

Использование Cells и Range вместе

Как вы уже видели, вы можете получить доступ только к одной ячейке, используя свойство Cells. Если вы хотите вернуть диапазон ячеек, вы можете использовать Cells с Range следующим образом:

Sub IspCellsSRange()

    With Sheet1
        ' Запишите 5 в диапазон A1: A10, используя свойство Cells
        .Range(.Cells(1, 1), .Cells(10, 1)).Value2 = 5

        ' Диапазон B1: Z1 будет выделен жирным шрифтом
        .Range(.Cells(1, 2), .Cells(1, 26)).Font.Bold = True

    End With

End Sub

Как видите, вы предоставляете начальную и конечную ячейку
диапазона. Иногда бывает сложно увидеть, с каким диапазоном вы имеете дело,
когда значением являются все числа. Range имеет свойство Address, которое
отображает буквенно-цифровую ячейку для любого диапазона. Это может
пригодиться, когда вы впервые отлаживаете или пишете код.

В следующем примере мы распечатываем адрес используемых нами
диапазонов.

Sub PokazatAdresDiapazona()

    ' Примечание. Использование подчеркивания позволяет разделить строки кода.
    With Sheet1

        ' Запишите 5 в диапазон A1: A10, используя свойство Cells
        .Range(.Cells(1, 1), .Cells(10, 1)).Value2 = 5
        Debug.Print "Первый адрес: " _
            + .Range(.Cells(1, 1), .Cells(10, 1)).Address

        ' Диапазон B1: Z1 будет выделен жирным шрифтом
        .Range(.Cells(1, 2), .Cells(1, 26)).Font.Bold = True
        Debug.Print "Второй адрес : " _
            + .Range(.Cells(1, 2), .Cells(1, 26)).Address

    End With

End Sub

В примере я использовал Debug.Print для печати в Immediate Window. Для просмотра этого окна выберите «View» -> «в Immediate Window» (Ctrl +  G).

ImmediateWindow

ImmediateSampeText

Свойство Offset диапазона

У диапазона есть свойство, которое называется Offset. Термин «Offset» относится к отсчету от исходной позиции. Он часто используется в определенных областях программирования. С помощью свойства «Offset» вы можете получить диапазон ячеек того же размера и на определенном расстоянии от текущего диапазона. Это полезно, потому что иногда вы можете выбрать диапазон на основе определенного условия. Например, на скриншоте ниже есть столбец для каждого дня недели. Учитывая номер дня (т.е. понедельник = 1, вторник = 2 и т.д.). Нам нужно записать значение в правильный столбец.

VBA Offset

Сначала мы попытаемся сделать это без использования Offset.

' Это Sub тесты с разными значениями
Sub TestSelect()

    ' Понедельник
    SetValueSelect 1, 111.21
    ' Среда
    SetValueSelect 3, 456.99
    ' Пятница
    SetValueSelect 5, 432.25
    ' Воскресение
    SetValueSelect 7, 710.17

End Sub

' Записывает значение в столбец на основе дня
Public Sub SetValueSelect(lDay As Long, lValue As Currency)

    Select Case lDay
        Case 1: Sheet1.Range("H3").Value2 = lValue
        Case 2: Sheet1.Range("I3").Value2 = lValue
        Case 3: Sheet1.Range("J3").Value2 = lValue
        Case 4: Sheet1.Range("K3").Value2 = lValue
        Case 5: Sheet1.Range("L3").Value2 = lValue
        Case 6: Sheet1.Range("M3").Value2 = lValue
        Case 7: Sheet1.Range("N3").Value2 = lValue
    End Select

End Sub

Как видно из примера, нам нужно добавить строку для каждого возможного варианта. Это не идеальная ситуация. Использование свойства Offset обеспечивает более чистое решение.

' Это Sub тесты с разными значениями
Sub TestOffset()

    DayOffSet 1, 111.01
    DayOffSet 3, 456.99
    DayOffSet 5, 432.25
    DayOffSet 7, 710.17

End Sub

Public Sub DayOffSet(lDay As Long, lValue As Currency)

    ' Мы используем значение дня с Offset, чтобы указать правильный столбец
    Sheet1.Range("G3").Offset(, lDay).Value2 = lValue

End Sub

Как видите, это решение намного лучше. Если количество дней увеличилось, нам больше не нужно добавлять код. Чтобы Offset был полезен, должна быть какая-то связь между позициями ячеек. Если столбцы Day в приведенном выше примере были случайными, мы не могли бы использовать Offset. Мы должны были бы использовать первое решение.

Следует иметь в виду, что Offset сохраняет размер диапазона. Итак .Range («A1:A3»).Offset (1,1) возвращает диапазон B2:B4. Ниже приведены еще несколько примеров использования Offset.

Sub IspOffset()

    ' Запись в В2 - без Offset
    Sheet1.Range("B2").Offset().Value2 = "Ячейка B2"

    ' Написать в C2 - 1 столбец справа
    Sheet1.Range("B2").Offset(, 1).Value2 = "Ячейка C2"

    ' Написать в B3 - 1 строка вниз
    Sheet1.Range("B2").Offset(1).Value2 = "Ячейка B3"

    ' Запись в C3 - 1 столбец справа и 1 строка вниз
    Sheet1.Range("B2").Offset(1, 1).Value2 = "Ячейка C3"

    ' Написать в A1 - 1 столбец слева и 1 строка вверх
    Sheet1.Range("B2").Offset(-1, -1).Value2 = "Ячейка A1"

    ' Запись в диапазон E3: G13 - 1 столбец справа и 1 строка вниз
    Sheet1.Range("D2:F12").Offset(1, 1).Value2 = "Ячейки E3:G13"

End Sub

Использование диапазона CurrentRegion

CurrentRegion возвращает диапазон всех соседних ячеек в данный диапазон. На скриншоте ниже вы можете увидеть два CurrentRegion. Я добавил границы, чтобы прояснить CurrentRegion.

VBA CurrentRegion

Строка или столбец пустых ячеек означает конец CurrentRegion.

Вы можете вручную проверить
CurrentRegion в Excel, выбрав диапазон и нажав Ctrl + Shift + *.

Если мы возьмем любой диапазон
ячеек в пределах границы и применим CurrentRegion, мы вернем диапазон ячеек во
всей области.

Например:

Range («B3»). CurrentRegion вернет диапазон B3:D14

Range («D14»). CurrentRegion вернет диапазон B3:D14

Range («C8:C9»). CurrentRegion вернет диапазон B3:D14 и так далее

Как пользоваться

Мы получаем CurrentRegion следующим образом

' CurrentRegion вернет B3:D14 из приведенного выше примера
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

Только чтение строк данных

Прочитать диапазон из второй строки, т.е. пропустить строку заголовка.

' CurrentRegion вернет B3:D14 из приведенного выше примера
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

' Начало в строке 2 - строка после заголовка
Dim i As Long
For i = 2 To rg.Rows.Count
    ' текущая строка, столбец 1 диапазона
    Debug.Print rg.Cells(i, 1).Value2
Next i

Удалить заголовок

Удалить строку заголовка (т.е. первую строку) из диапазона. Например, если диапазон — A1:D4, это возвратит A2:D4

' CurrentRegion вернет B3:D14 из приведенного выше примера
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

' Удалить заголовок
Set rg = rg.Resize(rg.Rows.Count - 1).Offset(1)

' Начните со строки 1, так как нет строки заголовка
Dim i As Long
For i = 1 To rg.Rows.Count
    ' текущая строка, столбец 1 диапазона
    Debug.Print rg.Cells(i, 1).Value2
Next i

Использование Rows и Columns в качестве Ranges

Если вы хотите что-то сделать со всей строкой или столбцом,
вы можете использовать свойство «Rows и
Columns
» на рабочем листе. Они оба принимают один параметр — номер строки
или столбца, к которому вы хотите получить доступ.

Sub IspRowIColumns()

    ' Установите размер шрифта столбца B на 9
    Sheet1.Columns(2).Font.Size = 9

    ' Установите ширину столбцов от D до F
    Sheet1.Columns("D:F").ColumnWidth = 4

    ' Установите размер шрифта строки 5 до 18
    Sheet1.Rows(5).Font.Size = 18

End Sub

Использование Range вместо Worksheet

Вы также можете использовать Cella, Rows и Columns, как часть Range, а не как часть Worksheet. У вас может быть особая необходимость в этом, но в противном случае я бы избегал практики. Это делает код более сложным. Простой код — твой друг. Это уменьшает вероятность ошибок.

Код ниже выделит второй столбец диапазона полужирным. Поскольку диапазон имеет только две строки, весь столбец считается B1:B2

Sub IspColumnsVRange()

    ' Это выделит B1 и B2 жирным шрифтом.
    Sheet1.Range("A1:C2").Columns(2).Font.Bold = True

End Sub

Чтение значений из одной ячейки в другую

В большинстве примеров мы записали значения в ячейку. Мы
делаем это, помещая диапазон слева от знака равенства и значение для размещения
в ячейке справа. Для записи данных из одной ячейки в другую мы делаем то же
самое. Диапазон назначения идет слева, а диапазон источника — справа.

В следующем примере показано, как это сделать:

Sub ChitatZnacheniya()

    ' Поместите значение из B1 в A1
    Sheet1.Range("A1").Value2 = Sheet1.Range("B1").Value2

    ' Поместите значение из B3 в лист2 в ячейку A1
    Sheet1.Range("A1").Value2 = Sheet2.Range("B3").Value2

    ' Поместите значение от B1 в ячейки A1 до A5
    Sheet1.Range("A1:A5").Value2 = Sheet1.Range("B1").Value2

    ' Вам необходимо использовать свойство «Value», чтобы прочитать несколько ячеек
    Sheet1.Range("A1:A5").Value2 = Sheet1.Range("B1:B5").Value2

End Sub

Как видно из этого примера, невозможно читать из нескольких ячеек. Если вы хотите сделать это, вы можете использовать функцию копирования Range с параметром Destination.

Sub KopirovatZnacheniya()

    ' Сохранить диапазон копирования в переменной
    Dim rgCopy As Range
    Set rgCopy = Sheet1.Range("B1:B5")

    ' Используйте это для копирования из более чем одной ячейки
    rgCopy.Copy Destination:=Sheet1.Range("A1:A5")

    ' Вы можете вставить в несколько мест назначения
    rgCopy.Copy Destination:=Sheet1.Range("A1:A5,C2:C6")

End Sub

Функция Copy копирует все, включая формат ячеек. Это тот же результат, что и ручное копирование и вставка выделения. Подробнее об этом вы можете узнать в разделе «Копирование и вставка ячеек»

Использование метода Range.Resize

При копировании из одного диапазона в другой с использованием присваивания (т.е. знака равенства) диапазон назначения должен быть того же размера, что и исходный диапазон.

Использование функции Resize позволяет изменить размер
диапазона до заданного количества строк и столбцов.

Например:

Sub ResizePrimeri()
 
    ' Печатает А1
    Debug.Print Sheet1.Range("A1").Address

    ' Печатает A1:A2
    Debug.Print Sheet1.Range("A1").Resize(2, 1).Address

    ' Печатает A1:A5
    Debug.Print Sheet1.Range("A1").Resize(5, 1).Address
    
    ' Печатает A1:D1
    Debug.Print Sheet1.Range("A1").Resize(1, 4).Address
    
    ' Печатает A1:C3
    Debug.Print Sheet1.Range("A1").Resize(3, 3).Address
    
End Sub

Когда мы хотим изменить наш целевой диапазон, мы можем
просто использовать исходный размер диапазона.

Другими словами, мы используем количество строк и столбцов
исходного диапазона в качестве параметров для изменения размера:

Sub Resize()

    Dim rgSrc As Range, rgDest As Range
    
    ' Получить все данные в текущей области
    Set rgSrc = Sheet1.Range("A1").CurrentRegion

      ' Получить диапазон назначения
    Set rgDest = Sheet2.Range("A1")
    Set rgDest = rgDest.Resize(rgSrc.Rows.Count, rgSrc.Columns.Count)
    
    rgDest.Value2 = rgSrc.Value2

End Sub

Мы можем сделать изменение размера в одну строку, если нужно:

Sub Resize2()

    Dim rgSrc As Range
    
    ' Получить все данные в ткущей области
    Set rgSrc = Sheet1.Range("A1").CurrentRegion
    
    With rgSrc
        Sheet2.Range("A1").Resize(.Rows.Count, .Columns.Count) = .Value2
    End With
    
End Sub

Чтение Value в переменные

Мы рассмотрели, как читать из одной клетки в другую. Вы также можете читать из ячейки в переменную. Переменная используется для хранения значений во время работы макроса. Обычно вы делаете это, когда хотите манипулировать данными перед тем, как их записать. Ниже приведен простой пример использования переменной. Как видите, значение элемента справа от равенства записывается в элементе слева от равенства.

Sub IspVar()

    ' Создайте
    Dim val As Integer

    ' Читать число из ячейки
    val = Sheet1.Range("A1").Value2

    ' Добавить 1 к значению
    val = val + 1

    ' Запишите новое значение в ячейку
    Sheet1.Range("A2").Value2 = val

End Sub

Для чтения текста в переменную вы используете переменную
типа String.

Sub IspVarText()

    ' Объявите переменную типа string
    Dim sText As String

    ' Считать значение из ячейки
    sText = Sheet1.Range("A1").Value2

    ' Записать значение в ячейку
    Sheet1.Range("A2").Value2 = sText

End Sub

Вы можете записать переменную в диапазон ячеек. Вы просто
указываете диапазон слева, и значение будет записано во все ячейки диапазона.

Sub VarNeskol()

    ' Считать значение из ячейки
    Sheet1.Range("A1:B10").Value2 = 66

End Sub

Вы не можете читать из нескольких ячеек в переменную. Однако
вы можете читать массив, который представляет собой набор переменных. Мы
рассмотрим это в следующем разделе.

Как копировать и вставлять ячейки

Если вы хотите скопировать и вставить диапазон ячеек, вам не
нужно выбирать их. Это распространенная ошибка, допущенная новыми пользователями
VBA.

Вы можете просто скопировать ряд ячеек, как здесь:

Range("A1:B4").Copy Destination:=Range("C5")

При использовании этого метода копируется все — значения,
форматы, формулы и так далее. Если вы хотите скопировать отдельные элементы, вы
можете использовать свойство PasteSpecial
диапазона.

Работает так:

Range("A1:B4").Copy
Range("F3").PasteSpecial Paste:=xlPasteValues
Range("F3").PasteSpecial Paste:=xlPasteFormats
Range("F3").PasteSpecial Paste:=xlPasteFormulas

В следующей таблице приведен полный список всех типов вставок.

Виды вставок
xlPasteAll
xlPasteAllExceptBorders
xlPasteAllMergingConditionalFormats
xlPasteAllUsingSourceTheme
xlPasteColumnWidths
xlPasteComments
xlPasteFormats
xlPasteFormulas
xlPasteFormulasAndNumberFormats
xlPasteValidation
xlPasteValues
xlPasteValuesAndNumberFormats

Чтение диапазона ячеек в массив

Вы также можете скопировать значения, присвоив значение
одного диапазона другому.

Range("A3:Z3").Value2 = Range("A1:Z1").Value2

Значение диапазона в этом примере считается вариантом массива. Это означает, что вы можете легко читать из диапазона ячеек в массив. Вы также можете писать из массива в диапазон ячеек. Если вы не знакомы с массивами, вы можете проверить их в этой статье.

В следующем коде показан пример использования массива с
диапазоном.

Sub ChitatMassiv()

    ' Создать динамический массив
    Dim StudentMarks() As Variant

    ' Считать 26 значений в массив из первой строки
    StudentMarks = Range("A1:Z1").Value2

    ' Сделайте что-нибудь с массивом здесь

    ' Запишите 26 значений в третью строку
    Range("A3:Z3").Value2 = StudentMarks

End Sub

Имейте в виду, что массив, созданный для чтения, является
двумерным массивом. Это связано с тем, что электронная таблица хранит значения
в двух измерениях, то есть в строках и столбцах.

Пройти через все клетки в диапазоне

Иногда вам нужно просмотреть каждую ячейку, чтобы проверить значение.

Вы можете сделать это, используя цикл For Each, показанный в следующем коде.

Sub PeremeschatsyaPoYacheikam()

    ' Пройдите через каждую ячейку в диапазоне
    Dim rg As Range
    For Each rg In Sheet1.Range("A1:A10,A20")
        ' Распечатать адрес ячеек, которые являются отрицательными
        If rg.Value < 0 Then
            Debug.Print rg.Address + " Отрицательно."
        End If
    Next

End Sub

Вы также можете проходить последовательные ячейки, используя
свойство Cells и стандартный цикл For.

Стандартный цикл более гибок в отношении используемого вами
порядка, но он медленнее, чем цикл For Each.

Sub PerehodPoYacheikam()
 
    ' Пройдите клетки от А1 до А10
    Dim i As Long
    For i = 1 To 10
        ' Распечатать адрес ячеек, которые являются отрицательными
        If Range("A" & i).Value < 0 Then
            Debug.Print Range("A" & i).Address + " Отрицательно."
        End If
    Next
 
    ' Пройдите в обратном порядке, то есть от A10 до A1
    For i = 10 To 1 Step -1
        ' Распечатать адрес ячеек, которые являются отрицательными
        If Range("A" & i) < 0 Then
            Debug.Print Range("A" & i).Address + " Отрицательно."
        End If
    Next
 
End Sub

Форматирование ячеек

Иногда вам нужно будет отформатировать ячейки в электронной
таблице. Это на самом деле очень просто. В следующем примере показаны различные
форматы, которые можно добавить в любой диапазон ячеек.

Sub FormatirovanieYacheek()

    With Sheet1

        ' Форматировать шрифт
        .Range("A1").Font.Bold = True
        .Range("A1").Font.Underline = True
        .Range("A1").Font.Color = rgbNavy

        ' Установите числовой формат до 2 десятичных знаков
        .Range("B2").NumberFormat = "0.00"
        ' Установите числовой формат даты
        .Range("C2").NumberFormat = "dd/mm/yyyy"
        ' Установите формат чисел на общий
        .Range("C3").NumberFormat = "Общий"
        ' Установить числовой формат текста
        .Range("C4").NumberFormat = "Текст"

        ' Установите цвет заливки ячейки
        .Range("B3").Interior.Color = rgbSandyBrown

        ' Форматировать границы
        .Range("B4").Borders.LineStyle = xlDash
        .Range("B4").Borders.Color = rgbBlueViolet

    End With

End Sub

Основные моменты

Ниже приводится краткое изложение основных моментов

  1. Range возвращает диапазон ячеек
  2. Cells возвращают только одну клетку
  3. Вы можете читать из одной ячейки в другую
  4. Вы можете читать из диапазона ячеек в другой диапазон ячеек.
  5. Вы можете читать значения из ячеек в переменные и наоборот.
  6. Вы можете читать значения из диапазонов в массивы и наоборот
  7. Вы можете использовать цикл For Each или For, чтобы проходить через каждую ячейку в диапазоне.
  8. Свойства Rows и Columns позволяют вам получить доступ к диапазону ячеек этих типов

Синтаксис

  • 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 также имеет параметр «Вставить транспонирование», который также обновляет формулы транспонированных ячеек.

 

cdj100

Пользователь

Сообщений: 29
Регистрация: 13.12.2019

#1

22.03.2022 10:55:58

Добрый день, форумчане. Подскажите, пжлст, как правильно закончить код копирования диапазона из разных книг и вставки диапазона один за другим, начиная с пустой строки?

Код копирования диапазона из одной книги, выглядит таким образом:

Код
Sub Get_Value_From_Close_Book()
    Dim sShName As String, sAddress As String, vData
    Dim objCloseBook As Object
    '"Отключаем обновление экрана"
    Application.ScreenUpdating = False
    Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA schedule.xlsx")
    sAddress = "D12:D18" '"или одна ячейка - "A1""
    '"получаем значениe"
    vData = objCloseBook.Sheets("Sheet1").Range(sAddress).Value
    '"Записываем данные на активный лист книги"
    '"с которой запустили макрос"
    Range("A1:A100").Clear '"Очищаем диапазон, от старых данных"
    If IsArray(vData) Then
        [A1].Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
    Else
      [A1] = vData
    End If
    '"если надо копировать ячейки с форматами"
    '"то можно использовать стандартные методы копирования вставки"
    '"objCloseBook.Sheets("Лист1").Range(sAddress).Copy"
    '"[A1].PasteSpecial xlPasteValues  'вставляем значения"
    '"[A1].PasteSpecial xlPasteFormats '"вставляем форматы"
    '"закрываем книгу(из которой получали значения) без сохранения"
    objCloseBook.Close False
    '"Включаем обновление экрана"
    Application.ScreenUpdating = True
End Sub
 

Пытливый

Пользователь

Сообщений: 4587
Регистрация: 22.12.2012

Там надо не закончить, а чуток структуру перестроить, т.к. вы (наверное) будете циклом по именам файлов проходить, открывать их, копировать и потом вставлять.
Так вот, ДО цикла очищаем старые данные, задали номер строки с которой вставляем данные (например, со 2).
Потом запускаем цикл — открыли файл, скопировали нужное, вставили с заданной строки, закрыли файл, откуда копировали.
Нашли первую пустую строку после вставленных данных, изменили значение номера строки для вставки
Повторили цикл.

Изменено: Пытливый22.03.2022 11:07:05

Кому решение нужно — тот пример и рисует.

 

cdj100

Пользователь

Сообщений: 29
Регистрация: 13.12.2019

Согласен с Вашим подходом.
Как будет в этом случае выглядеть цикл и как выглядит код поиска и вставки скопированного диапазона с новой строки? С этим основная сложность.
Буду благодарен, если сможете помочь написать такой код, я с VBA не очень силен.

 

Пытливый

Пользователь

Сообщений: 4587
Регистрация: 22.12.2012

#4

22.03.2022 12:06:07

Можно типа такого:

Код
Dim lngI as Long, intI as Integer
'до цикла чистим заполненный с прошлого раза диапазон, определяем номер строки с которой вставляем
Range("A1").СurrentRegion.Clear
lngI = 1
'Пушшаем цикл по открытию, копированию-вставке и т.д.
'например, нам надо открыть 13 файлов, скопировать, вставить и прочее
For intI =1 to 13
'тут инструкции по открытию файла, копированию нужной области
'потом инструкции по вставке скопированного с нужной строки:
Range("A" & lngI).PasteSpecial xlPasteValue
lngI=Cells(Rows.Count,1).end(xlUp).row+1 'определяем номер пустой строки после вставки по столбцу А
'и не забыть закрыть файл, откуда копировали.
Next intI  

Изменено: Пытливый22.03.2022 12:08:03

Кому решение нужно — тот пример и рисует.

 

cdj100

Пользователь

Сообщений: 29
Регистрация: 13.12.2019

#5

22.03.2022 13:09:01

Спасибо, вставляет с пустой строки, но не диапазон из второй книги.
Где мне необходимо прописать адрес и диапазон второй книги? На всякий случай высылаю файлы исходники.

Код
Sub name()
Dim lngI As Long, intI As Integer
Dim sShName As String, sAddress As String, vData
'"до цикла чистим заполненный с прошлого раза диапазон, определяем номер строки с которой вставляем"
Range("A1:A100").Clear
lngI = 1
'"Пушшаем цикл по открытию, копированию-вставке и т.д."
'"например, нам надо открыть 2 файла, скопировать, вставить и прочее"
For intI = 1 To 2
    Dim objCloseBook As Object
    '"Отключаем обновление экрана"
    Application.ScreenUpdating = False
    Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA1.xlsx")
    sAddress = "D12:D16" '"или одна ячейка - "A1""
    '"получаем значениe"
    vData = objCloseBook.Sheets("Sheet1").Range(sAddress).Value
    '"Записываем данные на активный лист книги"
    '"с которой запустили макрос"
    If IsArray(vData) Then
        [A1].Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
    Else
      [A1] = vData
    End If
    objCloseBook.Close False
    '"Включаем обновление экрана"
    Application.ScreenUpdating = True
Range("A" & lngI).PasteSpecial xlPasteValue
lngI = Cells(Rows.Count, 1).End(xlUp).Row + 1 '"определяем номер пустой строки после вставки по столбцу А"
'"и не забыть закрыть файл, откуда копировали."
    
    '"Отключаем обновление экрана"
    Application.ScreenUpdating = False
    Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA2.xlsx")
    sAddress = "D12:D16" '"или одна ячейка - "A1""
    '"получаем значениe"
    vData = objCloseBook.Sheets("Sheet1").Range(sAddress).Value
    '"Записываем данные на активный лист книги"
    '"с которой запустили макрос"
    If IsArray(vData) Then
        [A1].Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
    Else
      [A1] = vData
    End If
    objCloseBook.Close False
Next intI

End Sub

Прикрепленные файлы

  • QA2.xlsx (8.2 КБ)
  • QA1.xlsx (8.2 КБ)
  • QA final.xlsm (43.52 КБ)

 

Пытливый

Пользователь

Сообщений: 4587
Регистрация: 22.12.2012

#6

22.03.2022 13:20:07

Вы вот этой инструкцией

Код
Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA1.xlsx")

определяете из какой книги будете копировать данные.
Если книги различаются только числом в названии, то можно так:

Код
Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA" & intI & ".xlsx")

т.е. мы получаем на каждой итерации цикла новый путь к файлу, подставляя в текстовой строке значение счетчика цикла.
При первом прогоне будет имя файла
Set objCloseBook = GetObject(«C:Userspavlpid6DesktopIdeasQA matrix newQA1.xlsx»)
при втором
Set objCloseBook = GetObject(«C:Userspavlpid6DesktopIdeasQA matrix newQA2.xlsx»)
и так далее

Кому решение нужно — тот пример и рисует.

 

cdj100

Пользователь

Сообщений: 29
Регистрация: 13.12.2019

#7

22.03.2022 16:02:50

С пустой строки по-прежнему не вставляет диапазон с другой книги.
Некорректная последовательность в коде? Где именно?
Спасибо

Код
Sub Get_Value_From_Close_Book33()
    Dim sShName As String, sAddress As String, vData
    Dim objCloseBook As Object
Dim lngI As Long, intI As Integer
Application.ScreenUpdating = False
Range("A1:A100").Clear
lngI = 1
For intI = 1 To 2
Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA1.xlsx")
Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA2.xlsx")
    sAddress = "D12:D18"
    vData = objCloseBook.Sheets("Sheet1").Range(sAddress).Value
        If IsArray(vData) Then
        [A1].Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
    Else
      [A1] = vData
    End If
objCloseBook.Close False
Application.ScreenUpdating = True
Range("A" & lngI).PasteSpecial xlPasteValue
lngI = Cells(Rows.Count, 1).End(xlUp).Row + 1
Next intI
End Sub
 

Пытливый

Пользователь

Сообщений: 4587
Регистрация: 22.12.2012

#8

22.03.2022 17:46:45

Код
For intI = 1 To 2
'этой инструкцией вы в переменную objColseBook пишете ссылку на объект (книгу) откуда хотите копировать данные
'Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA1.xlsx")
'а следующей инструкцией в ту же переменную пишете уже НОВУЮ ссылку на НОВУЮ книгу. Не надо ее вообще писать, ссылка сама
'поменяется при новой итерации цикла
'Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA2.xlsx")
'вот так (в текстовую строку подставляем счетчик цикла):
Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA" & intI & ".xlsx")
    sAddress = "D12:D18"
    vData = objCloseBook.Sheets("Sheet1").Range(sAddress).Value
        If IsArray(vData) Then
        [A1].Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
    Else
      [A1] = vData
    End If
objCloseBook.Close False
Application.ScreenUpdating = True
Range("A" & lngI).PasteSpecial xlPasteValue
lngI = Cells(Rows.Count, 1).End(xlUp).Row + 1
Next intI

поставьте в редакторе курсор на название процедуры и вдумчиво давите F8 (пошаговое выполнение). Смотрите какие значения переменные принимают, куда какие значения записываются. Помогает понять ход выполнения и найти ошибки.

Изменено: Пытливый22.03.2022 17:48:35

Кому решение нужно — тот пример и рисует.

 

cdj100

Пользователь

Сообщений: 29
Регистрация: 13.12.2019

#9

22.03.2022 22:29:28

На этом куске кода, перезаписывается с ячейки А1 (цикл пошел по второму разу), а не с последней пустой в столбце А. Ожидается что со второго файла запись начнется с A6.
Уточните пжлст почему?

Код
lngI = Cells(Rows.Count, 1).End(xlUp).Row + 1
 

Пытливый

Пользователь

Сообщений: 4587
Регистрация: 22.12.2012

при пошаговом выполнении после 1 итерации цикла в lngI при выполнении этой инструкции какое значение?

Кому решение нужно — тот пример и рисует.

 

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

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

#11

23.03.2022 10:37:54

Цитата
Пытливый написал:
после 1 итерации цикла в lngI при выполнении этой инструкции какое значение?

Да какая разница? Вставка-то идет все равно в [A1] :)

Код
 If IsArray(vData) Then
        [A1].Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
    Else
      [A1] = vData
    End If

правильно так:

Код
If IsArray(vData) Then
    Range("A" & lngI).Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
Else
    Range("A" & lngI) = vData
End If

P.S. cdj100, на сайте, откуда Вы код этот взяли — есть полноценный код получения данных из нескольких книг с возможностью указать имена листов и диапазоны копирования.

Изменено: Дмитрий(The_Prist) Щербаков23.03.2022 10:38:22

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

Пытливый

Пользователь

Сообщений: 4587
Регистрация: 22.12.2012

тьфу ты. :) Слепая тетеря я … :)

Кому решение нужно — тот пример и рисует.

 

cdj100

Пользователь

Сообщений: 29
Регистрация: 13.12.2019

#13

23.03.2022 20:37:29

, работает, большое спасибо!  :)  Следующим шагом как раз и планировалось организовать сбор данных из разных книг. Получился код ниже.
Параллельно, возникла потребность просуммировать данные по условию, я реализовал это след. образом: но в итоговый файл сумма не отображается. Подскажите, в в чем ошибка? (возможно должна быть создана отдельная тема?)

Код
Sub Get_Value_From_Close_Book33()
    Dim sShName As String, sAddress As String, vData
    Dim objCloseBook As Object
Dim lngI As Long, intI As Integer
Application.ScreenUpdating = False
Range("A1:C15").Select
Selection.ClearContents

lngI = 1
For intI = 1 To 1
Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQA1.xlsx")
sAddress = "Application.SumIf(.[С12:С17], [A12], .[E12:F17])"
vData = objCloseBook.Sheets("Sheet1").Range(sAddress).Value
If IsArray(vData) Then
Range("A" & lngI).Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
Else
Range("A" & lngI) = vData
End If
objCloseBook.Close False
Application.ScreenUpdating = True
lngI = Cells(Rows.Count, 1).End(xlUp).Row + 2

Set objCloseBook = GetObject("C:Userspavlpid6DesktopIdeasQA matrix newQAline.xlsx")
sAddress = "Application.SumIf(.[С12:С17], [A12], .[E12:F17])"
vData = objCloseBook.Sheets("Sheet1").Range(sAddress).Value
If IsArray(vData) Then
Range("A" & lngI).Resize(UBound(vData, 1), UBound(vData, 2)).Value = vData
Else
Range("A" & lngI) = vData
End If
objCloseBook.Close False
Application.ScreenUpdating = True
lngI = Cells(Rows.Count, 1).End(xlUp).Row + 2
Next
End Sub

Строка суммирования в итоговый файл (QA final) по условию.

Код
sAddress = "Application.SumIf(.[С12:С17], [A12], .[E12:F17])"

Прикрепленные файлы

  • QA1.xlsx (8.41 КБ)
  • QAline.xlsx (8.41 КБ)
  • QA final.xlsm (45.6 КБ)

 

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

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

#14

24.03.2022 08:41:48

Цитата
cdj100 написал:
должна быть создана отдельная тема?

да.

Цитата
cdj100 написал:
Строка суммирования в итоговый файл

это кто такую строку Вам посоветовал? Думаете, она что-то должна суммировать, да еще и записанная в Range в качестве адреса ячеек? Думаю, Вам срочно надо начать изучать VBA — притом с самых азов…

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

cdj100

Пользователь

Сообщений: 29
Регистрация: 13.12.2019

#15

24.03.2022 10:06:22

С удовольствием, однако текущие условия требуют оперативного решения.

Копирование/вставка диапазона

Nikolay86

Дата: Среда, 26.10.2016, 17:18 |
Сообщение № 1

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

Добрый вечер.
Задача: В файле Primer с листа1 необходимо скопировать диапазон ячеек С20:I26 (количество строк будет постоянно меняться и определяться как «последняя заполненая -8») и вставить на лист2 следующим образом: ячейки столбца «С» листа1 вставить в столбец «B» листа2 начиная с ячейки «В14» и до «последней заполненной -12» (в примере это В24), ячейки столбца «D» листа1 в столбец «С» начиная с С14 и до «последней заполненной -12» и т.д. (в примере понятно какие куда вставлять по названию столбцов)
Пояснение: Последние 12 заполненных строк должны оставаться нетронутыми и как бы ползать вниз/вверх по листу в зависимости от количества вставляемых строк.

К сообщению приложен файл:

Primer.xls
(98.5 Kb)

Сообщение отредактировал Nikolay86Среда, 26.10.2016, 17:36

 

Ответить

sboy

Дата: Среда, 26.10.2016, 17:32 |
Сообщение № 2

Группа: Друзья

Ранг: Участник клуба

Сообщений: 2566


Репутация:

724

±

Замечаний:
0% ±


Excel 2010

И Вам добрый вечер…


Яндекс: 410016850021169

 

Ответить

KuklP

Дата: Среда, 26.10.2016, 17:59 |
Сообщение № 3

Группа: Проверенные

Ранг: Старожил

Сообщений: 2369


Репутация:

486

±

Замечаний:
0% ±


2003-2010

+5
Тут ТС хоть поздоровался, прежде чем понукать форумчанами. :) Nikolay86, Техзадания, задачи у нас ставят здесь


Ну с НДС и мы чего-то стoим! kuklp60@gmail.com
WM Z206653985942, R334086032478, U238399322728

 

Ответить

sboy

Дата: Четверг, 27.10.2016, 12:06 |
Сообщение № 4

Группа: Друзья

Ранг: Участник клуба

Сообщений: 2566


Репутация:

724

±

Замечаний:
0% ±


Excel 2010


Не сразу… но исправился

Сообщение отредактировал Nikolay86 — Среда, 26.10.2016, 17:36


Яндекс: 410016850021169

 

Ответить

sboy

Дата: Четверг, 27.10.2016, 14:30 |
Сообщение № 5

Группа: Друзья

Ранг: Участник клуба

Сообщений: 2566


Репутация:

724

±

Замечаний:
0% ±


Excel 2010

Добрый день.
Если правильно понял задачу, вот совместное решение с макрорекодером
[vba]

Код

Sub Скругленныйпрямоугольник1_Щелчок()
With ActiveSheet
    ilr = .Cells(20, 3).End(xlDown).Row
    irows = ilr — 19
    Set rMaterial = .Range(Cells(20, 3), Cells(ilr, 4))
    Set rArtikul = .Range(Cells(20, 6), Cells(ilr, 6))
    Set rFact = .Range(Cells(20, 9), Cells(ilr, 9))
End With
Sheets(2).Activate
With ActiveSheet
    ir1 = .Cells.Find(What:=»Наименование материала», After:=ActiveCell, LookIn:= _
            xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
            xlNext, MatchCase:=False, SearchFormat:=False).Row + 2

                ir2 = .Cells.Find(What:=»бочки п/эт», After:=ActiveCell, LookIn:=xlFormulas, _
            LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
            MatchCase:=False, SearchFormat:=False).Row — 2
    If ir2 > ir1 Then .Rows(ir1 & «:» & ir2).Delete (xlUp)
        For x = 0 To irows — 1
        .Rows(ir1 + x).Insert xlShiftDown
        Next x
    rArtikul.Copy
   .Cells(ir1, 1).Select
  .Paste
  rMaterial.Copy
  .Cells(ir1, 2).Select
  .Paste
  rFact.Copy
  .Cells(ir1, 5).Select
  .Paste
End With
End Sub

[/vba]

К сообщению приложен файл:

9646934.xls
(98.0 Kb)


Яндекс: 410016850021169

 

Ответить

Nikolay86

Дата: Четверг, 27.10.2016, 21:42 |
Сообщение № 6

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

hands Спасибо и доброй ночи), Вы все правильно поняли, все работает как надо, код понятен! Возникла пара вопросов: почему , а не xlValues мы же вроде как раз значение ищем? И…
что такое ТС?)

P.S. В моем случае этого конечно не предвидится, но макрос чувствителен к пустым ячейкам в списке материалов

ilr = .Cells(20, 3).End(xlDown).Row

просто интересно как в таком случае корректно скопировать все материалы)

 

Ответить

Pelena

Дата: Четверг, 27.10.2016, 22:27 |
Сообщение № 7

Группа: Админы

Ранг: Местный житель

Сообщений: 18797


Репутация:

4284

±

Замечаний:
±


Excel 2016 & Mac Excel


«Черт возьми, Холмс! Но как??!!»
Ю-money 41001765434816

 

Ответить

Nikolay86

Дата: Понедельник, 07.11.2016, 22:26 |
Сообщение № 8

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

Доброго времени суток уважаемые форумчане. При доработке макроса под себя столкнулся с трудностями :'( . Предложенное решение от sboy (за что огромное спасибо) работает, но макрос корректно выполняется только с первого листа, а мне необходимо со второго. Нашел решение, но остался вопрос:
[vba]

Код

Sub Скругленныйпрямоугольник1_Щелчок()
‘Sheets(1).Activate ‘(если раскомментировать то работает с Листа2, но при выполнении макроса «моргает» переключением листов)
With ActiveSheet   ‘(Вопрос: почему если вместо ActiveSheet вставить просто ThisWorkbook.Sheets(1) не работает с Листа2? пишет ошибку в строке Set rMaterial = .Ra…)
    ilr = .Cells(20, 3).End(xlDown).Row
    irows = ilr — 19
    Set rMaterial = .Range(Cells(20, 3), Cells(ilr, 4))
    Set rArtikul = .Range(Cells(20, 6), Cells(ilr, 6))
    Set rFact = .Range(Cells(20, 9), Cells(ilr, 9))
End With

[/vba]

К сообщению приложен файл:

123.xls
(90.5 Kb)

Сообщение отредактировал Nikolay86Понедельник, 07.11.2016, 22:27

 

Ответить

_Boroda_

Дата: Понедельник, 07.11.2016, 23:06 |
Сообщение № 9

Группа: Модераторы

Ранг: Местный житель

Сообщений: 16618


Репутация:

6465

±

Замечаний:
0% ±


2003; 2007; 2010; 2013 RUS

Немного по-другому написал
[vba]

Код

Sub tt()
    Application.ScreenUpdating = 0
    With Sheets(«Лист1»)
        r10_ = 20
        r11_ = .Range(«I» & Rows.Count).End(xlUp).Row
        If r11_ < r10_ Then
            Exit Sub
        Else
            n_ = r11_ — r10_ + 1
        End If
    End With
    With Sheets(«Лист2»)
        r20_ = 14
        r21_ = .Range(«E» & Rows.Count).End(xlUp).Row
        If r21_ >= r20_ Then
            .Rows(r20_ & «:» & r21_).Delete
        Else
            r21_ = r20_
        End If
        .Rows(r20_ & «:» & r20_ + n_ — 1).Insert
        Sheets(«Лист1»).Range(«C» & r10_).Resize(n_, 2).Copy .Range(«B» & r20_)
        Sheets(«Лист1»).Range(«F» & r10_).Resize(n_).Copy .Range(«A» & r20_)
        Sheets(«Лист1»).Range(«I» & r10_).Resize(n_).Copy .Range(«E» & r20_)
    End With
    Application.ScreenUpdating = 1
End Sub

[/vba]

К сообщению приложен файл:

123_1.xls
(92.0 Kb)


Скажи мне, кудесник, любимец ба’гов…
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995

 

Ответить

Nikolay86

Дата: Вторник, 08.11.2016, 21:16 |
Сообщение № 10

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

0

±

Замечаний:
20% ±


Excel 2007

Спасибо _Boroda_, так тоже работает, даже, наверно, немножко лучше, так как нет зависимости от «бочки п/эт». hands

 

Ответить

Понравилась статья? Поделить с друзьями:
  • Vba excel вставить график
  • Vba excel ввод формулы в ячейку
  • Vba excel ввод только чисел
  • Vba excel ввод символа
  • Vba excel ввод данных в ячейку