Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

excel - "Application.Calculation = xlCalculationManual" statement causing run-time error 1004 in VBA Copy-Paste procedure

I have VBA code that copies the first row and pastes the values to multiple rows. The below code runs fine and pastes the rows as expected:

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

However, if I move Application.Calculation = xlCalculationManual down two lines as below, then the code throws a 1004 run-time error:

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

I've searched for information on the VBA language reference site here: http://msdn.microsoft.com/en-us/library/office/jj692818(v=office.15).aspx and the Excel developer reference site here: http://msdn.microsoft.com/en-us/library/office/ff194068(v=office.15).aspx.

Further, I've verified this error using both Excel 2010 running on Windows 7 and 2013 running on Windows 8.1.

Can someone help me understand why the location of Application.Calculation = xlManualCalculation would affect how the code runs?

EDIT:

I ran some additional tests to check if focus is lost or the clipboard is cleared. First to see if focus is lost I recorded a Macro that copied the first row with ctrl + x, then I changed the calculation mode of the workbook, then I hit ctrl + x again without re-selecting the cells. This is the resultant Macro:

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

Next, I entered a variable into my original Macro1 to capture the Application.CutCopyMode at various stages of execution. Follows is the resultant Macro:

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  

Based on the results of these two tests I believe that Application.Calculation = xlCalculationManual does not cause the range to lose focus, but does clear the clipboard.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Pertinent to you particular question, the answer is: Application.Calculation = xlCalculationManual statement erases the Clipboard Memory, which causes the subsequent Run-time error in your code snippet.

Note: there is another suggested explanation as 'Excel copy loosing the focus'; it might be just a semantic difference, pointing to the same effect and just worded differently, but for better clarity I prefer this one, i.e. clipboard memory (or whatever you call that temp register) loosing value, or the reference.

The test settings to prove/illustrate the concept and detailed explanation follows:

'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

Also, there is an old discussion on similar topic: Stop VB from Clearing Clipboard (link: http://www.mrexcel.com/forum/excel-questions/459793-stop-vbulletin-clearing-clipboard-3.html).

You may consider the following solution to your problem optimized for speed and reliability:

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

Note: unlike your problematic code snippet, there is no need for the Select statement and Clipboard Copy/Paste operations in suggested solution, thus any potential side effects will be minimized, either.

Hope this may help. Kind regards,


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...