Ошибка при копировании вставки диаграммы через VBA

Я использовал этот код для копирования по ряду диапазонов и диаграмм. Однако по мере того, как мой код вырос, он, похоже, падает, после поиска в Google этой проблемы я думаю, что это вызвано неправильным копированием диаграммы / диапазона в / из кеша буфера обмена. Есть ли способ избежать этой ошибки?

Error - " Run-time error '-2147188160 (80048248)': Shapes.PasteSpecial :Invalid request. Clipboard is empty or contains data which may not be pasted here"

Public Sub CopyPasteHeadcountTopGraph()
    If PPT Is Nothing Then Exit Sub
    If PPT_pres Is Nothing Then Exit Sub

    Dim rng As Range
    Dim mySlide As Object
    Dim myShape As Object
    Dim cht As Chart

    Set mySlide = PPT_pres.Slides(6)

    With mySlide
    .Select
    Set cht = ThisWorkbook.Worksheets("Headcount").ChartObjects("HcChart").Chart

       cht.CopyPicture Appearance:=xlScreen, Format:=xlPicture, Size:=xlScreen
       .Shapes.Paste.Select 'ERROR HERE

        '''''''''''''''''''''''''''''''''
        'Paste as Chart and break link. '
        '''''''''''''''''''''''''''''''''
        'cht.ChartArea.Copy
        '.Shapes.Paste.Select


    'With .Shapes("HcChart")
        '.LinkFormat.BreakLink
    'End With

        PPT_pres.Windows(1).Selection.ShapeRange.Left = 35
        PPT_pres.Windows(1).Selection.ShapeRange.Top = 110
        PPT_pres.Windows(1).Selection.ShapeRange.Width = 655
        PPT_pres.Windows(1).Selection.ShapeRange.Height = 300

        End With

    'Clear The Clipboard
    Application.CutCopyMode = False
    Application.Wait (Now + TimeValue("00:00:01"))

End Sub
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
2
0
4 013
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Часто VBA начинает работать с объектами, когда эти объекты еще не готовы к работе. Даже копирование объекта может не быть завершено (т. Е. Весь объект не полностью зафиксирован в буфере обмена), когда VBA пытается вставить.

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

Например, в приведенном ниже коде я убрал вставку из основной процедуры. Это заставляет VBA ждать завершения копирования перед вставкой, а также до завершения вставки перед размещением вставленной диаграммы.

Фактически, у меня часто есть три отдельные функции, которые вызываются основной подпрограммой: копирование диаграммы, вставка диаграммы и позиционирование диаграммы.

Public Sub CopyPasteHeadcountTopGraph()
    If PPT Is Nothing Then Exit Sub
    If PPT_pres Is Nothing Then Exit Sub

    Dim rng As Range
    Dim mySlide As Object
    Dim myShape As Object
    Dim cht As Chart

    Set mySlide = PPT_pres.Slides(6)

    With mySlide
    .Select
    Set cht = ThisWorkbook.Worksheets("Headcount").ChartObjects("HcChart").Chart

       cht.CopyPicture Appearance:=xlScreen, Format:=xlPicture, Size:=xlScreen

       '''''''''''''''''''''''''''''''''''
       '' .Shapes.Paste.Select 'ERROR HERE
       '''''''''''''''''''''''''''''''''''

       PasteChartIntoSlide mySlide

        PPT_pres.Windows(1).Selection.ShapeRange.Left = 35
        PPT_pres.Windows(1).Selection.ShapeRange.Top = 110
        PPT_pres.Windows(1).Selection.ShapeRange.Width = 655
        PPT_pres.Windows(1).Selection.ShapeRange.Height = 300

        End With

    'Clear The Clipboard
    Application.CutCopyMode = False
    Application.Wait (Now + TimeValue("00:00:01"))

End Sub

Function PasteChartIntoSlide(theSlide As Object) As Object
    theSlide.Shapes.Paste.Select
End Function

Спасибо, Джон, отличное объяснение, и это действительно улучшило мой код, я был вынужден использовать Sleep 50 в каждой функции, но изначально он ждал целую секунду, поэтому резко увеличил скорость кода!

TisButaScratch 15.05.2018 17:13

Спасибо тебе за это. Я потратил несколько часов, потому что не знал об этом поведении VBA. Это даже не упоминается в документации ...

Rapwnzel 12.12.2018 10:39

@jonPeltier. У меня тоже были те же проблемы: много копий диаграмм нужно было вставить как изображения в другую таблицу. Я также не вижу задокументированной проблемы с ошибкой, но также отмечаю, что предложение «подпрограмма» для завершения необходимой обработки не имеет документированного объяснения. Мой вопрос1: Почему подпрограмма вызывает необходимую обработку? (Этот эффект где-нибудь задокументирован?) Вопрос 2: Если это помогает, почему TisButaScratch и JonPeltier вообще включают .waits?

John 09.01.2019 06:21

Проблема не задокументирована Microsoft; он носит спорадический характер, и вы увидите вопросы по этому поводу на онлайн-форумах. Объяснение «подпрограммы» таково: я обнаружил, что идентификация операций, которые требуют времени и могут привести к рассинхронизации VBA, и разбиение их на другие процедуры, похоже, помогает с этими проблемами. Я не знаю, почему это работает, но я предполагаю, что это может быть связано с тем, что границы вызываемых процедур заставляют VBA завершать работу с объектами перед входом в эти процедуры или выходом из них. Во всяком случае, для меня это имеет смысл.

Jon Peltier 18.01.2019 16:54

Я стараюсь избегать использования Application.Wait (хотя я вижу, что оставил его в образце кода в своем ответе, который был взят из образца кода в вопросе). DoEvents и вызов других процедур поддерживают работу VBA, тогда как .Wait фактически останавливает VBA. Мне кажется, что остановка VBA помешала бы ему догнать себя.

Jon Peltier 18.01.2019 16:56

Мне пришлось использовать этот код для решения этой проблемы. Вызова функции или DoEvents было недостаточно:

...
ActiveChart.ChartArea.Copy
aplicacion = RUTA & "\freemem.vbe"
lngErr = ShellExecute(0, "OPEN", aplicacion, "", "", 0)
Call pegadatos(PPSlide)
...

где функция shellexecute объявлена ​​ранее как

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

freemem.vbe - это текстовый файл с единственной строкой: Mystring=(80000000). После создания файла .txt необходимо изменить расширение на .vbe.

И пегадато:

Sub pegadatos(TheSlide As Object)
TheSlide.Shapes.Paste.Select
End Sub

Эта ошибка также может быть связана с ошибкой Excel, которая, по-видимому, не позволяет вам копировать диаграммы, метки данных которых связаны с несмежным диапазоном ячеек, так что вы получаете ошибку «Буфер обмена пуст ...» при последующей попытке вставить. Эта ошибка была воспроизведена в Excel 2013 и новее и дополнительно описана по адресу:

https://answers.microsoft.com/en-us/msoffice/forum/all/chart-with-data-labels-will-not-copy-to-clipboard/e60dcb59-8644-464a-8e13-0f5f62c4be76?auth= 1

Другие вопросы по теме