Vba excel копирование диапазона ячеек в другую книгу
Чтобы переменной присвоить диапазон ячеек, она должна быть объявлена как Variant, Object или Range:
Чтобы было понятнее, для чего переменная создана, объявляйте ее как Range.
Присваивается переменной диапазон ячеек с помощью оператора Set:
В выражении Range(Cells(3, 4), Cells(26, 18)) вместо чисел можно использовать переменные.
Для присвоения диапазона ячеек переменной можно использовать встроенное диалоговое окно Application.InputBox, которое позволяет выбрать диапазон на рабочем листе для дальнейшей работы с ним.
Адресация ячеек в диапазоне
К ячейкам присвоенного диапазона можно обращаться по их индексам, а также по индексам строк и столбцов, на пересечении которых они находятся.
Индексация ячеек в присвоенном диапазоне осуществляется слева направо и сверху вниз, например, для диапазона размерностью 5х5:
1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
Индексация строк и столбцов начинается с левой верхней ячейки. В диапазоне этого примера содержится 5 строк и 5 столбцов. На пересечении 2 строки и 4 столбца находится ячейка с индексом 9. Обратиться к ней можно так:
Задача состоит в том, чтобы скопировать определенный диапазон текущего листа, открыть другую книгу, и вставить эти скопированные данные в определенную ячейку, сохранить этот файл и закрыть. Ниже приведен код VBA.
Вариант 2: В открывшейся книге запускаем макрос, чтобы он открыл нужную нам книгу, скопировал от туда нужные нам данные и вставил в нашу открытую книгу, закрыв файл из которого эти данные были скопированы
Еще пример — Скопировать диапазоны данных из активной открытой книги Excel нескольких листов (в нашем примере 3-х листов) в другую книгу, которая хранится в определенном месте. Данные будут вставлены как значения, плюс будут перенесены форматы ячеек.
Если статья была вам полезна, то буду благодарен, если вы поделитесь ей со своими друзьями с помощью кнопок расположенных ниже.
Спасибо за внимание.
Related posts:
Здравствуйте.
А если, например, открыто две книги и находясь в активной книге, как не используя путь, скопировать данные в скрытом листе пассивной книги и вставить их в активную.
Здравствуйте
А если например открыто две книги и находясь в активной книге, как не используя путь скопировать данные с пассивной книги и вставить их в активную.
Hey. I sent a screenshot. Did you get it?
Здравствуйте.
редактирую Ваш код. Возникло 2 проблемы:
1.начало таблицы, из которой необходимо скопировать данные каждый раз начинается с разного номера строки так как в первоначальном файле данные формируются расширенным фильтром (выделено красным)
2.перед тем как скопируются новые данные во второй файл, необходимо , чтобы из этого столбца удалились старые
Sub Макрос()
Range(«b20000:b20100»).Select
Selection.Copy
Workbooks.Open Filename:= «путь к файлу, в который копируем»
Range(«A2»).Select
ActiveSheet.Paste
ActiveWorkbook.Save
ActiveWorkbook.Close
End Sub
Можно так сделать или нужно писать другой макрос?
Добрый день. Подскажите что надо поменять в это строчке что бы не прописывать полный путь к файлу, а можно было выбирать диалоговым окном путь и имя файла
Set bookconst = Workbooks.Open(«C:\Users\User\Desktop\1.xlsx»)
Вызов диалогового окна нашел. Спасибо за ответ
Sub AttachFile_test() ‘ пример использования
Filename$ = GetFilePath()
If Filename$ = «» Then Exit Sub
MsgBox «Выбран файл: » & Filename$
End Sub
Function GetFilePath(Optional ByVal Title As String = «Выберите файл для обработки», _
Optional ByVal InitialPath As String = «c:\», _
Optional ByVal FilterDescription As String = «Файлы счетов», _
Optional ByVal FilterExtention As String = «*.*») As String
On Error Resume Next
With Application.FileDialog(msoFileDialogOpen)
.ButtonName = «Выбрать»: .Title = Title:
.InitialFileName = GetSetting(Application.Name, «GetFilePath», «folder», InitialPath)
.Filters.Clear: .Filters.Add FilterDescription, FilterExtention
If .Show -1 Then Exit Function
GetFilePath = .SelectedItems(1)
folder$ = Left(.SelectedItems(1), InStrRev(.SelectedItems(1), «\»))
SaveSetting Application.Name, «GetFilePath», «folder», folder$
End With
End Function
Добрый день! Могли бы Вы помочь в решении проблемы, есть лист который необходимо поделить на несколько новых книг по параметру Город ( т.е. будет новая книга :Москва в которой будет шапка, город, марка,номер, водитель, Питер в которой будет шапка, город, марка,номер, водитель и т.д.) при этом сохранились форматы ячеек, а сама книга будет названа как город который будет в ней. Потом необходимо поделить лист на книги по параметру Марка и книга будет называться как Марка которая в ней будет. Заранее благодарна!
Как можно изменить код макроса, если при открытии файла его нет по указанному адресу. Нужно чтобы макрос остановится и открылось окно с информацией, что файл не найден. Иначе выдаёт ошибку.
Здравствуйте! Помогите, пожалуйста, в решении задачи:
Есть 2 файла. В первом файле хранятся столбцы с данными, файл ежедневно обновляется данными. Во втором — итоговая таблица. Нужно автоматически копировать столбцы из первого файла и вставить в конец таблицы второго.
Помогите, пожалуйста.
Нужен макрос, чтобы по нажатию, копировал данные из определенного статичного столбца в активный столбец (на котором стоит курсор).
Заранее, спасибо!
Включите запись макрорекодера, проделайте всю операцию и остановите запись. Получится нужный вам макрос
Добрый день! Вы просто герой! всем отвечаете и помогаете!
Помогите и мне пожалуйста, Вот код:
Sub форЮля()
Range(«A1:G1»).Select
With Selection.Interior
.ColorIndex = 6
.Pattern = xlSolid
End With
Selection.Copy
ChDir «C:\Users\karlov\Desktop\mind»
Workbooks.Open Filename:=»1″
Range(«A1»).Select
ActiveSheet.Paste
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.CutCopyMode = False
End Sub
как сделать так что бы запись в фаил «1» всегда была на одну строчку ниже?
2 дня уже не могу сделать , надеюсь на Вас. Спасибо.
Попробуйте добавить между
Range («A1»).Select и ActiveSheet.Paste
ActiveSheet.Range("A1").End(xlDown).Offset(1, 0).Select
ДД!
спасибо большое за Ваш пост! Нужно было переносить строки из общей таблицы на разные листы другой книги.
Подскажите, можно ли добавить условие в код? У меня большая таблица хронометража по разным показателям. Возможно ли копирование только тех ячеек значение которых больше 0?
То, что я имею сейчас:
Sub Перенос_строк_состав_комм_КМ()
Workbooks.Open Filename:=C:\1\2.xlsx»
Workbooks(«2.xlsx»).Worksheets(«приложение 3»).Range(«F30:BC30»).Copy
Workbooks(«КФ.xlsm»).Activate
ActiveWorkbook.Worksheets(«составление комм КМ»).Range(«C5»).Select
ActiveSheet.Paste
Workbooks(«2.xlsx»).Close
End Sub
Добрый день. Ваш код мне очень подходит. Вопрос, как изменить диапазон ячеек в коде, при условии, что я хочу перенести в другую книгу в определенный лист несколько разных ячеек с одного листа НАПРИМЕР диапазоны B7:С24 и H7:I24 . Подскажите как правильно это нужно указать. Спасибо.
Решили вопрос? Вам нужно скопировать сначала один диапазон, потом снова выделить книгу откуда вы копируете, например так
Workbooks(«Книга1.xlsm»).Activate
снова повторить копирование уже другого диапазона
У меня более 30 вкладок в одной книге, и часть ячеек не должна копировать в другую книгу, они должны совместиться. Я уже много перепробовала, но почему то копирует только второй диапазон, а первый будто не видит… например я пишу код
abook.Worksheets(«3»).Activate
Range(«B7:C39», «H7:I39»).Copy
bookconst.Worksheets(«3»).Activate
Range(«B7»).Select ‘выделяем диапазон
а копирует он только диапазон «H7:I39», игнорируя диапазон B7:C39
Так я и не решила эту проблему..
На мой взгляд у вас проблема о объединенных ячейках. У вас 61 и другие строки объединены. Вы попробуйте вручную выделить диапазон B7:C39 — у вас не получится и у VBA тоже не получается
Нужно делать по-отдельности. Сначала одни диапазон, потом второй и так далее
abook.Worksheets («3»).Activate
Range («B7:C39»).Copy
bookconst.Worksheets («3»).Activate
Range («B7»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
После этого снова активируете первую книгу и копируете второй диапазон
abook.Worksheets («3»).Activate
Range («H7:I39»).Copy
…
Эти Варианты я все перепробовала, решение оказалось таким:
Range(«B9:C2900, D9:E2900, K9:L2900»).Copy
bookconst.Worksheets(«благ»).Activate
Range(«B4»).Select ‘встаем на ячейку А1
При этом в заданных диапазонах не должны быть пересечения объеденных ячеек.
СПАСИБО АВТОРУ
Добрый день,
В коде при варианте 1 выводит ошибку 1004, выделяя желтым строку кода:
Range(«A6»).Select
В этой строке вряд ли ошибка может быть. Проверил код, должно все работать
Единственное вот тут неправильное описание
Workbooks.Open Filename:= «путь к файлу»
здесь нужно указать не путь к файлу, а только название файла, путь к папке мы указали в чуть выше в коде
Вопрос не актуален, спасибо!
Решение найдено!
Отлично, в чем была причина?
Также, вот чуток модифицированный вариант для того, чтобы данные не перезаписывались, а вставлялись в новую строку:
Range(«A1:E1»).Select
Selection.Copy
ChDir «C:\Users\50545\Desktop»
Workbooks.Open Filename:=»123.xlsx»
ActiveSheet.Range(«A1»).Select
If ActiveSheet.Range(«A1»).Value = «» Then
ActiveSheet.Paste
ActiveWorkbook.Save
ActiveWorkbook.Close
Else
Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Select
ActiveSheet.Paste
ActiveWorkbook.Save
ActiveWorkbook.Close
Создал отдельный модуль для макроса (до этого был в модуле листа)…
Добрый день,
К сожалению, ошибку все еще выдает 🙁
Прикладываю сам файл и принт-скрин…
Буду признателен за помощь в исправлении…
Доброго времени суток.
Подскажите пожалуйста код макроса со следующим функционалом:
Есть несколько документов. Первый документ — база со всеми данными, а остальные — документы в которых нужно скопировать некоторые данные из базы.
На словах макрос я бы описал так:
Открываем документ «База» вкладка «Лист1» копируем значение ячейки С15, после чего вставляем её в документ «Отчёт» вкладка «Данные» в поле F19.
Далее
Открываем документ «База» вкладка «Лист1» копируем значение ячейки С18, после чего вставляем её в документ «Отчёт» вкладка «Данные» в поле D20.
Далее
Открываем документ «База» вкладка «Лист1» копируем значение ячейки С24, после чего вставляем её в документ «Отчёт» вкладка «Данные» в поле L3.
И так далее…
Да, необходимо копировать только значение (стиль и т.д. не нужно) И если например в базе какая то ячейка стала пустой, то на пустоту необходимо заменить значение, что было прописано ранее в остальных документах.
В программировании не силён, если можно с кратким объяснением.
Пример приложил. Значения цифровые и текстовые, могут быть одновременно. Должны быть скопированы в неизменном виде (как в примере). Поля Параметр 2, Параметр 3 и т.д. роли не играют. Этим я просто показал что ячейки могут находиться в разных местах.
Да, в примере имена людей совпадают, но в реальности они могут отличаться, потому то я и прошу скрипт с указанием с какой в какую ячейку копировать данные. Положение в списке как правило не меняется.
Добрый вечер. Это опять я.
Появилась новая задача. Есть файл источник в котором есть данные.
Тот макрос, который Вы помогли запустить копирует только из этого, определенного файла.
А можно сделать так, чтобы макрос работал из любого другого файла.
То есть я копирую макрос в другой файл , а он сохраняет в отдельный.
нет. все равно заменяет.
может Вы можете помочь немного по другому.
Вот макрос, который копирует нужный диапазон и копирует в нужную книгу.
НО как и в первом варианте надо , после изменения в основном файле данных, вставлять не в туже строку , а в следующую.
Sub Кнопка2 Щелчок()
‘
‘ Кнопка2_Щелчок Макрос
‘
‘ Сочетание клавиш: Ctrl+j
‘
Range(«A7:J7″).Select
Selection.Copy
Workbooks.Open Filename:=»C:\Users\Slava\Desktop\Neuer Ordner\1.xlsm»
Range(«A1:J1»).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
ActiveSheet.Paste
Application.CutCopyMode = False
ActiveWorkbook.Save
ActiveWindow.Close
End Sub
может быть так проще?
Нет, не проще. Проверьте еще раз внимательно. У меня все работает. Данные не заменяются, а вставляются в следующие строку.
Сейчас, кстати заметил, что надо брать не G5000, а F5000 так как в столбце G ничего не вставляется, поэтому он и заменяет данные, так как последняя строчка всегда одна и та же
Добрый вечер. Хочу Вас поблагодарить. Все получилось.
Только я методом «тыка» изменил немного код. А именно вот эту строку
iLastRow = Workbooks(«Книга1.xlsm»).Worksheets(«Лист1»).Range(«F5000»).End(xlUp).Row + 1
у Вас стоял («Книга1.xlsm») а я написал («1.xlsm») указал ту книгу в которую производить копирование и всё пошло нормально.
Еще раз спасибо.
Да, все верно. Я просто тестировал на своих файлах и забыл поменять. Удачи!
В этой статье рассматриваются многочисленные методы передачи данных в Microsoft Excel из приложения Microsoft Visual Basic. В этой статье также представлены преимущества и недостатки каждого метода, чтобы можно было выбрать оптимальное решение.
Дополнительная информация
Чаще всего для передачи данных в Excel используется автоматизация. Автоматизация обеспечивает максимальную гибкость при указании расположения данных в книге, а также возможность форматирования книги и создания различных параметров во время выполнения. С помощью службы автоматизации можно использовать несколько подходов для передачи данных:
- Передача ячейки данных по ячейкам
- Передача данных в массиве в диапазон ячеек
- Передача данных из набора записей ADO в диапазон ячеек с помощью метода CopyFromRecordset
- Создание таблицы QueryTable на Excel, содержащей результат запроса к источнику данных ODBC или OLEDB
- Передача данных в буфер обмена, а затем вставка содержимого буфера обмена в Excel листа
Существуют также методы, которые можно использовать для передачи данных в Excel, которые не обязательно требуют автоматизации. Если вы работаете на стороне сервера приложений, это может быть хорошим подходом для того, чтобы отойдите от клиентов к массовой обработке данных. Для передачи данных без автоматизации можно использовать следующие методы:
- Передача данных в текстовый файл с разделителями-табуляции или запятыми, который Excel позже можно проанализировать в ячейки на листе.
- Передача данных на лист с помощью ADO
- Передача данных в Excel с помощью динамических Exchange данных (DDE)
В следующих разделах приведены более подробные сведения о каждом из этих решений.
Примечание При использовании Microsoft Office Excel 2007 при сохранении книг можно использовать новый формат Excel книги 2007 (*.xlsx). Для этого найдите следующую строку кода в следующих примерах кода:
Замените этот код следующей строкой кода:
Кроме того, база данных Northwind не включена в Office 2007 по умолчанию. Однако базу данных Northwind можно скачать из Microsoft Office Online.
Использование службы автоматизации для передачи данных по ячейкам
С помощью службы автоматизации можно передавать данные на лист по одной ячейке за раз:
Передача ячеек данных по ячейкам может быть вполне приемлемым подходом, если объем данных невелик. Вы можете размещать данные в любом месте книги и условно форматировать ячейки во время выполнения. Однако этот подход не рекомендуется, если у вас есть большой объем данных для передачи в Excel книге. Каждый объект Range, полученный во время выполнения, приводит к запросу интерфейса, чтобы передача данных таким образом была медленной. Кроме того, Microsoft Windows 95 и Windows 98 имеют ограничение в 64 КБ на запросы интерфейса. Если вы достигнете или превысите это ограничение в 64 КБ для запросов интерфейса, сервер автоматизации (Excel) может перестать отвечать на запросы или могут возникнуть ошибки, указывающие на нехватку памяти.
Еще раз перенос ячеек данных допускается только для небольших объемов данных. Если необходимо перенести большие наборы данных в Excel, следует рассмотреть одно из решений, представленных позже.
Дополнительные примеры кода для автоматизации Excel см. в статье об автоматизации Microsoft Excel из Visual Basic.
Использование автоматизации для передачи массива данных в диапазон на листе
Массив данных можно передать в диапазон из нескольких ячеек одновременно:
При передаче данных с помощью массива, а не ячейки по ячейкам вы можете реализовать огромное повышение производительности с большим объемом данных. Рассмотрим следующую строку из приведенного выше кода, который передает данные в 300 ячеек листа:
Эта строка представляет два запроса интерфейса (один для объекта Range, возвращаемого методом Range, и другой для объекта Range, возвращаемого методом Resize). С другой стороны, для передачи ячейки данных по ячейкам требуются запросы 300 интерфейсов к объектам Range. По возможности вы можете воспользоваться преимуществами массовой передачи данных и сокращения количества запросов интерфейса.
Использование автоматизации для передачи набора записей ADO в диапазон листа
Excel 2000 г. появился метод CopyFromRecordset, который позволяет передавать набор записей ADO (или DAO) в диапазон на листе. В следующем коде показано, как автоматизировать Excel 2000, Excel 2002 или Office Excel 2003 и передать содержимое таблицы Orders в образце базы данных Northwind с помощью метода CopyFromRecordset.
Примечание При использовании Office 2007 базы данных Northwind необходимо заменить следующую строку кода в примере кода:
Замените эту строку кода следующей строкой кода:
Excel 97 также предоставляет метод CopyFromRecordset, но его можно использовать только с набором записей DAO. CopyFromRecordset с Excel 97 не поддерживает ADO.
Дополнительные сведения об использовании ADO и метода CopyFromRecordset см. в статье о передаче данных из набора записей ADO в Excel с помощью автоматизации.
Использование автоматизации для создания таблицы QueryTable на листе
Объект QueryTable представляет таблицу, созданную на основе данных, возвращаемых из внешнего источника данных. При автоматизации Microsoft Excel можно создать таблицу QueryTable, просто указав строку подключения для OLEDB или источника данных ODBC вместе с SQL строкой. Excel несет ответственность за создание набора записей и его вставку на лист в указанном расположении. Использование таблиц QueryTables дает несколько преимуществ по сравнению с методом CopyFromRecordset:
- Excel обрабатывает создание набора записей и его размещение на листе.
- Запрос можно сохранить с помощью таблицы QueryTable, чтобы его можно было обновить позже, чтобы получить обновленный набор записей.
- При добавлении новой таблицы QueryTable на лист можно указать, что данные, уже существующие в ячейках листа, будут сдвинуты в соответствии с новыми данными (дополнительные сведения см. в свойстве RefreshStyle).
В следующем коде показано, как автоматизировать Excel 2000, Excel 2002 или Office Excel 2003 для создания новой таблицы QueryTable на листе Excel с помощью данных из образца базы данных Northwind:
Использование буфера обмена
Буфер обмена Windows также можно использовать в качестве механизма передачи данных на лист. Чтобы вставить данные в несколько ячеек на листе, можно скопировать строку, в которой столбцы разделены символами табуляции, а строки разделены символами каретки. В следующем коде показано, Visual Basic использовать объект буфера обмена для передачи данных в Excel:
Создание текстового файла с разделителями, который Excel анализировать по строкам и столбцам
Excel могут открывать файлы с разделителями-табуляции или запятыми и правильно анализировать данные в ячейках. Эту функцию можно использовать, если вы хотите перенести большой объем данных на лист, используя небольшой объем (при наличии) службы автоматизации. Это может быть хорошим подходом для клиент-серверного приложения, так как текстовый файл может быть создан на стороне сервера. Затем можно открыть текстовый файл на клиенте с помощью службы автоматизации, где это необходимо.
В следующем коде показано, как создать текстовый файл с разделителями-запятыми из набора записей ADO:
Обратите внимание, что при использовании Office 2007 базы данных Northwind необходимо заменить следующую строку кода в примере кода:
Замените эту строку кода следующей строкой кода:
Если текстовый файл имеет расширение .CSV, Excel открывает файл без отображения мастера импорта текста и автоматически предполагает, что файл разделен запятыми. Аналогичным образом, если файл имеет расширение .TXT, Excel автоматически анализировать файл с помощью разделителей табуляции.
В предыдущем примере кода Excel с помощью инструкции Оболочки, а имя файла использовался в качестве аргумента командной строки. В предыдущем примере автоматизация не использовалась. Однако при необходимости можно использовать минимальный объем автоматизации, чтобы открыть текстовый файл и сохранить его в Excel формате книги:
Передача данных на лист с помощью ADO
С помощью поставщика Microsoft Jet OLE DB можно добавлять записи в таблицу в существующей Excel книге. Таблица в Excel является просто диапазоном с определенным именем. Первая строка диапазона должна содержать заголовки (или имена полей), а все последующие строки — записи. Ниже показано, как создать книгу с пустой таблицей с именем MyTable.
Excel 97, Excel 2000 и Excel 2003
Запустите новую книгу в Excel.
Добавьте следующие заголовки в ячейки A1:B1 листа Sheet1:
A1: FirstName B1: LastName
Отформатировать ячейку B1 как выровненную по правому краю.
В меню "Вставка" выберите "Имена", а затем выберите "Определить". Введите имя MyTable и нажмите кнопку "ОК".
Сохраните новую книгу как C:\Book1.xls и закройте Excel.
Чтобы добавить записи в MyTable с помощью ADO, можно использовать следующий код:
Excel 2007
В Excel 2007 запустите новую книгу.
Добавьте следующие заголовки в ячейки A1:B1 листа Sheet1:
A1: FirstName B1: LastName
Отформатировать ячейку B1 как выровненную по правому краю.
На ленте откройте вкладку "Формулы " и выберите команду "Определить имя". Введите имя MyTable и нажмите кнопку "ОК".
Сохраните новую книгу как C:\Book1.xlsx и закройте Excel.
Чтобы добавить записи в таблицу MyTable с помощью ADO, используйте код, похожий на следующий пример кода.
При добавлении записей в таблицу таким образом форматирование в книге сохраняется. В предыдущем примере новые поля, добавленные в столбец B, форматируются с выравниванием по правому краю. Каждая запись, добавляемая в строку, заимствует формат из строки над ней.
Обратите внимание, что при добавлении записи в ячейку или ячейки листа она перезаписывает все данные, которые ранее были в этих ячейках. Другими словами, строки на листе не "помещаются вниз" при добавлении новых записей. Это следует учитывать при проектировании макета данных на листах.
Метод обновления данных на листе Excel с помощью ADO или DAO не работает в среде Visual Basic for Application в Access после установки Office 2003 с пакетом обновления 2 (SP2) или после установки обновления для Access 2002, включенного в статью базы знаний Майкрософт 904018. Этот метод хорошо работает в Visual Basic приложений из других Office приложений, таких как Word, Excel и Outlook.
Дополнительные сведения см. в следующей статье:
Дополнительные сведения об использовании ADO для доступа к книге Excel см. в статье "Как запрашивать и обновлять данные Excel с помощью ADO из ASP".
Использование DDE для передачи данных в Excel
DDE — это альтернатива автоматизации в качестве средства взаимодействия с Excel и передачи данных. Однако с появлением автоматизации и COM DDE больше не является предпочтительным методом для взаимодействия с другими приложениями и должен использоваться только в том случае, если вам не доступно другое решение.
Чтобы передать данные в Excel с помощью DDE, можно использовать метод LinkPoke для передачи данных в определенный диапазон ячеек или метод LinkExecute для отправки команд, которые Excel будут выполняться.
В следующем примере кода показано, как установить диалог DDE с Excel, чтобы можно было перенести данные в ячейки на листе и выполнить команды. В этом примере для успешной установки диалога DDE в LinkTopic Excel|MyBook.xls книга с именем MyBook.xls должна быть открыта в работающем экземпляре Excel.
При использовании Excel 2007 можно использовать новый формат .xlsx для сохранения книг. Убедитесь, что имя файла обновлено в следующем примере кода. В этом примере Text1 представляет элемент управления Text Box в Visual Basic форме:
При использовании LinkPoke с Excel указывается диапазон в нотации столбца строк (R1C1) для LinkItem. Если данные разделяются на несколько ячеек, можно использовать строку, в которой столбцы разделяются вкладками, а строки разделяются символами возврата каретки.
При использовании LinkExecute для Excel выполнения команды необходимо Excel в синтаксисе языка макросов Excel (XLM). Документация по XLM не входит в Excel 97 и более поздних версий.
DDE не рекомендуется для взаимодействия с Excel. Автоматизация обеспечивает максимальную гибкость и предоставляет больше доступа к новым функциям, Excel может предложить.
Range.Cut – это метод, который вырезает объект Range (диапазон ячеек) в буфер обмена или перемещает его в указанное место на рабочем листе.
Синтаксис
Параметры
Параметры | Описание |
---|---|
Destination | Необязательный параметр. Диапазон ячеек рабочего листа, в который будет вставлен (перемещен) вырезанный объект Range (достаточно указать верхнюю левую ячейку диапазона). Если этот параметр опущен, объект вырезается в буфер обмена. |
Для вставки на рабочий лист диапазона ячеек, вырезанного в буфер обмена методом Range.Cut, следует использовать метод Worksheet.Paste.
Метод Range.Copy
Range.Copy – это метод, который копирует объект Range (диапазон ячеек) в буфер обмена или в указанное место на рабочем листе.
Синтаксис
Параметры
Параметры | Описание |
---|---|
Destination | Необязательный параметр. Диапазон ячеек рабочего листа, в который будет вставлен скопированный объект Range (достаточно указать верхнюю левую ячейку диапазона). Если этот параметр опущен, объект копируется в буфер обмена. |
Метод Worksheet.Paste
Синтаксис
Метод Worksheet.Paste работает как с диапазонами ячеек, вырезанными в буфер обмена методом Range.Cut, так и скопированными в буфер обмена методом Range.Copy.
Параметры
Параметры | Описание |
---|---|
Destination | Необязательный параметр. Диапазон (ячейка), указывающий место вставки содержимого буфера обмена. Если этот параметр не указан, используется текущий выделенный объект. |
Link | Необязательный параметр. Булево значение, которое указывает, устанавливать ли ссылку на источник вставленных данных: True – устанавливать, False – не устанавливать (значение по умолчанию). |
В выражении с методом Worksheet.Paste можно указать только один из параметров: или Destination, или Link.
Для вставки из буфера обмена отдельных компонентов скопированных ячеек (значения, форматы, примечания и т.д.), а также для проведения транспонирования и вычислений, используйте метод Range.PasteSpecial (специальная вставка).
Примеры
Вырезание и вставка диапазона одной строкой (перемещение):
Вырезание ячеек в буфер обмена и вставка методом ActiveSheet.Paste:
Копирование и вставка диапазона одной строкой:
Копирование ячеек в буфер обмена и вставка методом ActiveSheet.Paste:
Копирование одной ячейки и вставка ее данных во все ячейки заданного диапазона:
18 комментариев для “VBA Excel. Вырезание, копирование и вставка ячеек (диапазонов)”
Странно, что не рассмотрено копирование ячеек, которые Cells.
Например, следующая строка копирует ячейку A1 в B2
а эта делает тоже самое, но демонстрирует,
как можно добавить размер и смещение:
Cells ( 1 , "A" ) . Resize ( 1 , 1 ) . Offset ( 0 , 0 ) . Copy Cells ( 2 , "B" ) . Resize ( 1 , 1 ) . Offset ( 0 , 0 )
Здравствуйте!
Скажите, как можно копировать на Лист 1, а вставить на Лист 2 диапазон ячеек целиком, либо отсортированный по 1 признаку диапазон(например по какому-то определенному значению, скажем, числу «500» в одном столбце Листа 1)?
Привет, Максим!
Вот пример сортировки таблицы по значению 500 в первом столбце на "Лист6" и копирования диапазона с "Лист6" на "Лист4" :
Спасибо большое, только я, наверно, неправильно описал ситуацию.
Сперва из эталонной таблицы Лист 1 копируем весь список на существующий Лист4.
Затем, пропускаем шапку, и, начиная со строки7, уже на Лист4 ищем строку, у которой в столбце 5 стоит число 500.
Вырезаем эту строку и вставляем на позицию строки 7. т.е первая после шапки.
Ищем следующую строку — вырезаем, потом вставляем на позицию строки 7+1=8 и т.д.
В итоге оставим только те строки, у которых в столбце 5 стоит число «500», остальные удаляются строки.
(пробовал менять местами строки в предыдущем коде, ошибок нет, копирует, переходит на лист 4, но строки на нем не удаляет, циклы пошагово проходят, но ничего не изменяется.)
Функция записи макросов Excel используется не столько для создания хорошего кода, сколько для поиска названий необходимых объектов, методов и свойств. Например, при записи операции копирования и вставки можно получить код:
Sub Макрос()
Range( " A1 " ).Select
Selection.Copy
Range( " B1 " ).Select
ActiveSheet.Paste
End Sub
Обратите внимание, что данная программа выделяет ячейки. Однако в VBA для работы с объектом не обязательно его выделять. Данную процедуру можно заменить значительно более простой — применить метод Сору, который использует аргумент, представляющий адрес места вставки копируемого диапазона.
Sub CopyRange()
Range( " А1 " ).Copy Range( " В1 " )
End Sub
Предполагается, что рабочий лист является активным и операция выполняется на активном рабочем листе. Чтобы скопировать диапазон на другой рабочий лист или в другую книгу, необходимо задать ссылку:
Sub CopyRange2()
Workbooks( " File1.xlsx " ).Sheets( " Лист1 " ).Range( " A1 " ).Copy _
Workbooks( " File2.xlsx " ).Sheets( " Лист2 " ).Range( " A1 " )
End Sub
Еще одним подходом к решению этой задачи является использование для представления диапазонов объектных переменных:
Sub CopyRange3()
Dim Rngl As Range, Rng2 As Range
Set Rngl = Workbooks( " File1.xlsx " ).Sheets( " Лист1 " ).Range( " A1 " )
Set Rng2 = Workbooks( " File2.xlsx " ).Sheets( " Лист2 " ).Range( " A1 " )
Rngl.Copy Rng2 End Sub
Можно копировать большой диапазон. Адрес места вставки определяется единственной ячейкой (представляющей верхний левый угол вставляемого диапазона):
Sub CopyRange4 ()
Range( " А1:С800 " ).Copy Range( " D1 " )
End Sub
Для перемещения диапазона ячеек вместо метода Сору используется метод Cut.
Если размер копируемого диапазона не известен используется свойство CurrentRegion, возвращающее объект Range, который соответствует прямоугольнику ячеек вокруг заданной ячейки:
Sub CopyCurrentRegion2()
Range( " A1 " ).CurrentRegion.Copy Sheets( " Лист2 " ).Range( " A1 " )
End Sub
Метод End имеет один аргумент, определяющий направление, в котором увеличивается выделение ячеек. Следующий оператор выделяет диапазон от активной ячейки до последней непустой ячейки внизу:
Range (ActiveCell, ActiveCell.End(xlDown)).Select
Три остальные константы имитируют комбинации клавиш при выделении в других направлениях: xlUp (вверх), xlToLeft (влево) и xlToRight (вправо).
В прилагаемом Excel-файле определено несколько распространенных типов выделения ячеек (см. рис. 1). Код любопытен тем, что является также примером создания контекстного меню.
Запрос значения ячейки
Следующая процедура запрашивает значение у пользователя и вставляет его в ячейку А1:
Sub GetValuel()
Range( " A1 " ).Value = InputBox( " Введите значение " )
End Sub
Однако при выполнении этой процедуры возникает проблема. Если пользователь щелкнет на кнопке Отмена в окне ввода данных, то процедура удалит данные, которые находились в текущей ячейке. Модифицированная версия процедуры адекватно реагирует на щелчок на кнопке Отмена и не выполняет при этом никаких действий:
Sub GetValue2()
Dim UserEntry As Variant
UserEntry = InputBox( " Введите значение " )
If UserEntry <> " " Then Range( " A1 " ).Value = UserEntry
End Sub
Во многих случаях следует проверить правильность данных, введенных пользователем. Например, необходимо обеспечить введение только чисел в диапазоне от 1 до 12 (рис. 2). Это можно сделать при помощи процедуры GetValue3(), код которой приведен в Модуле1 приложенного Excel-файла. Некорректные данные игнорируются, и окно запроса значения отображается снова. Этот цикл будет повторяться, пока пользователь не введет правильное значение или не щелкнет на кнопке Отмена.
Рис. 2. Проверка данных, введенных пользователем
Ввод значения в следующую пустую ячейку
Если требуется ввести значение в следующую пустую ячейку столбца или строки, используйте код (рис. 3):
Sub GetData()
Dim NextRow As Long
Dim Entry1 As String, Entry2 As String
Do
' Определение следующей пустой строки
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
' Запрос данных
Entry1 = InputBox( " Введите имя " )
If Entry1 = " " Then Exit Sub
Entry2 = InputBox( " Введите сумму " )
If Entry2 = " " Then Exit Sub
' Запись данных
Cells(NextRow, 1) = Entry1
Cells(NextRow, 2) = Entry2
Loop
End Sub
Рис. 3. Макрос вставляет данные в следующую пустую строку рабочего листа
Это бесконечный цикл. Для выхода из него (щелкните на кнопке Cancel) использовались операторы Exit Sub. Обратите внимание строку, в который определяется значение переменной NextRow. Если вам трудно ее понять, проанализируйте содержимое ячейки: перейдите в последнюю ячейку столбца А и нажмите и . После этого будет выделена последняя непустая ячейка в столбце А. Свойство Row возвращает номер этой строки; чтобы получить расположенную под ней строку (следующую пустую строку), к этому номеру прибавляется 1.
Приостановка работы макроса для определения диапазона пользователем
В некоторых ситуациях макрос должен взаимодействовать с пользователем. Например, можно создать макрос, который приостанавливается, когда пользователь указывает диапазон ячеек. Для этого воспользуйтесь функцией Excel InputBox. Не путайте метод Excel InputBox с функцией VBA InputBox. Несмотря на идентичность названий, это далеко не одно и то же.
Процедура, представленная ниже, демонстрирует, как приостановить макрос и разрешить пользователю выбрать ячейку. Затем автоматически формула вставляется в каждую ячейку выделенного диапазона.
Sub GetUserRange()
Dim UserRange As Range
Prompt = " Выберите диапазон для случайных чисел. "
Title = " Выбор диапазона "
' Отображение поля ввода
On Error Resume Next
Set UserRange = Application.InputBox( _
Prompt:=Prompt, _
Title:=Title, _
Default:=ActiveCell.Address, _
Type:=8) ' Выделение диапазона
On Error GoTo 0
' Отменено ли отображение поля ввода?
If UserRange Is Nothing Then
MsgBox " Отменено. "
Else
UserRange.Formula = " =RAND() "
End If
End Sub
Окно ввода данных показано на рис. 4. Важный момент в этой процедуре – определение аргумента Туре равным 8 (в этом случае InputBox вернет диапазон; подробнее см. Application.InputBox Method).
Рис. 4. Использование окна ввода данных с целью приостановки выполнения макроса
Обязательно проверьте, включено ли обновление экрана при использовании метода InputBox для выделения диапазона. Если обновление экрана отключено, вы не сможете выделить рабочий лист. Чтобы проконтролировать обновление экрана, в процессе выполнения макроса используйте свойство ScreenUpdating объекта Application.
Подсчет выделенных ячеек
Если активный лист содержит диапазон data, то следующий оператор присваивает количество ячеек в диапазоне data переменной с названием CellCount:
CellCount = Range( " data " ).Count
Вы можете также определить, сколько строк или столбцов содержится в диапазоне. Следующее выражение вычисляет количество столбцов в выделенном диапазоне:
Следующий оператор пересчитывает количество строк в диапазоне с названием data и присваивает это количество переменной RowCount.
RowCount = Range( " data " ).Rows.Count
Просмотр выделенного диапазона
Вы можете столкнуться с трудностями при создании макроса, который оценивает каждую ячейку в диапазоне и выполняет операцию, определенную заданному критерию. Если выделен целый столбец или строка, то работа макроса может занять много времени. Процедура ColorNegative устанавливает красный цвет для ячеек, которые содержат отрицательные значения. Цвет фона для других ячеек не определяется. Код процедуры можно найти в Модуле4 приложенного Excel-файла.
Усовершенствованная процедура ColorNegative2, создает объектную переменную WorkRange типа Range, которая представляет собой пересечение выделенного диапазона и диапазона рабочего листа (рис. 5). Если выделить столбец F (1048576 ячеек), то его пересечение с рабочим диапазоном В2:I16) даст область F2:F16, которая намного меньше исходного выделенного диапазона. Время, затрачиваемое на обработку 15 ячеек, намного меньше времени, уходящего на обработку миллиона ячеек.
Рис. 5. В результате пересечения используемого диапазона и выделенного диапазона рабочего листа уменьшается количество обрабатываемых ячеек
И всё же процедура ColorNegative2 недостаточно эффективна, поскольку обрабатывает все ячейки в диапазоне. Поэтому предлагается процедура ColorNegative3. В ней используется метод SpecialCells, с помощью которого генерируются два поднабора выделенной области: один поднабор (ConstantCells) включает ячейки, которые содержат исключительно числовые константы; второй поднабор (FormulaCells) включает ячейки, содержащие числовые формулы. Обработка ячеек в этих поднаборах осуществляется с помощью двух конструкций For Each-Next. Благодаря тому, что исключается обработка пустых и нетекстовых ячеек, скорость выполнения макроса существенно увеличивается.
Sub ColorNegative3()
' Окрашивание ячеек с отрицательными значениями в красный цвет
Dim FormulaCells As Range, ConstantCells As Range
Dim cell As Range
If TypeName(Selection) <> " Range " Then Exit Sub
Application.ScreenUpdating = False
' Создание поднаборов исходной выделенной области
On Error Resume Next
Set FormulaCells = Selection.SpecialCells(xlFormulas, xlNumbers)
Set ConstantCells = Selection.SpecialCells(xlConstants, xlNumbers)
On Error GoTo 0
' Обработка ячеек с формулами
If Not FormulaCells Is Nothing Then
For Each cell In FormulaCells
If cell.Value < 0 Then
cell.Interior.Color = RGB(255, 0, 0)
Else
cell.Interior.Color = xlNone
End If
Next cell
End If
' Обработка ячеек с константами
If Not ConstantCells Is Nothing Then
For Each cell In ConstantCells
If cell.Value < 0 Then
cell.Interior.Color = RGB(255, 0, 0)
Else
cell.Interior.Color = xlNone
End If
Next cell
End If
End Sub
Оператор On Error необходим, поскольку метод SpecialCells генерирует ошибку, если не находит в диапазоне ячеек указанного типа.
Удаление всех пустых строк
Следующая процедура удаляет все пустые строки в активном рабочем листе. Она достаточно эффективна, так как не проверяет все без исключения строки, а просматривает только строки в так называемом «используемом диапазоне», определяемом с помощью свойства UsedRange объекта Worksheet.
Sub DeleteEmptyRows()
Dim LastRow As Long
Dim r As Long
Dim Counter As Long
Application.ScreenUpdating = False
LastRow = ActiveSheet.UsedRange.Rows.Count + _
ActiveSheet.UsedRange.Rows(1).Row — 1
For r = LastRow To 1 Step -1
If Application.WorksheetFunction.CountA(Rows(r)) = 0 Then
Rows(r).Delete
Counter = Counter + 1
End If
Next r
Application.ScreenUpdating = True
MsgBox Counter & " Пустые строки удалены. "
End Sub
Первый шаг — определить последнюю используемую строку и присвоить этот номер строки переменной LastRow. Это не так просто, как можно ожидать, поскольку текущий диапазон необязательно начинается со строки 1. Следовательно, значение LastRow вычисляется таким образом: к найденному количеству строк используемого диапазона прибавляется номер первой строки текущего диапазона и вычитается 1.
В процедуре применена функция Excel СЧЁТЗ, определяющая, является ли строка пустой. Если данная функция для конкретной строки возвращает 0, то эта строка пустая. Обратите внимание, что процедура просматривает строки снизу вверх и использует отрицательное значение шага в цикле For-Next. Это необходимо, поскольку при удалении все последующие строки перемещаются «вверх» в рабочем листе. Если бы в цикле просмотр выполнялся сверху вниз, то значение счетчика цикла после удаления строки оказалось бы неправильным.
Дублирование строк
Пример, рассматриваемый в этом разделе, демонстрирует использование возможностей VBA для создания дубликатов строк. На рис. 6 показан пример рабочего листа, используемого организаторами лотереи. В столбце А вводится имя. В столбце В содержится количество лотерейных билетов, приобретенных одним покупателем. В столбце С находится случайное число сгенерированное с помощью функции СЛЧИС. Победитель определяется путем сортировки данных в третьем столбце (выигрыш соответствует наибольшему случайному числу).
Рис. 6. Дублирование строк на основе значений в столбце В
А теперь нужно продублировать строки, в результате чего количество строк для каждого участника лотереи будут соответствовать количеству купленных им билетов. Например, если Барбара приобрела два билета, для нее создаются две строки. Ниже показана процедура, выполняющая вставку новых строк.
Sub DupeRows()
Dim cell As Range
' 1-я ячейка, содержащая сведения о количестве билетов
Set cell = Range( " B2 " )
Do While Not IsEmpty(cell)
If cell > 1 Then
Range(cell.Offset(1, 0), cell.Offset(cell.Value _
— 1,0)).EntireRow.Insert
Range(cell, cell.Offset(cell.Value — 1, — 1)). _
EntireRow.FillDown
End If
Set cell = cell.Offset(cell.Value, 0)
Loop
End Sub
Объектная переменная cell была инициализирована ячейкой В2, первой ячейкой, в которой находится числовая величина. Вставка новых строк осуществляется в цикле, а их копирование происходит с помощью метода FillDown. Значение переменной cell увеличивается на единицу, после чего выбирается следующий участник лотереи, Цикл выполняется до тех пор, пока не встретится пустая ячейка. На рис. 7 показан рабочий лист после выполнения этой процедуры.
Рис. 7. В соответствии со значением в столбце В добавлены новые строки
Определение диапазона, находящегося в другом диапазоне
Функция InRange имеет два аргумента, оба — объекты Range. Функция возвращает значение True (Истина), если первый диапазон содержится во втором.
Function InRange(rng1, rng2) As Boolean
‘ Возвращает True, если rng1 является подмножеством rng2
InRange = False
If rng1.Parent.Parent.Name = rng2.Parent.Parent.Name Then
If rng1.Parent.Name = rng2.Parent.Name Then
If Union(rng1, rng2).Address = rng2.Address Then
InRange = True
End If
End If
End If
End Function
Возможно, функция InRange кажется сложнее, чем того требует ситуация, поскольку в коде должна быть реализована проверка принадлежности двух диапазонов одной и той же книге и рабочему листу. Обратите внимание, что в процедуре используется свойство Parent, которое возвращает объект-контейнер заданного объекта. Например, следующее выражение возвращает название листа для объекта rng1:
Следующее выражение возвращает название рабочей книги rng1:
Функция VBA Union возвращает объект Range, который представляет собой объединение двух объектов типа Range. Объединение содержит все ячейки, относящиеся к исходным диапазонам. Если адрес объединения двух диапазонов совпадает с адресом второго диапазона, первый диапазон входит в состав второго диапазона.
Определение типа данных ячейки
В состав Excel входит ряд встроенных функций, которые могут помочь определить тип данных, содержащихся в ячейке. Это функции ЕНЕТЕКСТ, ЕЛОГИЧ и ЕОШИБКА. Кроме того, VBA поддерживает функции IsEmpty, IsDate и IsNumeric.
Ниже описана функция CellType, которая принимает аргумент-диапазон и возвращает строку, описывающую тип данных левой верхней ячейки этого диапазона (рис. 8). Такую функцию можно использовать в формуле рабочего листа или вызвать из другой процедуры VBA.
Рис. 8. Функция CellType, возвращающая тип данных ячейки
Function CellType(Rng)
' Возвращает тип ячейки, находящейся в левом верхнем углу диапазона
Dim TheCell As Range
Set TheCell = Rng.Range( " A1 " )
Select Case True
Case IsEmpty(TheCell)
CellType = " Пустая "
Case TheCell.NumberFormat = " @ "
CellType = " Текст "
Case Application.IsText(TheCell)
CellType = " Текст "
Case Application.IsLogical(TheCell)
CellType = " Логический "
Case Application.IsErr(TheCell)
CellType = " Ошибка "
Case IsDate(TheCell)
CellType = " Дата "
Case InStr(1, TheCell.Text, " : " ) <> 0
CellType = " Время "
Case IsNumeric(TheCell)
CellType = " Число "
End Select
End Function
Обратите внимание на использование оператора SetTheCell. Функция CellType получает аргумент-диапазон произвольного размера, но этот оператор указывает, что функция оперирует только левой верхней ячейкой диапазона (представленной переменной TheCell).
Читайте также: