【问题标题】:"Application.Calculation = xlCalculationManual" statement causing run-time error 1004 in VBA Copy-Paste procedure“Application.Calculation = xlCalculationManual”语句在 VBA 复制粘贴过程中导致运行时错误 1004
【发布时间】:2014-12-23 07:51:52
【问题描述】:

我有复制第一行并将值粘贴到多行的 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 不会导致范围失去焦点,但会清除剪贴板。

【问题讨论】:

    标签: vba excel selection copy-paste


    【解决方案1】:

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

    注意:还有另一种建议解释为“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
    

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

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

    【讨论】:

    • 感谢您的回答。这对我的特殊情况没有帮助,因为它与我的问题无关。
    • 我已经扩展了我的答案,并提供了与您的错误原因相关的解释。我建议您参考我提供的优化解决方案。最好的问候,
    • 请提供您发现 Application.Calculation = xlCalculationManual 擦除剪贴板的位置。 excel 开发人员参考 (msdn.microsoft.com/en-us/library/office/…) 中的文档没有提及这一点。此外,根据我在搜索 Ron Rosenfeld 建议的“excel 复制失去焦点”时发现的信息,复制时 excel 不使用剪贴板。
    • @AStidham:您的问题已得到明确回答 - 因为剪贴板内存为空。现在,您要问另一个问题——“为什么剪贴板是空的”(或“在文档中的哪里可以找到它”)。我建议单独发布它,如果你愿意,可以在这里和/或微软论坛。亲切的问候,
    • @AlexBell 您不能要求 OP 接受答案。特别是正如 OP 指出的那样,您的初始回复没有解决实际问题,额外的回复并没有添加到 Ron Rosenfield 已经提供的回复中
    【解决方案2】:

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

    Excel 并不像其他程序那样真正使用系统剪贴板。我认为这与更改复制数据中的单元格引用有关。

    如果您只想粘贴值,可以尝试使用 Office 剪贴板,但据我所知,在最新版本的 Excel 中不支持 VBA。

    您可能会对此回复感兴趣。它引用了 Excel 开发人员 Prevent Excel from clearing copied data for pasting, after certain operations, without Office clipboard

    的评论

    【讨论】:

    • 感谢您的回答。你能通过改变焦点来澄清你的意思吗?我要改变什么焦点?你知道任何可以帮助我理解焦点规则的文档吗?
    • 我确实注意到,如果我在复制和粘贴之间的代码中放置 Application.EnableEvents = false,则代码运行不会出错。
    • @AStidham 用 excel copy lost focus 之类的内容搜索网络,您会发现一些讨论。
    • 使用谷歌搜索该词。我发现的信息表明复制,然后更改工作表或在另一个单元格中输入内容会导致 excel 失去焦点。但是,我还没有找到任何关于分配给属性的信息。另外,如果在复制和粘贴之间什么都做不了,那么我一定想知道为什么 Application.EnableEvents = false 不会导致 Excel 失去焦点?
    • @AStidham 有些行为没有很好的记录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    相关资源
    最近更新 更多