Excel range类的CopyPicture方法失败-有时失败
我有一个VBA代码,我用它将范围复制为图片并粘贴到图表中。它会这样做,这样我就可以将它保存到图片中。这段代码有70%的成功率,当它不工作时,它会发出错误“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)
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,当它失败时,它可以在任何一个图像上失败,但不一定