Работа с буфером обмена в 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 |
natalie |
|
1 |
|
Как очистить буфер обмена?17.11.2010, 10:01. Показов 53222. Ответов 16
вот собственно и весь вопрос |
0 / 0 / 3 Регистрация: 28.01.2010 Сообщений: 279 |
|
17.11.2010, 10:13 |
2 |
Clipboard.Clear
0 |
natalie |
|
17.11.2010, 10:49 |
3 |
Спасибо |
natalie |
|
17.11.2010, 16:14 |
4 |
не работает |
Comanche |
||||
17.11.2010, 17:06 |
5 |
|||
Объект ClipBoard не поддерживается в VBA (в отличие от VB). Делай так:
|
natalie |
|
17.11.2010, 17:34 |
6 |
круто |
14 / 14 / 2 Регистрация: 23.03.2010 Сообщений: 635 |
|
17.11.2010, 21:29 |
7 |
2Comanche: и опять те же ‘грабли’… From: comanche Дело в том, что вышепривед╦нные два примера (как и мой из другого топика) — для форм VB, а не VBA. Формы VBA не имеют свойства hWnd. И даже не имеют свойства hDC, по которому можно было бы восстановить хэндл…
0 |
1 / 1 / 1 Регистрация: 18.06.2008 Сообщений: 329 |
|
18.11.2010, 04:30 |
8 |
если в ёкселе, то
0 |
1 / 1 / 0 Регистрация: 03.07.2009 Сообщений: 112 |
|
18.11.2010, 06:01 |
9 |
В Excel точно работает
0 |
Comanche |
|
18.11.2010, 12:10 |
10 |
2 vlth: блин, ну точно — те же грабли! ) |
vladpros 0 / 0 / 0 Регистрация: 18.12.2015 Сообщений: 1 |
||||
15.06.2016, 07:52 |
11 |
|||
0 |
Hugo121 6875 / 2807 / 533 Регистрация: 19.10.2012 Сообщений: 8,562 |
||||
15.06.2016, 08:22 |
12 |
|||
vladpros, не работает!
Ну а что там у ТС — известно только ему…
0 |
2 / 2 / 0 Регистрация: 08.06.2017 Сообщений: 10 |
|
04.06.2019, 11:19 |
13 |
А в Ворде???
0 |
ArtNord 370 / 268 / 93 Регистрация: 18.11.2015 Сообщений: 990 |
||||
04.06.2019, 11:36 |
14 |
|||
_SVP_,
очищает буфер обмена. Он не привязан к Word или Excel. Это буфер обмена Windows и поэтому будет одинаково работать в любом приложении где используется VBA.
1 |
370 / 268 / 93 Регистрация: 18.11.2015 Сообщений: 990 |
|
06.06.2019, 09:43 |
15 |
Блин, извиняюсь, затупил.
1 |
Alex77755 11482 / 3773 / 677 Регистрация: 13.02.2009 Сообщений: 11,145 |
||||
06.06.2019, 10:13 |
16 |
|||
Тоже не всегда срабатывает. Нашел один работающий вариант
Добавлено через 3 минуты Application.CutCopyMode = False не факт, то в памяти данные из Application
1 |
{quote}{login=Hugo}{date=16.11.2010 09:53}{thema=}{post}Быстро и без лишней информации (и без буфера) можно копировать через массив.
Только здесь вероятно или через много массивов, или через один много раз.
Что-то вроде
Sub tt()
Dim a
a = [a1:b10]
[e1:f10] = a
End Sub{/post}{/quote}
Как этоприменить к моему макросу, если поможите сократить — буду оч. признателен
Вот полный код:
Sub KPI_9()
‘ KPI_9 Макрос
‘ Расходы_департамента безопастности
Application.ScreenUpdating = False
Application.StatusBar = «Подождите, выполняется обновление данных…»
‘ Путь
Workbooks.Open Filename:= _
«http://srv-portal/sites/fin/budg/PL/Безопасность%20и%20Фрод/Расходы_ДБ.xlsx», _
UpdateLinks:=0
‘ УРАЛ (УРАЛ)со строки 3 (7 строк ) конец 9 строка
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«УРАЛ»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Visible = True
‘Отобразить лист
Sheets(«9»).Select
Range(«A3»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ Екатеринбург (ЕКБ)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«ЕКБ»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A13»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ Челябинск (ЧЛБ)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«ЧЛБ»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A23»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ Курган (КУРГ)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«КУРГ»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A33»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ ХМАО (ХМАО)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«ХМАО»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A43»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ ЯНАО (ЯНАО)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«ЯНАО»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A53»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ Пермь (ПРМ)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«ПРМ»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A63»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ Тюмень (ТМН)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«ТМН»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A73»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ КОМИ (КОМИ)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«КОМИ»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A83»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ Удмуртия (УДМ)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«УДМ»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A93»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
‘ Киров (КИР)
Windows(«Расходы_ДБ.xlsx»).Activate
Sheets(«КИР»).Select
Range(«A3:N3,A7:N7,A10:N14,P3:AA3,P7:AA7,P10:AA14,AC3:AN3,AC7:AN7,AC10:AN14»).Select
Selection.Copy
Windows(«Base of PL.xlsm»).Activate
Sheets(«9»).Select
Range(«A103»).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Cells.SpecialCells(xlCellTypeLastCell)(2).Copy
‘ скопировать пустую ячейку
ActiveWindow.SelectedSheets.Visible = False
‘ Скрыть лист
Windows(«Расходы_ДБ.xlsx»).Activate
ActiveWindow.Close False
‘ Закрыт без сохранения (если закрыть с сохранением то ActiveWorkbook.Saved = True)
Windows(«Base of PL.xlsm»).Activate
Sheets(«Главная»).Select
Application.ScreenUpdating = True
Application.StatusBar = False
MsgBox «Данные обновлены!»
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
- 68198 просмотров
Не получается применить макрос? Не удаётся изменить код под свои нужды?
Оформите заказ у нас на сайте, не забыв прикрепить примеры файлов, и описать, что и как должно работать.
Много лет эксплуатирую а-а-а-агромную задачу типа бюджетирования на крупном предприятии (но конкретная задача — это лирическое отступление).
Суть проблемы вот в чем.
Допустим копирую 1000000 (миллион) формул.
Естественно не одним оператором, в цикле на разных листах.
Допустим 50листов Excel соответствуют 50подразделениям предприятия.
В цикле первые 30 обрабатываются нормально, а на 31-ом ошибка (и останов) в программе с сообщением что-то типа не хватает выделенной памяти.
Обрабатываю эту ситуацию так:
— сохраняю файл;
— перезагружаю комп;
— запускаю дальнейшую обработку начиная с 31-го подразделения.
Такая технология не есть правильная, на экономистов ее не перепихнешь (что желательно), приходится самому эксплуатацией заниматься.
Может быть в VBA есть (да есть наверняка) возможность освободить захламленную прежними копированиями буферную память.
Присоветуйте, кто знает.
Попробуйте в тот же цикл вставить после вставки:
[a1].copy'(любую, можно пустую ячейку)
Doevents' дадим системе время самой о себе позаботиться
Еще пример:
Sub Макрос1()
'очищает ClipBoard (буфер обмена).
'для работы примера должна быть подключена библиотека
'Microsoft Forms 2.0 Object Library в Tools - References...
'(или нужна любая пользовательская форма в проекте)
Dim MyData As DataObject, MyTest$
Set MyData = New DataObject
'копируем в буфер обмена
MyData.SetText "Test of copying and pasting to/from Clipboard!"
MyData.PutInClipboard
MyData.GetFromClipboard 'вставляем из буфер обмена
MyTest = MyData.GetText(1)
MsgBox MyTest
MyData.Clear ' чистим буфер
End Sub
И с помощью API:
Private Declare Function EmptyClipboard Lib "user32" () As Long
Я, как всегда, чертовски адекватен… Email: pilipnikop@yandex.ua WM Z206653985942, R334086032478, U238399322728, E332314026771
Здравствуйте KuklP, уже давно я тему основал
Как очистить системные буфера средствами VBA
« : 25 Август 2011, 06:53:19 »
Был только один Ваш ответ.
Пробовал воспользоваться Вашими советами, но как-то не очень получается
Пример
[a1].copy'(любую, можно пустую ячейку)
Doevents’ дадим системе время самой о себе позаботиться
что-то эффекта не дал
Пример
Sub Макрос1()
‘очищает ClipBoard (буфер обмена).
‘для работы примера должна быть подключена библиотека
‘Microsoft Forms 2.0 Object Library в Tools — References…
‘(или нужна любая пользовательская форма в проекте)
Dim MyData As DataObject, MyTest$
Set MyData = New DataObject
‘копируем в буфер обмена
MyData.SetText «Test of copying and pasting to/from Clipboard!»
MyData.PutInClipboard
MyData.GetFromClipboard ‘вставляем из буфер обмена
MyTest = MyData.GetText(1)
MsgBox MyTest
MyData.Clear ‘ чистим буфер
End Sub
В принципе, то что нужно.
Но у меня не получилось его адаптировать
Вот мне нужно тупо скопировать 10миллионов ячеек (только числа)
из одной книги Excel в другую
Копирую программно со 100листов 36диапазонов по 25000ячеек
(итого 90миллионов ячеек) — это в идеале, реально могу сократиться до 10миллионов ячеек.
Полтора-два миллиона пролетают за 10секунд, а потом все… На копирование каждого блока 25000ячеек уходит до минуты.
Можно ли подкорректировать Ваш пример (у меня не получилось) «очищает_буфер_обмена» так, чтобы в MyData заглатывать диапазон ячеек, затем из MyData вставлять ячейки на новом месте (в другой книгеExcel), а потом делать MyData.Clear
Заранее благодарен,
С.Казменко (dimikust)
Как Вы копируете? Через буфер обмена, т.е.
range1.Copy
range2.Paste
? Так, конечно, не надо делать. Если копируете ячейки целиком, с форматированием, используйте
range1.Copy range2
В качестве range2 можно указать одну первую ячейку диапазона.
Если копируете формулы (Допустим копирую 1000000 (миллион) формул), используйте
range2.Formula = range1.Formula
Если копируете значения (Вот мне нужно тупо скопировать 10миллионов ячеек (только числа)), используйте
range2.Value = range1.Value
В двух последних случаях диапазоны range1 и range2 должны иметь одинаковый размер, иначе можно получить ошибку или неожиданный результат.
Работает на порядок быстрее и не занимает буфер обмена.