#excel #vba #copy-paste
Вопрос:
Я хочу установить вставку по умолчанию в Excel только в качестве значений или соответствовать форматированию назначения. Я знаю, как создать макрос для каждого по отдельности, но xlPasteValues работает только при копировании из ячейки в книге, а форматирование в соответствии с назначением-нет (но оно работает при копировании с веб-страницы, чего я и хочу). Моя цель-создать один макрос VBA, который сочетает в себе оба, поэтому мне нужно использовать только одну команду, и независимо от того, скопирован ли я из ячейки или с веб-страницы, он будет вставлен без какого-либо исходного форматирования.
Псевдокод:
Sub SuperPaste() if clipboard source is a cell (or vice versa, whatever is easier): Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False else: ActiveSheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:= _ False, NoHTMLFormatting:=True (maybe some error handling) End Sub
Комментарии:
1. Самый близкий метод, который я могу придумать, — это
Application.CutCopyMode lt;gt; False
определить, содержит ли буфер обмена объект или текст. Выражение Истинно, если буфер обмена содержит объект (например, ячейку), который получен из текущего приложения (Excel). Кроме этого, вам придется использовать некоторый API, чтобы спросить Windows, что у них в буфере обмена, что гораздо сложнее и сложнее сделать в VBA. Если вы знаете, что это объект , вы можете это сделатьxlPasteValues
, в противном случае просто вставьте нормально.2. @Toddleson: Я пытался
Select Case Application.CutCopyMode
. Он не ведет себя прилично.
Ответ №1:
Следующее делает то, что вы пытаетесь сделать:
Sub SuperPaste() ''' Clipboard source is a current-instance excel cut: ''' - only option is to paste all (or throw an error msg) If Application.CutCopyMode = xlCut Then ActiveSheet.Paste ''' Clipboard source is a current-instance excel copy: ''' - paste values only (keeps destination formats) ''' - am pasting to the activecell to avoid mis-matched source and destination selections ElseIf Application.CutCopyMode = xlCopy Then ActiveWindow.ActiveCell.PasteSpecial xlPasteValues ''' Clipboard is empty: report to user ElseIf Application.ClipboardFormats(1) = -1 Then MsgBox "Nothing has been copied." ''' Clipboard source is another application (including another instance of excel): ''' - paste text (same as paste values for excel) ''' - still retains numbers (if tabbed or tabled apart) from word, html, another instance of excel, etc. Else: ActiveSheet.PasteSpecial Format:="Text" End If End Sub
Примечания:
- Вы можете сделать более сложные вещи, объявив функции Lib для работы с буфером обмена
- Однако вышесказанное работает для 99,9% типов копий, в которых вы хотите сохранить форматы назначения
ПРАВКА: Добавлена обработка пустого буфера обмена
Комментарии:
1. Он выдает
Run-time error '1004': PasteSpecial method of Worksheet class failed
, если это не текст, т. Е. Это никогдаxlCut
не так, он всегда выдаетxlCopy
ошибку. Возможно, это связано с версией (я используюWin10 64bit Office 2019 64bit
): не могли бы вы подтвердить, что это работает на вашей машине.2. @VBasic2008: Интересно. Я провел тестирование перед публикацией (и все сработало). Сейчас я протестировал (все варианты исходного кода cut/copy) как в 365 (64-разрядная версия), так и в 2010 (32-разрядная версия) (сегодня у меня нет доступа к 2019 году). Все работает так, как задумывалось в этих двух протестированных версиях. Это делает менее вероятным (хотя и не невозможным), что это связано с версией. Возможно, проблема в конкретном источнике копирования? С чего вы копируете, когда он выдает ошибку?
3. Я просто выбираю диапазон и использую
Ctrl X
илиCtrl C
, чтобы «позволитьCutCopyMode
делать свое дело». Затем я выбираю другую ячейку и запускаю вспомогательный модуль, и возникает ошибка. То же самое происходило при использовании аналогичного кода, который я написал.4. Это прекрасно! Большое вам спасибо! Я только что провел небольшое тестирование, и оно работает, когда источником является другая ячейка, веб-страница, файл PDF и другая рабочая книга. Это фантастика!! Единственное, чего я не понимаю, так это почему отмена не работает ни с одним из макросов вставки, которые я пробовал, включая этот. Ничего особенного, но это было бы неплохо.
5. @VBasic2008 : Я решил протестировать это с системами 2019 года (как 32-разрядными, так и 64-разрядными). И то, и другое работало так, как ожидалось, и код выполнялся так, как предполагалось. Итак, с 356 (64), 2010 (32), 2019 (64 и 32) все ведет себя так же правильно, это убедительно говорит о том, что все, что вы видите, не связано с версией, а скорее с чем-то конкретным в вашей системе.