我有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
我在此处搜索了有关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 7上运行的Excel 2010和在Windows 8.1上运行的2013验证了此错误。
有人可以帮我理解为什么Application.Calculation = xlManualCalculation
的位置会影响代码的运行方式吗?
修改
我运行了一些额外的测试来检查焦点是否丢失或剪贴板是否已清除。首先看看焦点是否丢失我录制了一个用ctrl + x复制第一行的宏,然后我改变了工作簿的计算模式,然后再次点击ctrl + x而不重新选择单元格。这是结果宏:
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中输入了一个变量,以便在执行的各个阶段捕获Application.CutCopyMode。以下是结果宏:
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
根据这两个测试的结果,我认为Application.Calculation = xlCalculationManual不会导致范围失去焦点,但会清除剪贴板。
答案 0 :(得分:2)
您正在更改复制和粘贴之间的焦点。当您这样做时,Excel会丢失复制的数据,在您尝试粘贴时会出现错误。如果您尝试按此顺序从工作表中执行此操作,则会发生同样的情况。
Excel并不像其他程序那样真正使用系统剪贴板。我认为这与在复制数据中更改单元格引用有关的问题有关。
如果您只想粘贴值,可以尝试使用Office剪贴板,但在最新版本的Excel中,我不知道VBA支持。
您可能会发现此感兴趣的回复。它引用了Excel开发人员Prevent Excel from clearing copied data for pasting, after certain operations, without Office clipboard
的注释答案 1 :(得分:2)
对于您的具体问题,答案是:Application.Calculation = xlCalculationManual
语句删除剪贴板内存,这会导致代码段中的后续运行时错误。
注意:还有另一个建议的解释是'Excel副本失去焦点';它可能只是一个语义上的差异,指向相同的效果,只是措辞不同,但为了更清晰,我更喜欢这一个,即剪贴板内存(或任何你称之为临时寄存器)失去价值或参考。
用于证明/说明概念和详细解释的测试设置如下:
'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)。
您可以考虑针对速度和可靠性优化的问题采用以下解决方案:
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
注意:与有问题的代码段不同,在建议的解决方案中不需要Select
语句和剪贴板复制/粘贴操作,因此任何潜在的副作用都将被最小化。
希望这可能会有所帮助。亲切的问候,