Excel range类的CopyPicture方法失败-有时失败

Excel range类的CopyPicture方法失败-有时失败,excel,vba,charts,copy-paste,Excel,Vba,Charts,Copy Paste,我有一个VBA代码,我用它将范围复制为图片并粘贴到图表中。它会这样做,这样我就可以将它保存到图片中。这段代码有70%的成功率,当它不工作时,它会发出错误“range类的CopyPicture方法失败”。我不明白为什么它有时能工作,有时不能,因为它需要相同的输入 有人能帮忙吗 Public Sub ExportRange(workbookPath As String, sheetName As String, rangeString As String, savepath As String)

我有一个VBA代码,我用它将范围复制为图片并粘贴到图表中。它会这样做,这样我就可以将它保存到图片中。这段代码有70%的成功率,当它不工作时,它会发出错误“range类的CopyPicture方法失败”。我不明白为什么它有时能工作,有时不能,因为它需要相同的输入

有人能帮忙吗

Public Sub ExportRange(workbookPath As String, sheetName As String, rangeString As String, savepath As String)

    Set tempWorkBook = Workbooks.Open(workbookPath)

    Dim selectRange As range
    Set selectRange = Worksheets(sheetName).range(rangeString)
    Dim numRows As Long
    numRows = selectRange.Rows.Count
    Dim numCols As Long
    numCols = selectRange.Columns.Count

    ' Transfer selection to a new sheet and autofit the columns
    selectRange.Copy
    Dim tempSheet As Worksheet
    Set tempSheet = Sheets.Add
    tempSheet.range("A1").PasteSpecial xlPasteAll

    ActiveSheet.UsedRange.Columns.AutoFit
    Set selectRange = ActiveSheet.UsedRange
    selectRange.Select
    selectRange.CopyPicture xlScreen, xlPicture

    Dim tempSheet2 As Worksheet
    Set tempSheet2 = Sheets.Add
    Dim oChtobj As Excel.ChartObject
    Set oChtobj = tempSheet2.ChartObjects.Add( _
        selectRange.Left, selectRange.Top, selectRange.Width, selectRange.Height)

    Dim oCht As Excel.Chart
    Set oCht = oChtobj.Chart
    oCht.Paste
    oCht.Export filename:=savepath
    oChtobj.Delete

    Application.DisplayAlerts = False
    tempSheet.Delete
    tempSheet2.Delete
    tempWorkBook.Close
    Application.DisplayAlerts = True

End Sub

对我来说,我也有类似的问题,我可以通过在
selectRange.CopyPicture
中的
xlScreen
xlPrinter
之间切换来解决


我希望这能有所帮助

我和你在同一个问题上苦苦挣扎,我认为这与我们的VBA代码或缺乏编程技能无关。这个错误太随机了

此外,如果在收到错误消息后,我单击DEBUG并按F8继续一步一步地执行代码,那么我可以跳过错误。在出现问题的行之后,我按F5以正常执行模式继续

当然,以上不是一个解决方案,但显示出我的编码没有任何错误

好吧,我做了这件事,它对我很有用:

在这句话之前,

rgToPic.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
我加了一句:

rgToPic.Copy  'just for nothing
我再也没有在
CopyPicture
方法中出现过错误


在其他地方查找此问题时,我发现一些用户能够在
CopyPicture
方法之前引入这句话,从而跳过错误:

    application.CutCopyMode=false

虽然这是一个老帖子,也许这会帮助一些人。 很长一段时间以来,我一直在为类似的问题苦苦挣扎<代码>复制图片失败 (在某些电脑上比在其他电脑上更频繁,但在我的笔记本电脑上很难复制)当我复制 包含嵌入的PNG图片。它仅在
Application.Visible=0
模式下失败,
Application.Visible=1
工作正常(对于我的应用程序,必须在不可见模式下运行Excel)。最后我发现,当在一个有1个CPU的VM上运行时,我可以100%地重现这个问题。下面的解决方案很奇怪,但似乎完全解决了我的问题

嵌入式PNG是Excel API术语中的
形状
。在调用
CopyPicture
之前,我只需要循环浏览这些形状(甚至什么都不做):

#“rng”是我想要复制图片的范围
用于rng中的形状。形状:通过
rng.CopyPicture(xlScreen,xlBitmap)
我的发现与, 其中
CopyPicture
在图表范围内失败。就他们而言, 激活工作簿和范围本身有帮助


假设,在速度慢或负载重的计算机上,Excel对页面上的复杂对象进行“惰性处理”,即在以某种方式访问对象之前不呈现它们,这似乎是合理的。强制渲染的一种方法似乎是在
Visible=1
模式下运行。另一种方法是在对象之间循环。如果是这种情况,那么这就是Excel的
CopyPicture
实现的一个缺陷,它不会在尝试复制之前强制渲染复杂对象。当copy方法发现目标范围的渲染尚未就绪时,它只是抛出一个错误,而不是强制该范围进行渲染。好吧,至少这是我的理论。

我找到了一种方法,迫使excel等待剪贴板中有图片,因为有时候它太快了:

Private Declare PtrSafe Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Long) As Long
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 

'just after copypicture, add this: (in my case i added it inside pastepicture, or i'd have too much coding )
Dim T#
  Do
      Waiting (2)
Loop Until IsClipboardFormatAvailable(2) Or Timer - T > 0.3

Sub Waiting(ByVal Mili_Seconds&)
Sleep Mili_Seconds
End Sub

我找到了一个简单的方法来解决这个我苦苦挣扎了几个月的问题。我知道这是一个“糟糕的代码”,但它帮助了我,对我来说工作得非常完美。在我的例子中,详细信息被复制,但调试错误窗口正在填充。因此,我跳过了调试窗口,我的生活变得更轻松了

修复方法是将下面的代码添加到VBA中“复制”代码的前面。这肯定会修复此错误

On Error Resume Next

唯一对我有效的方法是在CopyPicture方法之前增加一个延迟。在我键入此内容时,我们正在将其缩短,但我知道50毫秒的延迟可以正常工作:

声明PtrSafe子睡眠库“kernel32”(ByVal-dwms长)

'设置要捕获的范围

变暗rgExp为范围:设置rgExp=范围(“B2:D6”)

Sleep(50)'以毫秒为单位暂停以防止CopyPicture出现运行时错误,您的系统可能能够使用更短的睡眠时间,或者可能需要更长的睡眠时间

'将范围作为图片复制到剪贴板上

rgExp.CopyPicture外观:=xlScreen,格式:=xlBitmap


CopyPicture
方法将结果发送到剪贴板。但由于安全原因,Win10禁止在屏幕锁定时访问剪贴板。因此,如果在锁定屏幕时运行宏,则
CopyPicture
方法将失败,错误代码为1004。
同样的错误发生在
工作表.Pictures.Paste上

另一方面,简单的
Copy
PasteSpecial
不会弹出错误。当剪贴板不可访问时,内容不会复制到剪贴板,但VBA不会对此抱怨

不幸的是,
PasteSpecial
没有粘贴为图片的选项。

唯一简单的解决方法是在运行宏时使计算机处于解锁状态。

我的解决方法是将其放入错误捕获while循环,并不断重试,直到它能够完全复制范围而不显示错误消息。现在很有魅力

对我有效的是在我用
Application.CutCopyMode=False复制图片之前清除剪贴板


我认为最好的做法是粘贴您需要的内容,然后直接清除剪贴板。

对于相同的图像/工作表等是否失败?还是在不同的情况下?与运行循环100次一样,在某些情况下,它是否运行0次,在其他情况下运行100次,或者它是否运行介于两者之间的某个数字,然后由于错误而停止?对于相同的图像和工作表,它失败。我用6个图像在一个循环中运行这个Sub,当它失败时,它可以在任何一个图像上失败,但不一定