簡體   English   中英

在VBA復制粘貼過程中導致運行時錯誤1004的“Application.Calculation = xlCalculationManual”語句

[英]“Application.Calculation = xlCalculationManual” statement causing run-time error 1004 in VBA Copy-Paste procedure

我有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不會導致范圍失去焦點,但會清除剪貼板。

您正在更改復制和粘貼之間的焦點。 當您這樣做時,Excel會丟失復制的數據,在您嘗試粘貼時會出現錯誤。 如果您嘗試按此順序從工作表中執行此操作,則會發生同樣的情況。

與其他程序一樣,Excel並不真正使用系統剪貼板。 我認為這與在復制數據中更改單元格引用有關的問題有關。

如果您只想粘貼值,可以嘗試使用Office剪貼板,但在最近的Excel版本中,我不知道VBA支持。

您可能會發現此感興趣的回復。 它引用Excel開發人員Prevent Excel的注釋,在沒有Office剪貼板的情況下,在某些操作之后清除復制的數據以進行粘貼

與您有關的具體問題,答案是: 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語句和剪貼板復制/粘貼操作,因此任何潛在的副作用也將被最小化。

希望這可能有所幫助。 親切的問候,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM