在VBA复制粘贴过程中导致运行时错误1004的“Application.Calculation = xlCalculationManual”语句

我有VBA代码复制第一行,并将值粘贴到多行。 下面的代码运行良好,并按预期粘贴行:

Sub Macro1() Dim i As Long Application.Calculation = xlCalculationManual Range("A1:M1").Select Selection.Copy For i = 1 To 50 Range("A" & i).Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Next i End Sub 

但是,如果我将Application.Calculation = xlCalculationManual下移两行,则代码将引发1004运行时错误:

 Sub Macro1() Dim i As Long Range("A1:M1").Select Selection.Copy Application.Calculation = xlCalculationManual For i = 1 To 50 Range("A" & i).Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Next i End Sub 

我在这里search了VBA语言参考站点上的信息: http : //msdn.microsoft.com/en-us/library/office/jj692818(v=office.15).aspx和Excel开发人员参考站点在这里: http://msdn.microsoft.com/en-us/library/office/ff194068(v=office.15).aspx 。

此外,我已经使用在Windows 8.1和Windows 8.1上运行的Excel 2010运行Excel 2010validation了此错误。

有人可以帮我理解为什么Application.Calculation = xlManualCalculation的位置会影响代码的运行方式吗?

编辑:

我跑了一些额外的testing,以检查焦点是否丢失或剪贴板被清除。 首先看看焦点是否丢失我logging了一个macros,用ctrl + x复制第一行,然后我改变了工作簿的计算模式,然后再次按下ctrl + x而不重新select单元格。 这是由此产生的macros:

 Sub MacroFocusTest() Range("A1:M1").Select Selection.Copy Application.CutCopyMode = False 'Macro recording entered this. Application.Calculation = xlManual Selection.Cut 'Range("A1:M1") is cut on the worksheet suggesting focus was not lost. End Sub 

接下来,我在我的原始Macro1中input了一个variables,以在执行的各个阶段捕获Application.CutCopyMode。 遵循是由此产生的macros:

 Sub Macro1() Dim i As Long Dim bCCMode as Boolean bCCMode = Application.CutCopyMode ' False Range("A1:M1").Select Selection.Copy bCCMode = Application.CutCopyMode ' True Application.EnableEvents = False ' Included because I mention in comments no error is thrown using this bCCMode = Application.CutCopyMode ' True Application.Calculation = xlCalculationManual bCCMode = Application.CutCopyMode ' False For i = 1 To 50 Range("A" & i).Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Next i End Sub 

基于这两个testing的结果,我相信Application.Calculation = xlCalculationManual不会导致范围失去焦点,但清除剪贴板。

与您的特定问题相关,答案是: Application.Calculation = xlCalculationManual语句擦除剪贴板内存,这将导致您的代码段中的后续运行时错误。

注意:还有另一个build议的解释是“Excel副本丢失焦点”。 它可能只是一个语义差异,指向相同的效果,只是措辞不同,但为了更好的清晰度,我更喜欢这个,即剪贴板内存(或任何你称之为临时寄存器)丢失价值,或参考。

testing设置certificate/说明的概念和详细的解释如下:

 'Error occured because a statement 'Application.Calculation = xlCalculationManual 'or Application.Calculation = xlAutomatic 'or Application.Calculation = xlManual 'placed after `Selection.Copy` clears the clipboard memory; 'thus there is nothing to paste and Error 1004 occured 'as demonstrated in the added test code block Sub YourMacroWithProblem() Dim i As Long Range("A1:M1").Select 'Selected Range content is placed to Clipboard memory Selection.Copy 'This statement erases Clipboard memory Application.Calculation = xlCalculationManual ' test if clipboard is empty --------------------- On Error Resume Next ActiveSheet.Paste If Err Then MsgBox "Clipboard is Empty": Err.Clear '------------------------------------------------- For i = 1 To 50 Range("A" & i).Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Next i End Sub 

此外,还有一个类似的话题的老讨论: 停止从清除剪贴板的VB (链接: http : //www.mrexcel.com/forum/excel-questions/459793-stop-vbulletin-clearing-clipboard-3.html )。

您可以考虑针对速度和可靠性进行优化的以下解决scheme:

 Sub Macro2() Dim i As Long Application.Calculation = xlCalculationManual Application.ScreenUpdating = False For i = 1 To 50 Range("A1:M1").Copy Destination:=Range("A" & i) Next i Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True End Sub 

注意:与有问题的代码片段不同,在build议的解决scheme中不需要Select语句和剪贴板复制/粘贴操作,因此任何潜在的副作用都将被最小化。

希望这可能有帮助。 亲切的问候,

您正在更改副本和粘贴之间的焦点。 当你这样做Excel丢失复制的数据,当你尝试粘贴时给你错误。 如果您尝试按照该顺序从工作表中执行此操作,则会发生同样的情况。

与其他程序一样,Excel并不真正使用系统剪贴板。 我相信这与处理复制数据中单元格引用的问题有关。

如果您只想粘贴这些值,则可以尝试使用Office剪贴板,但是在最近的Excel版本中没有我知道的VBA支持。

你可能会发现这种感兴趣的回应。 它引用Excel开发人员的评论防止Excel清除粘贴的复制数据,在某些操作之后,不使用Office剪贴板