如何locking剪贴板或避免在MS Excel中使用它?

我在Excel下编写一个程序,通过从一个工作表复制/粘贴一些数据到另一个工作表来生成大量的电子表格(例如:使用一个“布局”工作表与一些页眉/页脚单元格将被复制/粘贴到生成的工作表)。

我的问题是,有时(不是每次),当运行我的“生成过程”,Excel生成此错误(对不起,这是从我的法语Excel错误的英文翻译):

错误1004:“_Worksheet”对象的“粘贴”方法失败

所以我假设剪贴板存在问题(我的电脑上可能同时使用了剪贴板上的其他软件:/)

我首先尝试find一种方法来复制/粘贴我的单元格(和其他东西),而不使用剪贴板,代码如下:

ThisWorkbook.Sheets("Layout").Range("A1").Copy Destination:=ThisWorkbook.Sheets("Test").Range("A1") 

或者那个

 ThisWorkbook.Sheets("Test").Range("A1") = ThisWorkbook.Sheets("Layout").Range("A1") 

但似乎只能复制文本或公式,不是所有的东西(边框,颜色,…),也不是图表对象(我有)!

所以我试图find一种在复制/粘贴过程中locking/解锁剪贴板的方法。 我发现这个代码要做到这一点:

 Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long Declare Function CloseClipboard Lib "user32" () As Long Declare Function EmptyClipboard Lib "user32" () As Long Public Sub Lockk() If OpenClipboard(0) = 0 Then MsgBox "cannot open clipboard." ElseIf EmptyClipboard() = 0 Then MsgBox "cannot clear clipboard." End If End Sub Public Sub Unlockk() CloseClipboard End Sub 

复制单元格的时候好像还在工作:我可以在excel下locking剪贴板,进入另一个软件(例如记事本),并且不能将一些数据复制到这个软件中; 回到excel,我可以复制/粘贴数据(手动或与macros)。

但:

  • 看起来,粘贴一个单元格会解锁剪贴板(我可以locking,去记事本,记事本没有访问剪贴板,回到excel,复制/粘贴一个单元格,回到记事本,然后记事本可以访问剪贴板;我没有明确解开剪贴板)。 这对我来说不是一个问题。

  • locking剪贴板后,我们无法复制/移除图表对象(手动或使用macros)。 用macros,我得到了和以前完全一样的错误)。

那么,是否有人想知道如何locking/解锁剪贴板来复制图表对象呢? 或者不使用剪贴板复制它们?

编辑:

用于复制/粘贴graphics对象的代码:

 Utils_Clipboard.Lockk ThisWorkbook.Sheets("Layout").ChartObjects("CHART_TEMPLATE").Copy DoEvents worksheet_p.Paste Destination:=where_p Utils_Clipboard.Unlockk 

其中worksheet_p是一个Worksheet对象,并且where_p是一个范围。 请注意,没有第一行和最后一行(Lockk剪贴板),它工作正常(除了一段时间)。

好吧,我find了一个解决scheme(也许不是最好的?)

我可以使用我的Utils_Clipboard.Lockk和Utils_Clipboard.Unlockk来确保复制(复制/粘贴)单元格,合并的单元格时剪贴板不会被其他软件使用…

但似乎剪贴板被locking时,我们无法复制/粘贴图表对象(通过按ctrl + c和ctrl + v键手动input;或者通过metod Copy和Past对象自动inputvba)。

我图表对象的解决scheme是使用函数Duplicate(http://msdn.microsoft.com/en-us/library/office/ff840956.aspx)和移动(http://msdn.microsoft.com/en-us /library/office/ff840583.aspx)像这样(其中worksheet_p是工作表,我想放图表对象):

 Utils_Clipboard.Lockk Dim newchart_l As Shape Set newchart_l = ThisWorkbook.Sheets("Layout").ChartObjects("CHART_TEMPLATE").Duplicate newchart_l.Chart.Location xlLocationAsObject, worksheet_p.Name Utils_Clipboard.Unlockk 

请注意,重复的对象是Shape而不是ChartObject(如果我们键入ChartObject的话,执行代码时会产生错误)。

所以确定它正在工作(我认为没有必要在这里locking剪贴板),但图表对象不是我想要的(在worksheet_p正确的顶部/左侧坐标)。 要做到这一点,我发现我们必须移动ChartArea(重复对象的父对象),但是我们不能直接操作“newchart_l”(看起来,Excel在重复调用之后并不更新所有的内部variables为什么?)。 所以我的解决scheme是首先检索新的重复图表对象,这样:

 Dim ChartObject_m As Chart Set ChartObject_m = worksheet_p.ChartObjects(worksheet_p.ChartObjects.Count).Chart 

然后移动该对象的chartarea(其中'where_p'是我想要放置我的charobject的范围/单元格):

 ChartObject_m.ChartArea.Left = where_p.Left ChartObject_m.ChartArea.Top = where_p.Top 

Et瞧!

受你的解决scheme的启发,我有一个改进的代码,我想分享。 改进之处在于,它不依赖像“ChartObjects-Collection中的图表顺序反映插入顺序”这样的假设:

 Private Function copyGraph(source As ChartObject, pos As Range) As ChartObject ' Copies a given graph to the given position and returns the resulting ' ChartObject. The destination position is expected to be a cell in the desired ' target worksheet. The resulting ChartObject will be aligned to the Top/Left- ' Border of the given cell. Dim dup As Object Dim dstChart As Chart ' First just duplicate the graph. This operation leaves it on the original ' worksheet. Set dup = source.Duplicate ' In case the duplication failed, ... If (Not dup.HasChart) Then ' ... we remove the duplicated object and leave the copy function. ' This yields a Nothing-reference as return value to signal the error ' to the caller. dup.Delete set copyGraph = Nothing Exit Function End If ' Then we move the graph to the target worksheet passed as parameter. This ' gives us the new link to the moved chart. ' ' Excel displays some weired behavior when using the reference returned by ChartObject.Duplicate. ' Namely it yields sporadic 1004 runtime errors without further specification. However it seems, ' that activating the chart and calling location for ActiveChart gets around this problem. ' ' Therefor the original code: ' Set dstChart = dup.Chart.Location(xlLocationAsObject, pos.Parent.Name) ' has been replaced with the following dup.Chart.parent.Activate Set dstChart = ActiveChart.Location(xlLocationAsObject, pos.Parent.Name) ' As we relocated the chart as an object, the parent of the chart object is ' an instance of ChartObject. Hence we use it as the return value. Set copyGraph = dstChart.parent ' Finally we move the graph to the requested position passed by the pos ' parameter. With copyGraph .Top = pos.Top .Left = pos.Left End With End Function 

我希望这可以帮助其他用户在这个问题上寻找一个简单的解决scheme。