Excel vba копировать в буфер обмена

Работа с буфером обмена в VBA Excel: копирование и вставка ячеек, копирование текста из переменной, очистка буфера обмена. Объект DataObject. Примеры.

Копирование и вставка ячеек

Копирование содержимого и форматов ячеек (диапазона) в буфер обмена осуществляется методом Range.Copy, а вставка – методом Worksheet.Paste:

‘Копирование одной ячейки в буфер обмена

Range(«A10»).Copy

Cells(10, 1).Copy

‘Копирование диапазона ячеек в буфер обмена

Range(«B8:H12»).Copy

Range(Cells(8, 2), Cells(12, 8)).Copy

‘Вставка ячейки (диапазона) из буфера обмена на рабочий лист

ActiveSheet.Paste Range(«A20»)

ActiveSheet.Paste Cells(20, 1)

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

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

Буфер обмена и переменная

Передача текста между переменной и буфером обмена в VBA Excel осуществляется с помощью объекта DataObject. Стоит иметь в виду, что на некоторых компьютерах DataObject может некорректно работать при открытом окне проводника.

Объект DataObject

DataObject – это область временного хранения форматированных фрагментов текста, используемая в операциях переноса данных.

Подробнее об элементе DataObject вы можете прочитать на сайте разработчиков.

Методы объекта DataObject:

Метод Описание
GetFromClipboard Копирует данные из буфера обмена в DataObject
GetText Извлекает текстовую строку из объекта DataObject в указанном формате
PutInClipboard Перемещает данные из DataObject в буфер обмена
SetText Копирует текстовую строку в DataObject, используя указанный формат

Копирование текста из переменной в буфер обмена

Sub Primer2()

Dim s As String, myData As New DataObject

s = «Копирование текста из переменной в буфер обмена»

‘Копируем текст из переменной в DataObject

myData.SetText (s)

‘Перемещаем текст из DataObject в буфер обмена

myData.PutInClipboard

‘Проверяем содержимое буфера обмена

ActiveSheet.Paste Range(«A1»)

End Sub

Копирование текста из буфера обмена в переменную

Sub Primer3()

Dim s As String, myData As New DataObject

Range(«A1») = «Копирование текста из буфера обмена в переменную»

‘Копируем данные из ячейки в буфер обмена

Range(«A1»).Copy

‘Копируем данные из буфера обмена в DataObject

myData.GetFromClipboard

‘Извлекаем текст из объекта DataObject и присваиваем переменной s

s = myData.GetText

‘Проверяем содержимое переменной s

MsgBox s

End Sub

Очистка буфера обмена

Специального метода для очистки буфера обмена в VBA Excel нет. Для решения этой задачи можно использовать выход из режима вырезания-копирования:

Application.CutCopyMode = False

Следующий пример демонстрирует вставку скопированной ячейки "A1" в ячейки "A2" и "A3" и отсутствие вставки в ячейки "A4" и "A5" после строки Application.CutCopyMode = False:

Sub Primer4()

Range(«A1») = «Очистка буфера обмена»

Range(«A1»).Copy

ActiveSheet.Paste Range(«A2»)

ActiveSheet.Paste Range(«A3»)

Application.CutCopyMode = False

On Error Resume Next

ActiveSheet.Paste Range(«A4»)

ActiveSheet.Paste Range(«A5»)

End Sub

Оператор On Error Resume Next необходим для обработки (пропуска) ошибки, возникающей при вставке из пустого буфера обмена.

Функции для работы с буфером обмена

В некоторых системах, начиная с Windows 8, метод DataObject.PutInClipboard не работает правильно: если открыт хотя бы один экземпляр Проводника (папка), в буфер обмена записываются два квадратика. Следующие функции должны решить эту проблему:

‘Функция записи текста в буфер обмена

Function SetClipBoardText(ByVal Text As Variant) As Boolean

    SetClipBoardText = CreateObject(«htmlfile»).parentWindow.clipboardData.SetData(«Text», Text)

End Function

‘Функция вставки текста из буфера обмена

Function GetClipBoardText() As String

    On Error Resume Next

    GetClipBoardText = CreateObject(«htmlfile»).parentWindow.clipboardData.GetData(«Text»)

End Function

‘Функция очистки буфера обмена

Function ClearClipBoardText() As Boolean

    ClearClipBoardText = CreateObject(«htmlfile»).parentWindow.clipboardData.clearData(«Text»)

End Function

Пример использования функций для работы с буфером обмена:

Sub Primer()

Dim s As String

    s = «Копирование текста из переменной в буфер обмена»

    ‘Копируем текст в буфер обмена

    SetClipBoardText (s)

    ‘Вставляем текс из буфера обмена в ячейку «A1»

    Range(«A1») = GetClipBoardText

    ‘Очищаем буфер обмена, если это необходимо

    ClearClipBoardText

End Sub


Результат чтения текста из буфера обмена

Функции для работы с буфером обмена

(очистка буфера обмена, запись в буфер обмена, чтение из буфера обмена)

ВНИМАНИЕ: для работы функций требуется установка ссылки на библиотеку Microsoft Forms 2.0 Object Library:

Public Sub SetClipboard(Obj As Variant)
    Dim MyDataObj As New DataObject
    MyDataObj.SetText Format(Obj)
    MyDataObj.PutInClipboard
End Sub
 
Public Sub SetTextIntoClipboard(ByVal txt As String)
    Dim MyDataObj As New DataObject
    MyDataObj.SetText txt
    MyDataObj.PutInClipboard
End Sub
 
Public Function GetClipboard() As Variant
    GetClipboard = "": On Error Resume Next
    Dim MyDataObj As New DataObject
    MyDataObj.GetFromClipboard: GetClipboard = MyDataObj.GetText()
End Function
 
Public Sub ClearClipboard()
    Dim MyDataObj As New DataObject
    MyDataObj.SetText "": MyDataObj.PutInClipboard
End Sub

Аналогичная функция ClipboardText (чтение текста из буфера обмена), но не требующая подключения библиотеки:

Sub ПримерИспользования()
    txt = ClipboardText
    MsgBox txt, vbInformation, "Содержимое буфера обмена Windows"
End Sub
 
Function ClipboardText() ' чтение из буфера обмена
    With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .GetFromClipboard
        ClipboardText = .GetText
    End With
End Function
 
Sub SetClipboardText(ByVal txt$) ' запись в буфер обмена
    With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .SetText txt$
        .PutInClipboard
    End With
End Sub
  • 68142 просмотра

Не получается применить макрос? Не удаётся изменить код под свои нужды?

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

Update! Better Solution from ExcelHero

Excel MVP Daniel Ferry from ExcelHero graciously provided a much more eloquent solution than my original article over on the StackOverflow forum.

In the below solution, he is utilizing the Microsoft HTML Object Library to access the clipboard. This solution will work with 32-bit and 64-bit versions of Excel which has been a pain point for many proposed VBA solutions out there on the web. His VBA function also allows you to both read from the clipboard and write to the clipboard depending on if you pass through a variable. Check out this beautiful piece of code (and if you dare keep scrolling to see my original behemoth of a solution!).

Text To The Clipboard (original solution)

There may be instances where you create a macro that reads in text and sticks it in your computer’s clipboard so you can manually paste it somewhere else.  The most prominent way to do this, is to use a DataObject variable from the Forms library (language).

You can reference this library by either going to your Visual Basic Editor’s tools menu and enabling the Microsoft Forms 2.0 Object Library reference or by simply adding a userform to your project (the userform doesn’t have to do anything, it’s very existence tells your project that the Forms library is needed).

Below is a very self-explanatory snippet of VBA code that will show you how to copy text straight into your computer’s clipboard.

Sub CopyTextToClipboard()
‘PURPOSE: Copy a given text to the clipboard (using DataObject)
‘SOURCE: www.TheSpreadsheetGuru.com
‘NOTES: Must enable Forms Library: Checkmark Tools > References > Microsoft Forms 2.0 Object Library

Dim obj As New DataObject
Dim txt As String

‘Put some text inside a string variable
  txt = «This was copied to the clipboard using VBA!»

‘Make object’s text equal above string variable
  obj.SetText txt

‘Place DataObject’s text into the Clipboard
  obj.PutInClipboard

‘Notify User
  MsgBox «There is now text copied to your clipboard!», vbInformation

End Sub

There’s An Excel Office Bug!

I initially started investigating how to copy text to the clipboard while running someone else’s code.  This code worked perfectly on my work computer (using Windows 7/Excel 2007), however it kept copying just two question marks to the clipboard while executing the VBA code on my home computer (using Windows 8.1/Excel 2013).  It took me forever to narrow down what was causing this to happen (the source code was very long) and of course, the problem ended up being a bug on the part of Microsoft!

Luckily, there were many others who were running into this very issue on the forums.  Someone posted that they were actually able to troubleshoot this problem with a Microsoft support member a couple years ago (maybe in 2010) and that person determined it to be a bug.  The support member pointed to a solution using a Windows API as a workaround (shown in the next section).  

Copy To Clipboard With Windows API

Below is the API workaround suggested by Microsoft to get around the «SetText» bug.  It has three parts: an API declaration section, a Function routine, and then I used a similar subroutine macro to place the desired text into the Clipboard.

UPDATE: I have modified the API declarations to work with both 64-bit and 32-bit versions of Microsoft Office

‘Handle 64-bit and 32-bit Office
#If VBA7 Then
  Private Declare PtrSafe Function GlobalUnlock Lib «kernel32» (ByVal hMem As LongPtr) As LongPtr
  Private Declare PtrSafe Function GlobalLock Lib «kernel32» (ByVal hMem As LongPtr) As LongPtr
  Private Declare PtrSafe Function GlobalAlloc Lib «kernel32» (ByVal wFlags As LongPtr, _
    ByVal dwBytes As LongPtr) As LongPtr
  Private Declare PtrSafe Function CloseClipboard Lib «user32» () As LongPtr
  Private Declare PtrSafe Function OpenClipboard Lib «user32» (ByVal hwnd As LongPtr) As LongPtr
  Private Declare PtrSafe Function EmptyClipboard Lib «user32» () As LongPtr
  Private Declare PtrSafe Function lstrcpy Lib «kernel32» (ByVal lpString1 As Any, _
    ByVal lpString2 As Any) As LongPtr
  Private Declare PtrSafe Function SetClipboardData Lib «user32» (ByVal wFormat As LongPtr, _
    ByVal hMem As LongPtr) As LongPtr
#Else
  Private Declare Function GlobalUnlock Lib «kernel32» (ByVal hMem As Long) As Long
  Private Declare Function GlobalLock Lib «kernel32» (ByVal hMem As Long) As Long
  Private Declare Function GlobalAlloc Lib «kernel32» (ByVal wFlags As Long, _
    ByVal dwBytes As Long) As Long
  Private Declare Function CloseClipboard Lib «user32» () As Long
  Private Declare Function OpenClipboard Lib «user32» (ByVal hwnd As Long) As Long
  Private Declare Function EmptyClipboard Lib «user32» () As Long
  Private Declare Function lstrcpy Lib «kernel32» (ByVal lpString1 As Any, _
    ByVal lpString2 As Any) As Long
Private Declare Function SetClipboardData Lib «user32» (ByVal wFormat _
    As Long, ByVal hMem As Long) As Long
#End If

Const GHND = &H42
Const CF_TEXT = 1
Const MAXSIZE = 4096

Function ClipBoard_SetData(MyString As String)
‘PURPOSE: API function to copy text to clipboard
‘SOURCE: www.msdn.microsoft.com/en-us/library/office/ff192913.aspx

#If VBA7 Then
  Dim hGlobalMemory As LongPtr, lpGlobalMemory As LongPtr
  Dim hClipMemory As LongPtr, x As LongPtr
#Else
  Dim hGlobalMemory As Long, lpGlobalMemory As Long
  Dim hClipMemory As Long, x As Long
#End If

‘Allocate moveable global memory
  hGlobalMemory = GlobalAlloc(GHND, Len(MyString) + 1)

‘Lock the block to get a far pointer to this memory.
  lpGlobalMemory = GlobalLock(hGlobalMemory)

‘Copy the string to this global memory.
  lpGlobalMemory = lstrcpy(lpGlobalMemory, MyString)

‘Unlock the memory.
  If GlobalUnlock(hGlobalMemory) <> 0 Then
    MsgBox «Could not unlock memory location. Copy aborted.»
    GoTo OutOfHere2
  End If

‘Open the Clipboard to copy data to.
  If OpenClipboard(0&) = 0 Then
    MsgBox «Could not open the Clipboard. Copy aborted.»
    Exit Function
  End If

‘Clear the Clipboard.
  x = EmptyClipboard()

‘Copy the data to the Clipboard.
  hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory)

OutOfHere2:
  If CloseClipboard() = 0 Then
    MsgBox «Could not close Clipboard.»
  End If

End Function

Sub CopyTextToClipboard()
‘PURPOSE: Copy a given text to the clipboard (using Windows API)
‘SOURCE: www.TheSpreadsheetGuru.com
‘NOTES: Must have above API declaration and ClipBoard_SetData function in your code

Dim txt As String

‘Put some text inside a string variable
  txt = «This was copied to the clipboard using VBA!»

‘Place text into the Clipboard
   ClipBoard_SetData txt

‘Notify User
  MsgBox «There is now text copied to your clipboard!», vbInformation

End Sub

About The Author

Hey there! I’m Chris and I run TheSpreadsheetGuru website in my spare time. By day, I’m actually a finance professional who relies on Microsoft Excel quite heavily in the corporate world. I love taking the things I learn in the “real world” and sharing them with everyone here on this site so that you too can become a spreadsheet guru at your company.

Through my years in the corporate world, I’ve been able to pick up on opportunities to make working with Excel better and have built a variety of Excel add-ins, from inserting tickmark symbols to automating copy/pasting from Excel to PowerPoint. If you’d like to keep up to date with the latest Excel news and directly get emailed the most meaningful Excel tips I’ve learned over the years, you can sign up for my free newsletters. I hope I was able to provide you with some value today and I hope to see you back here soon!

— Chris
Founder, TheSpreadsheetGuru.com

Return to VBA Code Examples

This article will demonstrate how to use VBA to copy items to the Clipboard.

You may want to copy information in Excel VBA and store it to use within another application or at another time when the Excel macro has stopped running. Once a macro stops running, the information that is stored in a variable or variables stops existing and can no longer be retrieved.  A way to solve this problem would be to copy this information to the clipboard.

Copying to the Clipboard using the HTML Object Library

The simplest way to use the clipboard in Excel VBA is to call the HTML Object Library.

Sub StoreData()
  Dim varText As Variant
  Dim objCP As Object
  varText = "Some copied text"
  Set objCP = CreateObject("HtmlFile")
  objCP.ParentWindow.ClipboardData.SetData "text", varText
End Sub

This uses late binding by declaring the variable objCP as an Object, thus you do not need to add a reference first.

If youopen an Excel worksheet and click Paste, the text “Some copied data” would be inserted into the selected cell.

If you change the previous sub procedure into a function, you can pass the text to a variable.

Function StoreData(varText As Variant) as String
  Dim objCP As Object
  Set objCP = CreateObject("HtmlFile")
  objCP.ParentWindow.ClipboardData.SetData "text", varText
End Function

It’s then possible to call this function multiple times.

Sub CopyData()
  StoreData "Some copied text"
End Sub

You can also use the HTML Object to return the text from the clipboard – ie Pasting.  For this use the GetData rather than the SetData method.

Function ReturnData()
  Dim objCP As Object
  Set objCP = CreateObject("HtmlFile")
  ReturnData = objCP.parentWindow.clipboardData.GetData("text")
End Function

Then you can call this function to return the data stored on the clipboard.

Sub PasteData()
  MsgBox ReturnData
End Sub

A neat trick is combining the 2 functions together so you can use the same function to Copy and to Paste data, depending on whether or not data is sent to the clipboard, or if you wish to retrieve data from the clipboard.

Function StoreOrReturnData(Optional strText As String) As String
  Dim varText As Variant
  Dim objCP As Object
  Set objCP = CreateObject("HtmlFile")
  varText = strText
  If strText <> "" Then
    objCP.ParentWindow.ClipboardData.SetData "text", varText
  Else
    StoreOrReturnData = objCP.ParentWindow.ClipboardData.GetData("text")
  End If
End Function

In the code above, the strText variable is optional – this means you do not need to enter the variable value if you only wish to paste data.

Then assign the string variable (strText) to a Variant variable in order for it to be stored in the SetData method of the HTML File Object.

To copy the data, you can use this procedure:

Sub CopyData()
  StoreOrReturnData "SomeCopiedText"
End Sub

This procedure shows a message box displaying the clipboard value.

Sub PasteData()
  MsgBox StoreOrReturnData
End Sub

VBA Coding Made Easy

Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
vba save as

Learn More!

В этой статье будет показано, как использовать VBA для копирования элементов в буфер обмена.

Может быть, в какой-то момент мы захотим скопировать информацию в Excel VBA и сохранить ее для использования в другом приложении или в другое время, когда макрос Excel перестал работать. Как только макрос перестает работать, информация, которая хранится в переменной или переменных, перестает существовать и больше не может быть получена. Решить эту проблему можно, скопировав эту информацию в буфер обмена.

Копирование в буфер обмена с помощью библиотеки объектов HTML

Самый простой способ использовать буфер обмена в Excel VBA — вызвать библиотеку объектов HTML.

1234567 Sub StoreData ()Dim varText как вариантDim objCP как объектvarText = «Некоторый скопированный текст»Установите objCP = CreateObject («HtmlFile»)objCP.ParentWindow.ClipboardData.SetData «текст», varTextКонец подписки

Поскольку мы используем позднее связывание, объявляя переменную objCP как объект, нам не нужно добавлять ссылку на Excel, чтобы эта процедура работала.

Если бы мы сейчас переключились на нашу таблицу Excel и нажали «Вставить», текст «Некоторые скопированные данные» был бы вставлен в выбранную ячейку.

Если бы мы превратили эту процедуру выше в функцию, мы могли бы передать текст, который будет скопирован, как переменную.

12345 Функция StoreData (varText As Variant) как строкаDim objCP как объектУстановите objCP = CreateObject («HtmlFile»)objCP.ParentWindow.ClipboardData.SetData «текст», varTextКонечная функция

Затем мы могли бы вызывать эту функцию несколько раз в нашем коде VBA, когда нам нужно скопировать текст в буфер обмена. Поэтому текст не будет жестко закодирован в коде VBA.

123 Sub CopyData ()StoreData «Некоторый скопированный текст»Конец подписки

Мы также можем использовать объект HTML для возврата текста из буфера обмена, то есть вставки. Для этого мы используем GetData, а не метод SetData.

12345 Функция ReturnData ()Dim objCP как объектУстановите objCP = CreateObject («HtmlFile»)ReturnData = objCP.parentWindow.clipboardData.GetData («текст»)Конечная функция

Затем мы можем вызвать эту функцию, чтобы вернуть данные, хранящиеся в буфере обмена.

123 Sub PasteData ()MsgBox ReturnDataКонец подписки

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

1234567891011 Функция StoreOrReturnData (необязательный strText как строка) как строкаDim varText как вариантDim objCP как объектУстановите objCP = CreateObject («HtmlFile»)varText = strTextЕсли strText «» ТогдаobjCP.ParentWindow.ClipboardData.SetData «текст», varTextЕщеStoreOrReturnData = objCP.ParentWindow.ClipboardData.GetData («текст»)Конец, еслиКонечная функция

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

Затем мы назначим строковую переменную (strText) переменной Variant, чтобы она сохранялась в методе SetData объекта HTML File.

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

123 Sub CopyData ()StoreOrReturnData «SomeCopiedText»Конец подписки

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

123 Sub PasteData ()MsgBox StoreOrReturnDataКонец подписки

Вы поможете развитию сайта, поделившись страницей с друзьями

Понравилась статья? Поделить с друзьями:
  • Excel vba копирование ячеек с форматированием
  • Excel vba копирование таблиц
  • Excel vba копирование строки на другой лист
  • Excel vba копирование макроса
  • Excel vba контрольная сумма