можем ли мы использовать специальный метод вставки, если исходный диапазон удален

Я хочу издеваться над поведением художника формата, циклически перебирая последние 8 форматов. Для этого я сохраняю последние 8 захваченных Range в объекте List‹> в формате цикла. При применении я выбираю метод COPY вызова каждого диапазона, чтобы скопировать этот диапазон в буфер обмена, а затем вызываю метод PasteSpecial для диапазона назначения, как показано ниже.

RangeInfo tempRangeInfo = listRangeInfo[Counter]; 
//Copy to clipboard
                        tempRangeInfo.CopiedRange.Copy();
                        selection.PasteSpecial(xl.XlPasteType.xlPasteFormats,  xl.XlPasteSpecialOperation.xlPasteSpecialOperationNone,
                            false, false);

Но если я удалю исходный диапазон, я получу:

Ошибка метода PasteSpecial класса Range.

Любое предложение?


person sagar    schedule 13.09.2012    source источник


Ответы (1)


Когда вы копируете в Excel (скопированная область имеет границу марширующих муравьев), данные фактически не находятся в буфере обмена. Excel использует буфер обмена для переноса из исходных ячеек в режиме реального времени при вставке. Это делается для того, чтобы во время операции вставки формулы можно было преобразовать в новые относительные ссылки на ячейки. Если вы удалите исходные ячейки, Excel не сможет извлечь данные во время операции вставки.

VBA не имеет встроенной поддержки для работы напрямую с буфером обмена. Однако вы можете добавить MSForms в проект VBA, а затем объявить объект, который поддерживает функции буфера обмена.

Инструкции и примеры доступа к буферу обмена непосредственно из VBA см. на следующем веб-сайте:

http://www.cpearson.com/excel/Clipboard.aspx

Что касается меня, то у меня не было MSForms в списке доступных references, как было предложено на сайте cpearson, но я поискал на диске C:\ FM20.dll и обнаружил, что он спрятан в какой-то непонятной папке. Я скопировал его в корень C:\ и смог добавить как reference, щелкнув browse в диалоговом окне add references.

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

Public Sub Test()
  Dim obj As New MSForms.DataObject
  obj.SetText ActiveCell.Value
  obj.PutInClipboard
End Sub

Это копирует формулы, которые сохраняются:

Public Sub Test()
  Dim obj As New MSForms.DataObject
  obj.SetText ActiveCell.Formula
  obj.PutInClipboard
End Sub

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

Изменить №1

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

Буфер обмена Office не использует буфер обмена Windows. Он сам хранит скопированные значения и может хранить множество различных вариантов. Однако в Office 2000 им нельзя было управлять через VBA (см. Как использовать Буфер обмена Office 2000), а выборки, скопированные из Excel, — это либо «вставить текст», либо «вставить все». Нет никакой специальной вставки, чтобы просто вставить форматы. Я не смог найти ничего, что отличалось бы от более поздних версий Office.

Вывод. Единственный способ использовать VBA для выполнения специальной вставки — это иметь активный/действительный/скопированный выбор. Поэтому я согласен с тем, что единственным решением является объявление ваших собственных постоянных глобальных переменных (например, списка объектов) и сохранение форматов для каждого скопированного выбора в списке. Поскольку буфер обмена на самом деле не является жизнеспособным решением, SetData и SetDataObject не имеют значения... Если оказывается невозможным зафиксировать форматирование ячейки в одной строке кода VBA, вы всегда можете перечислить интересующие форматы и установить флаги в ваши сохраненные объекты для последующего использования.

person James L.    schedule 13.09.2012
comment
Быстрый способ получить ссылку на MSForms в Excel — перейти в редактор Visual Basic, а затем вставить > Userform. Это автоматически создает ссылку на MSForms, после чего вы можете удалить UserForm. - person barrowc; 14.09.2012
comment
Мне пришлось использовать метод System.Windows.Forms.Clipboard.SetData(), потому что FM20.dll предоставляет только метод SetText. Но моя проблема все еще не решена, потому что при получении объекта из буфера обмена он возвращает мне ноль. Также не могли бы вы ответить на мои вопросы ниже 1) Как я могу сохранить 8 диапазонов в буфере обмена, чтобы я мог получить к ним доступ, используя некоторый индекс 2) Чтобы преодолеть это, я подумал о сохранении этих диапазонов в объект LIST, но в этом случае, когда я использую setdata или setdataobject класса буфера обмена, что это за формат данных, который я должен использовать? - person sagar; 14.09.2012
comment
Я провел небольшое исследование буфера обмена Windows и Office. Я тоже не думаю, что это хорошее решение. См. Edit #1 к ответу выше. - person James L.; 14.09.2012
comment
спасибо @JamesL. Это было прекрасное обучение, а также вы помогли поддержать мое открытие. - person sagar; 18.09.2012
comment
@Джеймс Л. Могу ли я поместить объект DisplayFormats непосредственно в память и использовать его, даже если диапазон удален? ИЛИ есть ли какой-либо другой объект из класса диапазона, с которым я могу помочь? - person sagar; 18.09.2012
comment
После некоторых экспериментов оказалось, что вы не можете сохранить объект DisplayFormats, а затем назначить его другой ячейке (даже без удаления исходной ячейки). Похоже, вам нужно хранить и восстанавливать отдельные свойства границы, шрифта, стиля (и т. д.) по отдельности, а это означает, что не имеет значения, удалена ли исходная ячейка или нет, потому что вы создали свой собственный постоянный объект со свойствами, которые вы хотите использовать. - person James L.; 18.09.2012